gpt4 book ai didi

haskell - 在其他一些 monad m1 中绑定(bind)一个 Monadic 值 (m2 a)

转载 作者:行者123 更新时间:2023-12-02 17:47:35 26 4
gpt4 key购买 nike

今天在编码道场工作时,我尝试了以下操作

example :: IO ()
example = do input <- getLine
parsed <- parseOnly parser input
...

where parseOnly::Parser a -> Either String a (来自 attoparsec)当然编译器提示 Either .. 不是IO .. 本质上告诉我我正在混合 monad。

当然可以通过以下方式解决

             case parseOnly parser input of .. -> ..

我认为这有点不优雅。我的猜测是,其他人早些时候也遇到过这个问题,我认为解决方案与 monad 转换器有关,但最后的部分我无法拼凑在一起。

它也让我想起了 liftIO - 但我认为这是另一种方式,它解决了提升发生在某些周围 monad 内的 IO 操作的问题(更准确地说 MonadIO > - 例如,在 Snap 中,当一个人想要在获取一些 http 的同时将某些内容打印到 stdout 时)。

更一般地说,这个问题似乎是针对 Monad m1 和(不同的)Monad m2 我该如何做类似的事情

example = do a <- m1Action
b <- m2Action
..

最佳答案

一般来说你不能。整个 do block 必须是一个特定的 monad(因为 example 需要具有某种特定类型)。如果您可以在该 do block 内绑定(bind)任意其他 monad,则您将拥有 unsafePerformIO

Monad 转换器允许您生成一个 monad,将多个其他 monad 可以做的事情组合起来。但是您必须决定 do block 中的所有操作都使用相同的 monad 转换器堆栈来使用它们,它们不是在 do block 中任意切换 monad 的方法。

您使用 case 的解决方案仅有效,因为您有一个特定的已知单子(monad)(任一),它有一种从其内部提取值的方法。并非所有 monad 都提供此功能,因此在不了解所涉及的特定 monad 的情况下不可能构建通用解决方案。这就是为什么 do block 语法不提供这样的快捷方式。

关于haskell - 在其他一些 monad m1 中绑定(bind)一个 Monadic 值 (m2 a),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34912922/

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