无法理解Monad >>应用的结果

Sci*_*pio 6 monads haskell

操作>>说明如下:

顺序组成两个动作,丢弃第一个产生的任何值,如命令式语言中的排序操作符(如分号).

这是让我困惑的例子:

> ([1] ++ [2]) >> ([2] ++ [3])
[2,3,2,3]
Run Code Online (Sandbox Code Playgroud)

我期待列表[2,3],它将是正确表达部分的结果.如何解释[2,3,2,3]的结果?

Lee*_*Lee 12

(>>) 默认情况下定义为

a >> b = a >>= (\_ -> b)
Run Code Online (Sandbox Code Playgroud)

所以忽略的值是a给定的monadic值m a.>>=专门列出的类型是:

(>>=) :: [a] -> (a -> [b]) -> [b]
Run Code Online (Sandbox Code Playgroud)

l >>= f调用f列表的每个元素l以产生列表列表,然后将其连接起来.

例如

[1,2] >>= (\i -> [i, -i])
> [1,-1,2,-2]
Run Code Online (Sandbox Code Playgroud)

忽略每个输入元素并返回值[2,3]将导致列表的n个副本[2,3]的长度输入列表n

例如

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

[1,2] >>= (\_ -> [2,3])
> [2,3,2,3]
Run Code Online (Sandbox Code Playgroud)

第二个例子相当于([1] ++ [2]) >> ([2] ++ [3])你的问题.


chi*_*chi 7

Lee对答案的一个小补充:

([1] ++ [2]) >> ([2] ++ [3])
Run Code Online (Sandbox Code Playgroud)

相当于

([1] ++ [2]) >> ([2] ++ [3]) >>= \x -> return x
Run Code Online (Sandbox Code Playgroud)

这相当于

([1] ++ [2]) >>= \y -> ([2] ++ [3]) >>= \x -> return x
Run Code Online (Sandbox Code Playgroud)

这相当于

[ x | y <- [1]++[2] , x <- [2]++[3] ]
Run Code Online (Sandbox Code Playgroud)

这与命令式伪代码接近

for y in [1]++[2]:
   for x in [2]++[3]:
      print x
Run Code Online (Sandbox Code Playgroud)