Haskell:优雅地循环用户输入

时间:2017-11-01 05:17:21

标签: loops haskell monads

这是Learn You a Haskell

的示例
main = do
    putStrLn "hello, what's your name?"
    name <- getLine
    putStrLn ("Hey, " ++ name ++ ", you rock!")

为清晰起见,没有do的相同重做:

main =
    putStrLn "hello, what's your name?" >>
    getLine >>= \name ->
    putStrLn $ "Hey, " ++ name ++ ", you rock!"

我应该如何干净地循环(直到“q”),Haskell方式(使用do劝阻)?

我是从Haskell - loop over user input

借来的
main = mapM_ process . takeWhile (/= "q") . lines =<< getLine
    where process line = do
                            putStrLn line

对于初学者,但它不会循环。

2 个答案:

答案 0 :(得分:1)

您可以再次致电main并检查您的字符串是否为&#34; q&#34;或不。

import Control.Monad

main :: IO ()
main =
    putStrLn "hello, what's your name?" >>
    getLine >>= \name ->
                  when (name /= "q") $ (putStrLn $ "Hey, " ++ name ++ ", you rock!") >> main

λ> main
hello, what's your name?
Mukesh Tiwari
Hey, Mukesh Tiwari, you rock!
hello, what's your name?
Alexey Orlov
Hey, Alexey Orlov, you rock!
hello, what's your name?
q
λ> 

答案 1 :(得分:0)

也许您可以通过调整System.IO.Lazy包来使用IO类型的懒惰。它基本上只包含interleave :: IO a -> T aimport qualified System.IO.Lazy as LIO getLineUntil :: String -> IO [String] getLineUntil s = LIO.run ((sequence . repeat $ LIO.interleave getLine) >>= return . takeWhile (/=s)) printData :: IO [String] -> IO () printData d = d >>= print . sum . map (read :: String -> Int) *Main> printData $ getLineUntil "q" 1 2 3 4 5 6 7 8 9 q 45 函数,可以将IO操作来回转换为惰性操作。

getLine

在上面的代码中,我们按repeat $ LIO.interleave getLine类型的[T String]sequence构建了一个无限的T [String]列表,我们将其转换为printData类型然后继续阅读直到&#34; q&#34;收到了。 <td rowSpan="1" colSpan="1"> Mrs Mallet Anonime <br></br> 11, RUE FRANCOIS BOLLE <br></br> 12345 PARIS 05 FRANCE <br></br> </td> 效用函数正在汇总并打印输入的整数。