gpt4 book ai didi

haskell - Haskell中do block 中 `<-`的含义

转载 作者:行者123 更新时间:2023-12-04 00:14:16 25 4
gpt4 key购买 nike

我试图理解 Haskell monads,阅读 "Monads for the Curious Programmer" .我遇到了 List Monad 的例子:

tossDie=[1,2,3,4,5,6]

toss2Dice = do
n <- tossDie
m <- tossDie
return (n+m)

main = print toss2Dice

一路 do block 产生 m作为 36 元素列表,我有点理解 - 它映射 n 的每个元素作为 6 个元素的列表,然后连接这些列表。我不明白的是 nm <- tossDie 的存在而改变,从 6 个元素列表到 36 个元素。显然“我们先绑定(bind) n再绑定(bind) m”在这里理解是错误的,但是什么是对的呢?

我也不清楚 do 中如何应用双参数函数。堵塞。我怀疑这是一个curying的例子,但我对它的工作原理有点模糊。

有人可以解释上述两个谜团吗?

最佳答案

对于列表(例如 tossDie ),do表示法的作用类似于列表推导——也就是说,就好像每个变量绑定(bind)都是嵌套的 foreach环形。

do-block 表达式:

toss2Dice = do { n <- tossDie; m <- tossDie; return (n+m) }

和这个列表理解做同样的事情:
toss2Dice = [ n+m | n <- tossDie, m <- tossDie ]

结果与以下命令式伪代码相当:
toss2Dice = []
foreach n in tossDie:
foreach m in tossDie:
toss2Dice.push_back(n+m)

除了 Haskell 示例是根据需要懒惰地生成结果,而不是急切地一次生成结果。

如果您查看列表的 monad 实例,您可以看到它是如何工作的:
instance Monad [] where
xs >>= f = concat (map f xs)
return x = [x]

do 的开头开始 block ,每个变量绑定(bind)在 block 的其余部分创建一个循环:
do { n <- tossDie; m <- tossDie; return (n+m) }
===> tossDie >>= \n -> do { m <- tossDie; return (n+m) }
===> concat ( map (\n -> do { m <- tossDie; return (n+m) }) tossDie )

请注意 map函数迭代列表中的项目 tossDie ,结果为 concat制定。映射函数是 do 的余数 block ,因此第一个绑定(bind)有效地围绕它创建了一个外循环。

附加绑定(bind)创建连续嵌套循环;最后是 return函数从每个计算值中创建一个单例列表 (n+m)使“绑定(bind)”功能 >>= (需要列表)可以正确连接它们。

关于haskell - Haskell中do block 中 `<-`的含义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19961941/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com