3

所以我试图准确地理解 Haskelldo符号是如何工作的。我知道它与 monads 一起使用,并且它基本上扩展(因为它实际上是语法糖)成与 bind ( >>=) 或 then ( >>) 连接的匿名函数,如此处所示https://en.wikibooks.org/wiki/Haskell /Syntactic_sugar#Do_notation

但是我的问题是为什么下面的命令

Prelude> do [1, 2, 3]; "hello"

返回

"hellohellohello"

我知道数组实际上是 monad(并且字符串是字符数组),但我看不出这是如何导致上述行为的。

4

2 回答 2

18
do [1, 2, 3]; "hello"

脱糖

[1, 2, 3] >> "hello"

这与

[1, 2, 3] >>= (\_ -> "hello")

这与

concatMap (\_ -> "hello") [1, 2, 3]

这与

concat (map (\_ -> "hello") [1, 2, 3])

这与

concat [(\_ -> "hello") 1, (\_ -> "hello") 2, (\_ -> "hello") 3])

这与

concat ["hello","hello","hello"]

这与

"hellohellohello"
于 2016-01-07T17:11:55.113 回答
3

为了补充 Joachim Breitner 的回答,以下是从另一个角度来看这个问题:

do [1, 2, 3]
   "hello"

do a <- [1, 2, 3]
   b <- "hello"
   return b

do a <- [1, 2, 3]
   do b <- "hello"
      do return b

[b | a <- [1,2,3], b <- "hello"]

和伪代码一样

for a in (a list of Nums) [1, 2, 3]:
   -- here we have `a` (a Num)
   for b in (a list of Chars) "hello":
      -- here we have that same `a` (a Num), 
      -- and `b` (which is a Char)
      emit b       -- whatever "emit" means

当然,列表(不是“数组”)的列表(不是“数组”)的列表推导(无论是什么东西,比如Nums、Chars 等)去糖化为相同的concatMap使用代码;但有时在精神上更容易处理它们,无论是按原样还是作为某些嵌套循环的规范。

事实上,do-notation 似乎一开始就很容易成为for-notation。

于 2016-01-07T23:17:51.087 回答