使用列表 monad 进行迭代
我无法理解列表 monad 的迭代行为如何从其定义导出。
instance Monad [] where
m >>= f = concatMap f m
return x = [x]
fail s = []
我读过的讨论似乎忽略了 >>=
如何创建控制结构的问题,正如 do
表示法最清楚地显示的那样:
allEvenOdds :: Int -> [(Int,Int)]
allEvenOdds n = do
evenValue <- [2,4 .. n]
oddValue <- [1,3 .. n]
return (evenValue,oddValue)
这是否内置于Haskell,我假设 IO monad 与实际 i/o 的接口的方式是?
I'm having trouble understanding how the iterative behavior of the list monad can be derived from its definition.
instance Monad [] where
m >>= f = concatMap f m
return x = [x]
fail s = []
Discussions I've read seem to pass over the question of how >>=
creates a control structure, as shown most clearly with do
notation:
allEvenOdds :: Int -> [(Int,Int)]
allEvenOdds n = do
evenValue <- [2,4 .. n]
oddValue <- [1,3 .. n]
return (evenValue,oddValue)
Is this built in to Haskell, the way I assume the IO monad's interface to actual i/o is?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
没有任何内置内容,一切都是您引用的 Monad 实例的简单结果(并且,由于此示例使用
do
表示法,因此它如何脱糖以使用>>=< /code> 运算符):
您希望可以轻松地看到它“迭代”两个列表,并生成所有对(偶数、奇数)的列表,并从两个列表中获取值。
在较高的层次上,我们可以说列表 monad 导致迭代,因为
concatMap
与map
一样,为列表的每个元素执行给定的函数,因此它隐式地执行迭代列表。There's nothing built-in, everything is a simple consequence of the Monad instance you quoted (and, since this example uses
do
notation, how that desugars to uses of the>>=
operator):which you can hopefully easily see "iterates over" both lists and results in a list of all pairs of (even, odd) with values taken from both lists.
At a high level, we can say that the list monad results in iteration simply because
concatMap
, likemap
, executes the given function for each element of the list, so it implicitly iterates over the list.Monad
类型类模型的列表实例非确定性:您可以将每个var <- someList
视为for
像 Python 中一样循环。do
表示法被脱糖为[2,4 .. n] >>= (\evenValue -> [1, 3 .. n] >>= (\ oddValue -> return (evenValue, oddValue)))
,因此这相当于 Python 中的内容,例如:或者使用列表理解:
这对于
实例 Monad []
有效,表达式[2,4 .. n] >>= (\evenValue -> [1, 3 .. n] >>= (\oddValue -> return (evenValue, oddValue)) )
因此等价于:因此:
但是
do
表示法并不是“硬连线”到IO
:IO
只是一个实例的Monad
的实现方式是一个IO
操作将在第二个操作之前运行。对于列表,它的实现方式与跨越 Pythonfor
循环的方式相同。The list instance of the
Monad
typeclass models nondeterminism: you can see eachvar <- someList
as afor
loop like in Python.The
do
notation is desugared to[2,4 .. n] >>= (\evenValue -> [1, 3 .. n] >>= (\oddValue -> return (evenValue, oddValue)))
, so this is equivalent to something in Python like:or with list comprehension:
This works since for
instance Monad []
, the expression[2,4 .. n] >>= (\evenValue -> [1, 3 .. n] >>= (\oddValue -> return (evenValue, oddValue)))
is thus equivalent to:and thus:
But
do
notation is not "hardwired" toIO
:IO
is just an instance ofMonad
that is implemented in such way that oneIO
action will run before the second one. For lists, it thus is implemented in an equivalent way as spanning Pythonfor
loops.