【发布时间】:2014-08-09 05:40:59
【问题描述】:
我仍在为 Haskell 苦苦挣扎,现在我遇到了一个问题,就是围绕 Input/Output monad from this example:
main = do
line <- getLine
if null line
then return ()
else do
putStrLn $ reverseWords line
main
reverseWords :: String -> String
reverseWords = unwords . map reverse . words
我知道因为像 Haskell 这样的函数式语言不能基于函数的副作用,所以必须发明一些解决方案。在这种情况下,似乎所有内容都必须包装在 do 块中。我得到了简单的例子,但在这种情况下,我真的需要有人解释:
- 为什么对于 I/O 操作仅使用一个
do块还不够? - 为什么必须在 if/else 情况下打开全新的?
- 另外,我不知道怎么称呼它
domonad 的“范围”什么时候结束,即什么时候可以使用标准的 Haskell 术语/函数?
【问题讨论】:
-
do只是语法糖,以避免使用>>=和>>编写过于复杂的语句,它适用于所有 monad,并且与 IO 没有特殊关联。您不必在示例代码中使用第二个do(您甚至不需要第一个do,但生成的代码会更难阅读),您也可以编写else putStrLn (reverseWords line) >> main,它会有同样的效果。 -
我在这里回答了一个非常相似的问题:stackoverflow.com/questions/23049409/… 这有帮助吗?诀窍是基本上看所有函数的返回类型,一切都会到位。
-
This 博客文章是一个很好的读物,如果你在一般情况下都在与 monad 作斗争,情况似乎就是这样。阅读 .hs 文件并打开 ghci 提示符,以便您进行练习。
-
非常感谢您的帮助,好的教程可以比理论更好地解释一切。
标签: haskell functional-programming do-notation