Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 列表上的Haskell一元运算_List_Haskell_Monads - Fatal编程技术网

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:我想我在回答你的问题之前就已经明白你的意思了。我刚刚提交了您可能感兴趣的内容。