将 Monadic 函数转换为 IO Monadic 函数
parseSource :: String -> Either ParserError Mod.Module
parseSource src = do
(imports, rest) <- parseImports (Lex.lexSource src)
bindings <- mapM parseBinding rest
buildModule imports bindings
我需要使上面返回一个 IO (Either ParserError Mod.Module) ,因为最后的 buildModule 语句需要执行一些 IO 功能(读取文件)。我遇到的问题是,当我将其设为 IO 函数时,我无法再执行绑定(错误的术语?)<-
操作。
完成这项工作的最简单方法是什么?
parseSource :: String -> Either ParserError Mod.Module
parseSource src = do
(imports, rest) <- parseImports (Lex.lexSource src)
bindings <- mapM parseBinding rest
buildModule imports bindings
I need to make the above return an IO (Either ParserError Mod.Module)
as the buildModule
statement at the end will need to perform some IO functions (reading files). The problem i have is that when i make it an IO function, i can no longer do the bind(wrong term?) <-
operations.
What is the simplest way to make this work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看看根据 ErrorT ParseError IO。
Take a look at defining your problem in terms of ErrorT ParseError IO.
我找不到组合器将纯
Either
计算提升到ErrorT
monad 中,因此我编写了一个名为liftError
的组合器。我用虚拟类型和实现充实了您的示例。main
运行解析器两次,一次输入抛出ParserError
,另一次成功但产生IO
副作用。为了使ErrorT ParserError IO
成为Monad
,ParserError
必须是Error
的实例(以便它可以实现失败
)。I couldn't find a combinator to lift a pure
Either
computation into theErrorT
monad, so I wrote one calledliftError
. I fleshed out your example with dummy types and implementations. Themain
runs the parser twice, once with input that throws aParserError
, and once which succeeds with anIO
side-effect. In order forErrorT ParserError IO
to be aMonad
,ParserError
must be an instance ofError
(so that it is possible to implementfail
).