为什么没有提供功能时list monad起作用

Ber*_*ian 0 monads haskell list

当没有指定功能时,我试图使我进入清单monad:

func::[(Int,String)]
func =do
    a <- [1,2,3]
    b <- ["a","b"]
    return (a,b)
Run Code Online (Sandbox Code Playgroud)

我了解(>>=) ml f=concat (map f ml)。在我们这个例子中,值是f多少?
当我说: a<-[1,2,3]这被翻译成[1,2,3]>>=(\x->return x)
如果不是,为什么由于我没有为bind运算符提供任何功能,它为什么不会崩溃?

以后编辑

感谢您的回复,虽然我了解多个会发生什么,但>>=在这种简单情况下,我更加担心:

    mym =do
     a<-[1,2,3]
     return a
Run Code Online (Sandbox Code Playgroud)

什么是等效的? [1,2,3] >>= (\x -> return x)

Wil*_*sem 7

确实为bind函数提供了一个函数。如果我们do符号[Haskell'10 report]进行减,则会得到:

[1,2,3] >>= (\a -> ["a", "b"] >>= (\b -> return (a, b)))
Run Code Online (Sandbox Code Playgroud)

因此,这意味着我们在这里基本上得到:

concatMap (\a -> ["a", "b"] >>= (\b -> return (a, b))) [1,2,3]
Run Code Online (Sandbox Code Playgroud)

因此:

concatMap (\a -> concatMap (\b -> [(a, b)]) ["a", "b"]) [1,2,3]
Run Code Online (Sandbox Code Playgroud)

所以我们map[1,2,3]给定功能,对于每个元素a,我们再进行第二次concatMap\b -> [(a, b)]concatMap每个元素映射到一个单例元素的A 等效于map,因此:

concatMap (\a -> map (\b -> (a, b)) ["a", "b"]) [1,2,3]
Run Code Online (Sandbox Code Playgroud)

等效于:

concatMap (\a -> [(a, "a"), (a, "b")]) [1,2,3]
Run Code Online (Sandbox Code Playgroud)

因此:

[(1, "a"), (1, "b"), (2, "a"), (2, "b"), (3, "a"), (3, "b")]
Run Code Online (Sandbox Code Playgroud)

因此,do窗帘后面的方块会产生一种表情。

编辑:的等效项[1,2,3] >>= (\x -> return x)是:

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

因为(>>=)monad是list flip concatMap,并且returnis \x -> [x]。因此,我们在这里将元素包装在列表中,然后将这些列表连接起来。因此,这等效于:

map id [1,2,3]
Run Code Online (Sandbox Code Playgroud)

因此等同于:

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


chi*_*chi 5

do
a <- [1,2,3]
b <- ["a","b"]
return (a,b)
Run Code Online (Sandbox Code Playgroud)

被翻译成

[1,2,3] >>= (\a -> do
  b <- ["a","b"]
  return (a,b) )
Run Code Online (Sandbox Code Playgroud)

被翻译成

[1,2,3] >>= (\a ->
  ["a","b"] >>= (\b ->
     return (a,b) ))
Run Code Online (Sandbox Code Playgroud)

本质上,该f函数ml >>= f是“其余部分do”。没有针对的独立翻译a <- [1,2,3],仅在其代码do块中进行了翻译。

您可以尝试简化上面的表达式,直到得到

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

然后

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

然后

[(1, "a"), (1, "b"), (2, "a"), (2, "b"), (3, "a"), (3, "b")]
Run Code Online (Sandbox Code Playgroud)