简体   繁体   English

是monads表达式,还是Haskell中有语句?

[英]Are monads expressions, or are there statements in Haskell?

I have an ontological question about monads in haskell; 关于哈斯克尔的单子,我有一个本体论的问题; I'm shaky on whether the language makes a distinction between statements and expressions at all. 我对这种语言是否区分语句和表达方式感到不满。 For example, I feel like in most other languages anything with a signature like a -> SomeMonadProbs () would be considered a statement. 例如,我觉得在大多数其他语言中,任何带有签名的东西a -> SomeMonadProbs ()例如a -> SomeMonadProbs ()都会被视为一种陈述。 That said, since haskell is purely functional, and functions are composed of expressions, I'm a wee bit confused on what haskell would say about monads in terms of their expression-hood. 也就是说,因为haskell纯粹是功能性的,而且函数是由表达式组成的,所以我对于haskell在表达方面对monad所说的内容感到有点困惑。

Monad is just one interface for interacting with expressions. Monad只是一个与表达式交互的界面。 For example, consider this list comprehension implemented using do notation: 例如,考虑使用do表示法实现的列表理解:

example :: [(Int, Int)]
example = do
    x <- [1..3]
    y <- [4..6]
    return (x, y)

That desugars to: 该desugars:

[1..3] >>= \x ->
[4..6] >>= \y ->
return (x, y)

... and substituting in the definition of (>>=) for lists gives: ...并在(>>=)的定义中替换列表给出:

concatMap (\x -> concatMap (\y -> [(x, y)]) [4..6]) [1..3]

The important idea is that anything you can do using do notation can be replaced with calls to (>>=) . 重要的想法是,使用do符号可以执行的任何do都可以替换为对(>>=)调用。

The closest thing to "statements" in Haskell are syntactic lines of a do notation block, such as: 与Haskell中“语句”最接近的do符号块的语法行,例如:

x <- [1..3]

These lines do not correspond to isolated expressions, but rather syntactic fragments of an expression which are not self-contained: 这些行不对应于孤立的表达式,而是表达式的非自包含的句法片段:

[1..3] >>= \x -> ... {incomplete lambda}

So it's really more appropriate to say that everything is an expression in Haskell, and do notation gives you something which appears like a bunch of statements but actually desugars to a bunch of expressions under the hood. 所以真的更适合说,一切是在Haskell的表达,并do标记给你的东西这似乎像一堆报表,但实际上desugars的引擎盖下了一堆表情。

Here are few thoughts. 这里有一些想法。

a >>= b is an application just like any other application, so from syntactic point of view there are clearly no statements in Haskell, only expressions. a >>= b就像任何其他应用程序一样是一个应用程序,所以从语法的角度来看,Haskell中没有明确的语句,只有表达式。

From semantic point of view (see for example Tackling the awkward squad paper) there are "denotational" and "operational" fragments of Haskell semantics. 从语义的角度来看(例如,参见解决尴尬的小队论文),有Haskell语义的“指称”和“可操作”片段。

The denotational fragment treats >>= similar to a data constructor, so it considers a >>= b to be in WHNF. 指称片段处理>>=类似于数据构造函数,因此它认为a >>= b在WHNF中。 The "operational" fragment "deconstructs" the values in IO monad and performs different effects in the process. “操作”片段“解构”IO monad中的值,并在该过程中执行不同的效果。

When reasoning about programs, you often don't need to consider the "operational" fragment at all. 在推理程序时,通常根本不需要考虑“操作”片段。 For example, when you refactor foo a >> foo a into let bar = foo a in bar >> bar you don't care about the nature of foo , so IO actions are indistinguishable from any other values here. 例如,当你重构foo a >> foo a into let bar = foo a in bar >> bar你不关心foo的本质,所以IO动作与这里的任何其他值都没有区别。

It's where Haskell shines, and it's tempting to say there are no statements at all, however it leads to funny and somewhat paradoxical conclusion. 这是Haskell闪耀的地方,并且很容易说没有任何陈述,但它会导致有趣且有些矛盾的结论。 For example, C preprocessor language can be considered a denotational fragment of C. So C has denotational and operational fragments too, but nobody says that C is purely functional or has no statements. 例如,C预处理器语言可以被认为是C的指称片段。所以C也有指称和操作片段,但是没有人说C是纯函数或没有语句。 See The C language is purely functional post for a detailed treatment of this matter. 请参阅C语言是纯粹的功能性帖子,用于详细处理此事。

Haskell of course differs from C quantitatively: its denotational fragment is expressive enough to be practically useful, so you have to think about underlying transitions in its operational semantics less often than in C. Haskell当然与C在数量上有所不同:它的指称片段具有足够的表现力,实际上非常有用,所以你必须考虑其操作语义中的底层转换,而不是在C中。

But when you have to think about those transitions, like when reasoning about the order of data written to a network socket, you have to resort to that statement-after-statement thinking. 但是当你必须考虑这些转换时,比如在推理写入网络套接字的数据顺序时,你必须采用语句后语句思维。

So while IO actions are not themselves statements and in a certain narrow technical sense there are no statements at all, the actions represent the statements so I think it's fair to say that statements are present in Haskell in a very indirect form. 因此,尽管IO操作本身并不是语句,并且在某种狭隘的技术意义上根本没有语句,但这些操作代表了语句,所以我认为可以说Haskell中的语句以非常间接的形式存在。

whether the language makes a distinction between statements and expressions at all 该语言是否完全区分语句和表达式

It does not. 它不是。 There are no productions for "statement" or anything like that in the grammar, and nothing is called "statement" or anything equivalent (as far as I know) in the language description. 在语法中没有“语句”或类似内容的产生,在语言描述中没有任何东西被称为“语句”或任何等价物(据我所知)。

The language report calls elements inside the do notation "statements". 语言报告呼吁里面的元素do记号“声明”。 There are two kinds of statements that are not expressions: pat <- exp`` and let decls`. 有两种语句不是表达式: pat <- exp`` and let decls`。

in most other languages anything with a signature like a -> SomeMonadProbs () would be considered a statement 在大多数其他语言中,任何带有像a -> SomeMonadProbs ()这样的签名的东西都会被视为一种陈述

Haskell is different from most other languages. Haskell与大多数其他语言不同。 That's kinda its point (not being different for the sake of it, obviously, but unifying expressions and statements into a single construct). 这有点重要(显然不是为了它而不同,而是将表达式和语句统一到一个构造中)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM