Haskell中的IO与interact和map

6
我试图使用 interact 函数和 map 来制作一个交互式的 Haskell 程序。
以下是在 ghci 中的输出结果(据我所知,所有教程都是按照这种方式解释 interact 的用法 -- 除了结果)。
*Module> interact $ unlines . map (++ "!") . lines
tteesstt
!

请注意,实际发生的情况是我输入的每个字符都会立即重复,并且在我按下回车键后才会出现感叹号。然而,我预期的是这样的结果:
*Module> interact $ unlines . map (++ "!") . lines
test
test!

如果我使用相同的程序结构,但是使用filter而不是map,那么它将完美地工作。

2个回答

10

问题是ghci会把缓存模式更改为按字符缓存,这意味着程序会在读取到字符后立即处理代码。如果你将这行代码写入名为foo.hs的文件中,

main = interact $ unlines . map (++ "!") . lines

如果你使用 runhaskell foo.hs 运行它,你会发现它按预期工作,因为Haskell默认使用行缓冲。


1
谢谢,这是完全正确的。可以通过执行 import IO 然后 hSetBuffering stdout LineBuffering 将其设置为行缓冲。 - notan3xit

3
如FUZxxl所说,这是一个缓冲问题。要在GHCi中更改缓冲样式,请使用hSetBuffering。
Prelude> :m +System.IO
Prelude System.IO> hSetBuffering stdout LineBuffering 
Prelude System.IO> interact $ unlines . map (++"!") . lines
hello
hello!
^CInterrupted.
Prelude System.IO> 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接