【问题标题】:Haskell: words count from a getLine without the "do" notationHaskell:单词从没有“do”表示法的 getLine 计数
【发布时间】:2016-10-06 09:00:53
【问题描述】:

如何在不使用“do”表示法的情况下编写以下函数?

wordsCount =  do 
    putStr "Write a line and press [enter]:\n"
    s <- getLine
    putStr $ show $ length . words $ s
    putChar '\n'

【问题讨论】:

  • 这两个问题(1,2)也是关于去糖的 do 语法。 This answer 也很好地解释了如何做到这一点。

标签: haskell getline notation


【解决方案1】:

您可以使用&gt;&gt; 和&gt;&gt;=,而不是使用do:

wordsCount = putStr "Write a line and press [enter]:\n" >> getLine >>= putStr . show . length . words >> putChar '\n'

或者让它更容易阅读:

wordsCount = putStr "Write a line and press [enter]:\n" >>
    getLine >>=
    putStr . show . length . words >>
    putChar '\n'

更直接的翻译是:

wordsCount = putStr "Write a line and press [enter]:\n" >>
    getLine >>=
    \s -> (putStr $ show $ length $ words s) >>
    putChar '\n'

基本上,编译器将此类do-notation 块转换为其一元等效项(仅使用&gt;&gt; 和&gt;&gt;=)。 do 只是语法糖,因此不必每次都写 &gt;&gt;= 和/或管理变量。

补充说明:

  • 正如@ChadGilbert 在his comment 中所说,括号应该包裹在函数中,不包括\s -&gt;,以便稍后可以在程序中使用s,例如:

    -- This is not an equivalent program
    wordsCount = putStr "Write a line and press [enter]:\n" >>
        getLine >>=
        \s -> (putStr $ show $ length $ words s) >>
        putChar '\n' >>
        putStrLn s -- repeat s
    
  • 您可以使用putStrLn,而不是使用putStr 和putChar。例如:

    wordsCount = putStr "Write a line and press [enter]:\n" >>
        getLine >>=
        putStrLn . show . length . words
    

【讨论】:

  • 在您更直接的翻译中,括号不应该简单地包裹putStr $ show $ length $ words s 语句吗?包装(\s -&gt; putStr $ show $ length $ words s) 意味着s 在后续的monadic 语句中不可用
  • @ChadGilbert:你的意思是喜欢更新的答案?确实是的。感谢您发现这一点。
  • @ChadGilbert:我已经用附加说明更新了答案,以进一步解释问题,非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多