gpt4 book ai didi

haskell - 为什么 `fmap (take 10) . sequence . fmap return $ [1..]::m [Int]` 只适用于某些 monad?

转载 作者:行者123 更新时间:2023-12-02 09:07:04 26 4
gpt4 key购买 nike

我希望拥有无穷无尽的随机或不确定的数字。我继续这样编程:

supply :: Monad m => (Int -> m Int) -> m [Int]
supply action = sequence . fmap action $ [1..]

— 与 action\n -> <a href="https://hackage.haskell.org/package/random-1.1/docs/System-Random.html#v:randomRIO" rel="noreferrer noopener nofollow">randomRIO</a> (1, n)\n -> [1.. n]

不幸的是,我无法从该供应中获取任何东西。

当我更换action时与 return并尝试了不同的单子(monad),我发现IdentityReader工作,但它们在这种情况下没那么有用。

λ flip runReader 13 (fmap (take 10) (supply return))
[1,2,3,4,5,6,7,8,9,10]
λ runIdentity (fmap (take 10) (supply return))
[1,2,3,4,5,6,7,8,9,10]
λ [] : (fmap (take 10) (supply return))
[[]^CInterrupted.
fmap (take 10) (supply return) :: IO [Int]
^CInterrupted.

某些单子(monad)在测序时具有这种悬挂特性肯定是有原因的,但我没有看到它。这是严格性问题吗?例如,此 Identity 和列表​​实例之间的标志性差异是什么?为什么我可以用 Identity i 组装出一个流,但不是类似的琐碎单例列表 [i]

最佳答案

这在 IO 中不起作用并不奇怪。您正在构建一个无限的 IO 操作列表,然后 sequence 将其转换为单个 IO 操作,该操作通过执行 < em>所有基本操作。它必须立即执行所有操作,因为它们可能会产生副作用。 显然,这永远不会结束。如果您希望它起作用,您需要类似 unsafeInterleaveIO 的东西。

[] 示例更加微妙。以下内容也将挂起:

> map (take 10) $ transpose [[x] | x <- [1..]]
[[1,2,3,4,5,6,7,8,9,10]^CInterrupted.

transpose 必须遍历整个无限列表,查找其中可能包含两个元素的任何内容,以决定是否应该有第二行。 序列本质上是相同的。

关于haskell - 为什么 `fmap (take 10) . sequence . fmap return $ [1..]::m [Int]` 只适用于某些 monad?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57020592/

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