List 列表上的Haskell一元运算
我有以下几点List 列表上的Haskell一元运算,list,haskell,monads,List,Haskell,Monads,我有以下几点 [3,2,1] >> [1] = [1,1,1] 我不完全明白为什么会这样?看看>>我希望[3,2,1]会是结果,但我看到列表上的情况有所不同 有人能解释一下原因吗?>可以这样定义: ma >> mb = ma >>= const mb (这不是它在[]的Monad实例中的实际定义,但这并不重要。) 在列表中,对于[1,2,3]中的每个元素,您将得到[1],并且总体结果相当于concat[[1],[1],[1]],即[1,1,1] 下面是GH
[3,2,1] >> [1]
= [1,1,1]
我不完全明白为什么会这样?看看>>我希望[3,2,1]会是结果,但我看到列表上的情况有所不同
有人能解释一下原因吗?
>
可以这样定义:
ma >> mb = ma >>= const mb
(这不是它在[]
的Monad
实例中的实际定义,但这并不重要。)
在列表中,对于[1,2,3]
中的每个元素,您将得到[1]
,并且总体结果相当于concat[[1],[1],[1]]
,即[1,1,1]
下面是GHC.Base中的[]
的实例:
m >>= k = foldr ((++) . k) [] m
m >> k = foldr ((++) . (\ _ -> k)) [] m
我们在这里使用折叠,将右手边的一个副本连接到左手边的每个元素,忽略该元素可能是什么。对于任何单子,您可以将
a>>b
翻译为a>=\\\\\->b
。在列表monad中,bind操作符(>>=)
是concatMap
,其参数被翻转,因此您的示例相当于
concatMap (\_ -> [1]) [3, 2, 1]
你可以这样评估
concatMap (\_ -> [1]) [3, 2, 1]
= concat (map (\_ -> [1]) [3, 2, 1]) -- definition of concatMap
= concat [[1], [1], [1]] -- apply map
= [1, 1, 1] -- apply concat
回想一下,列表的返回是
\x->[x]
。如果我用return
[1,2,3] >> return 1
让我们加些糖
do [1,2,3]
return 1
你现在能看见吗<代码>>>不从其左参数中提取值,仅从其周围的上下文中提取。在本例中,上下文是一个三元素列表,或者您可以说,三个不同的选择都是非确定选择的。然后在每种情况下,返回1
如果你做了
do x <- [1,2,3]
return x
do x我不懂“const mb”这个词。常量a->b->a,所以我希望mb被输出。i、 是的,没错,mb
被输出。它被输出三次,因为对于列表,对于左侧列表的每个元素,>
和>=
的右侧被调用一次。所以你得到了[[1],[1],[1]]
。想想会发生什么事,IO
monad确实以类似的方式运行putStr“Hello,”>>putStr“world”
将是一个只打印“world”
的操作。如果您解释一下为什么希望得到您建议的结果,可能会有所帮助。@leftaroundabout:想想(>>)的类型::Monad m=>MA->MB->MB
。就IO
而言,这将是“分别组合ioa
和iob
类型的两个动作,并产生iob
类型的动作”。想象一下(getLine>>getLine)::IO String
:它从标准输入中读取两行,丢弃读取第一行的结果,并返回读取第二行的结果。([3,2,1]>[“Hello”,“World]”)的类似情况::[String]
:选择一个数字,然后选择一个字符串,然后返回该字符串,该字符串隐式地丢弃该数字。@sacundim:我的观点与被丢弃的“返回的”单子参数数据无关(这就是我选择输出操作的原因,因为这些操作只有()
无论如何),这是关于结构的。@leftaroundabout:我想我在回答你的问题之前就已经明白你的意思了。我刚刚提交了您可能感兴趣的内容。