Uli*_*ler 5 monads haskell scope do-notation
据我所知,doHaskell中的块只是monadic绑定运算符的某种语法糖.例如,一个人可以转换
main = do f <- readFile "foo.txt"
print f
print "Finished"
Run Code Online (Sandbox Code Playgroud)
至
main = readFile "foo.txt" >>= print >> print "Finished"
Run Code Online (Sandbox Code Playgroud)
是否可以将所有do块转换为绑定语法?例如,f多次使用此块的情况如何:
main = do f <- readFile "foo.txt"
print $ "prefix " ++ f
print $ f ++ " postfix"
Run Code Online (Sandbox Code Playgroud)
假设我们在IO monad中,则不可能简单地执行readFile两次计算.如何使用绑定语法表示此示例(如果可能的话)?
我认为使用Control.Monad不是解决方案,因为它在内部使用do块.
我认为可以使用箭头(使用&&&)表达这一点- 也许这只是一个箭头可以用作monads的推广的情况?
请注意,这个问题不是关于上面的特殊示例,而是关于在monadic表达式中多次使用计算结果的一般情况print.
Mig*_*Mit 11
是的,所有这些都可以转换为绑定语法; 实际上,它们是由编译器在内部转换的.
我希望你的例子的这个翻译给你提示:
main = readFile "foo.txt" >>= \f ->
(print $ "prefix " ++ f) >>
(print $ f ++ " postfix")
Run Code Online (Sandbox Code Playgroud)
该报告提供了从do语法到内核Haskell的完整翻译:
表达式是否满足以下身份,可以在消除空的stmts之后用作内核的转换:
Run Code Online (Sandbox Code Playgroud)do {e} = e do {e;stmts} = e >> do {stmts} do {p <- e; stmts} = let ok p = do {stmts} ok _ = fail "..." in e >>= ok do {let decls; stmts} = let decls in do {stmts}省略号“ ...”代表编译器生成的错误消息,传递给失败,最好给出模式匹配失败位置的指示;函数>>,>> =和fail是在Pread中定义的Monad类中的操作;好的是一个新的标识符。
因此,您的示例是这样翻译的:
do f <- readFile "foo.txt"
print $ "prefix " ++ f
print $ f ++ " postfix"
=
let ok f = do print $ "prefix " ++ f
print $ f ++ " postfix"
ok _ = fail "..."
in readFile "foo.txt" >>= ok
=
let ok f = (print $ "prefix " ++ f) >> do print $ f ++ " postfix"
ok _ = fail "..."
in readFile "foo.txt" >>= ok
=
let ok f = (print $ "prefix " ++ f) >> (print $ f ++ " postfix")
ok _ = fail "..."
in readFile "foo.txt" >>= ok
Run Code Online (Sandbox Code Playgroud)
这个版本没有do障碍,但看起来不是很自然。但是我们可以应用方程式推理以及我们知道的任何优化。因此,例如,观察该ok _ = fail "..."子句是无效代码,我们可能ok像这样:
=
readFile "foo.txt" >>= \f ->
(print $ "prefix " ++ f) >>
(print $ f ++ " postfix")
Run Code Online (Sandbox Code Playgroud)
do无需do这种方式,可以将所有块机械地翻译为代码。
| 归档时间: |
|
| 查看次数: |
228 次 |
| 最近记录: |