Haskell:为什么这个函数不断要求用户输入而不是终止

时间:2016-04-16 07:04:15

标签: haskell

我正在学习一些Haskell而且我遇到了这个小程序

reverseLines :: String -> String
reverseLines input = 
    unlines (map reverse (lines input))

main :: IO ()
main = interact reverseLines

该程序将不断要求用户输入更多信息并反转输入并将其打印在屏幕上。

大部分内容都是直截了当的,但有一点我无法解决这个问题,为什么这个函数会继续运行并要求用户提供更多输入,而如果我只是将reverseLines函数替换为函数简单地返回一些不会发生的字符串。

该程序将在执行一次后停止:

foo input = "Stops"
main :: IO ()
main = interact foo

为什么?

1 个答案:

答案 0 :(得分:4)

如果您查看source of interact,就会看到:

interact f      =   do s <- getContents
                       putStr (f s)

请参阅getContents?这就是魔术开始的地方 - 它将读取所有内容,直到 EOF

现在在Haskell中这是 lazy-IO 这可能很糟糕但这里几乎是神奇的 - 看到字符串被懒惰地读取并传递给你的reverseLines - 这当然只会一看到\n个字符(lines)就会生成输出,所以看起来你的程序是某种REPL。

在第二个中你根本不使用任何一个懒字符串,所以它会尽快停止

正如我在评论中写的那样,您可以通过使用文件(或echo)和终端上的管道将内容传递到程序中来玩这个:

echo "Hello World\nBye Bye" | runhaskell LazyIO.hs

或使用CTRL-D自己传递EOF。

为了感受它,我会更多地使用这些函数 - 如果您使用需要先查看完整输入的内容会发生什么(在没有地图的情况下尝试reverse)?使用words代替lines,...?

会发生什么

玩得开心!