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

jcc*_*333 4 monads haskell

关于哈斯克尔的单子,我有一个本体论的问题; 我对这种语言是否区分语句和表达方式感到不满.例如,我觉得在大多数其他语言中,任何带有签名的东西a -> SomeMonadProbs ()都会被视为一种陈述.也就是说,因为haskell纯粹是功能性的,而且函数是由表达式组成的,所以我对于haskell在表达方面对monad所说的内容感到有点困惑.

Gab*_*lez 9

Monad只是一个与表达式交互的接口.例如,考虑使用do表示法实现的列表理解:

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

该desugars:

[1..3] >>= \x ->
[4..6] >>= \y ->
return (x, y)
Run Code Online (Sandbox Code Playgroud)

...并且在(>>=)列表的定义中替换给出:

concatMap (\x -> concatMap (\y -> [(x, y)]) [4..6]) [1..3]
Run Code Online (Sandbox Code Playgroud)

重要的想法是,使用do符号可以执行的任何操作都可以替换为调用(>>=).

与Haskell中"语句"最接近的是do符号块的语法行,例如:

x <- [1..3]
Run Code Online (Sandbox Code Playgroud)

这些行不对应于孤立的表达式,而是表达式的非自包含的语法片段:

[1..3] >>= \x -> ... {incomplete lambda}
Run Code Online (Sandbox Code Playgroud)

所以说一切都是Haskell中的一个表达式更合适,并且do符号给你的东西看起来像一堆语句,但实际上是对一堆表达式的贬低.


npo*_*cop 6

这里有一些想法.

a >>= b 就像任何其他应用程序一样是一个应用程序,所以从语法的角度来看,Haskell中只有表达式中没有语句.

从语义的角度来看(例如,参见解决尴尬的小队论文),有Haskell语义的"指称"和"可操作"片段.

指称片段>>=与数据构造函数类似,因此它认为a >>= b是在WHNF中."操作"片段"解构"IO monad中的值,并在该过程中执行不同的效果.

在推理程序时,通常根本不需要考虑"操作"片段.例如,当你重构foo a >> foo alet bar = foo a in bar >> bar你不关心的性质foo,所以IO动作是从这里的任何其他值没有区别.

这是Haskell闪耀的地方,并且很容易说没有任何陈述,但它会导致有趣且有些矛盾的结论.例如,C预处理器语言可以被认为是C的指称片段.所以C也有指称和操作片段,但是没有人说C是纯函数或没有语句.请参阅C语言是纯粹的功能性帖子,用于详细处理此事.

Haskell当然与C在数量上有所不同:它的指称片段具有足够的表现力,实际上非常有用,所以你必须考虑其操作语义中的底层转换,而不是在C中.

但是当你必须考虑这些转换时,比如在推理写入网络套接字的数据顺序时,你必须采用语句后语句思维.

因此,尽管IO操作本身并不是语句,并且在某种狭隘的技术意义上根本没有语句,但这些操作代表了语句,所以我认为可以说Haskell中的语句以非常间接的形式存在.


n. *_* m. 5

该语言是否完全区分语句和表达式

它不是.在语法中没有"语句"或类似内容的产生,在语言描述中没有任何东西被称为"语句"或任何等价物(据我所知).

语言报告调用do符号"语句"中的元素.有两种语句不是表达式:pat <- exp`` andlet decls`.

在大多数其他语言中,任何具有签名的内容都a -> SomeMonadProbs ()将被视为一种陈述

Haskell与大多数其他语言不同.这有点重要(显然不是为了它而不同,而是将表达式和语句统一到一个构造中).