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)
您确实为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)
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)