如何在Haskell中无限读取和处理用户输入
我希望我的命令行Haskell程序的功能如下: 程序等待用户输入如何在Haskell中无限读取和处理用户输入,haskell,Haskell,我希望我的命令行Haskell程序的功能如下: 程序等待用户输入 用户键入内容,按“回车” Haskell处理输入,在标准输出上显示结果 Haskell等待下一个用户输入 若并没有更多的输入,用户通过Ctrl+D终止程序 我试过获取内容。但getContents会等待用户在处理所有行之前键入它们。使用和读取输入 这避免了使用interact时出现的惰性i/o问题 (如果不使用isEOF,则按Ctrl+D时将引发异常。) import Control.Monad(除非) 导入System.IO(i
interact
时出现的惰性i/o问题
(如果不使用isEOF
,则按Ctrl+D时将引发异常。)
import Control.Monad(除非)
导入System.IO(isEOF)
processEachLine::(字符串->IO a)->IO()
processEachLine k=do
完成您可以尝试使用交互
功能。它接受类型为String->String
的函数,并将其转换为读取stdin的操作,将其连续传递给函数,然后写入函数返回stdout的字符串。如果您注意不要过度使用输入字符串,您将获得所请求的行为。这里有很多混乱。让我们把事情弄清楚
我试过获取内容。但getContents会等待用户键入所有行,然后再进行处理
这里最可能的情况是,您已经编译了程序,但没有注意到输出的默认缓冲是块缓冲。这很容易解决:
f line = putStrLn ("Hi, " ++ line ++ "!")
main = do
hSetBuffering stdout LineBuffering -- or use NoBuffering
putStrLn "Enter some names."
input <- getContents
mapM_ f (lines input)
…程序将在每行之后打印更多的输出。您可能还想将stdin
的缓冲设置为NoBuffering
(而不是默认的LineBuffering
),因为show
的效率足够高,它确实可以在每次击键后产生更多的输出。特别是,交互(unlines.map processTheInput.lines)
。非常好!但在我的第一次尝试中,我使用了“互动秀”,但它不起作用。你知道为什么吗?@osager因为show
在其全部输入用尽之前不会返回任何输出<代码>交互
需要一个递增求值函数。@osager另外,请检查缓冲是否设置为Line@Ptharien'sFlame来自IRC频道的人建议我使用它:hSetBuffering stdin LineBuffering。但是“交互显示”仍然不起作用getContents
返回一个延迟的字符列表。也许消费函数太严格了。如果你想输入一个String->String
类型的函数,你可以很容易地创建一个类似的助手:processLinesPure::(String->String)->IO();processLinesPure f=processEachLine(putStrLn.f)
f line = putStrLn ("Hi, " ++ line ++ "!")
main = do
hSetBuffering stdout LineBuffering -- or use NoBuffering
putStrLn "Enter some names."
input <- getContents
mapM_ f (lines input)
main = do
hSetBuffering stdout NoBuffering
interact show