【发布时间】:2016-01-20 23:51:47
【问题描述】:
今天在 Coding Dojo 工作我尝试了以下方法
example :: IO ()
example = do input <- getLine
parsed <- parseOnly parser input
...
其中parseOnly :: Parser a -> Either String a(来自attoparsec)当然编译器抱怨Either ..不是IO ..本质上告诉我我在混合monad。
当然可以解决
case parseOnly parser input of .. -> ..
我认为这有点不雅。另外我的猜测是其他人早些时候遇到过这个问题,我认为解决方案与 monad 转换器有关,但最后一点我无法拼凑起来。
它也让我想起了liftIO - 但我认为这是相反的方式,它解决了在一些周围的 monad 内部发生的提升 IO 动作的问题(更准确地说是MonadIO - 例如在Snap 内部想打印一些东西到stdout,同时得到一些http)。
更一般地说,这个问题似乎是针对 Monad m1 和(不同的)Monad m2 我该怎么做类似的事情
example = do a <- m1Action
b <- m2Action
..
【问题讨论】:
-
这不太可能是单子转换器,我不认为。
IO只能位于单子变压器堆栈的底部。 -
@dfeuer 你确定吗?
ExceptT IO e是一个完全合理的 monad(由转换器构建),Either e和IO动作都可以合理地解除。 -
@DanielWagner,这是一个很好的观点。
IO仍在底部,因此您必须将整个东西包裹在runExceptT或其他东西中,但在里面的东西更方便。 user3237465 已将其转化为答案。
标签: haskell monads monad-transformers