gpt4 book ai didi

haskell - 理解 I/O monad 和 "do"符号的使用

转载 作者:行者123 更新时间:2023-12-03 14:54:43 25 4
gpt4 key购买 nike

我仍在为 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 中。堵塞。我得到了简单的例子,但在这种情况下,我真的需要有人解释:
  • 为什么单用一个还不够do阻止 I/O 操作?
  • 为什么你必须在 if/else 情况下打开一个全新的?
  • 另外,do 的——我不知道怎么称呼它——“范围”是什么时候? monad 结束,即你什么时候可以使用标准的 Haskell 术语/函数?
  • 最佳答案

    do block 涉及与第一个语句处于相同缩进级别的任何内容。因此,在您的示例中,它实际上只是将两件事联系在一起:

     line <- getLine

    以及所有其他的,恰好更大:
     if null line  
    then return ()
    else do
    putStrLn $ reverseWords line
    main

    但无论多么复杂, do语法不考虑这些表达式。所以这一切都与
    main :: IO ()
    main = do
    line <- getLine
    recurseMain line

    使用辅助功能
    recurseMain :: String -> IO ()
    recurseMain line
    | null line = return ()
    | otherwise = do
    putStrLn $ reverseWords line
    main

    现在,显然 recurseMain 中的内容无法知道该函数是在 do 内调用的从 main 阻止,所以你需要使用另一个 do .

    关于haskell - 理解 I/O monad 和 "do"符号的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24293814/

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