我正在学习Haskell,而且我遇到了一些我无法理解的东西,而且我无法找到解释。所以,我在无限列表上测试了一些函数,看看它们是如何工作的,我发现了我想要理解的地图和滤镜之间的差异。
Prelude.map
定义:
map _ [] = []
map f (x:xs) = f x : map f xs
Prelude.filter
定义:
filter _pred [] = []
filter pred (x:xs)
| pred x = x : filter pred xs
| otherwise = filter pred xs
如果我这样做:
map (==5) [1..]
输出开始,它永远不会结束,直到我停止它。因为列表是无限的,所以很有意义。
但现在如果我这样做:
filter (==5) [1..]
我什么也没看到,甚至没有[5,
。
这也是有道理的,因为列表也是无限的,但我想了解这是什么区别beetwen map和filter。
谢谢你,对不起我的英文!
编辑:我使用的是tryhaskell.org,这就是问题!
答案 0 :(得分:8)
正如评论中所发现的,这是由于使用了Try Haskell。从实验开始,在结束并向您发送结果之前,它似乎将等待程序终止,经过3秒或产生1024个字符的输出。不幸的是,filter (==5) [1..]
只会生成两个字符([5
),不符合1024个字符的限制,由于某种原因,Try Haskell不会向您发送[5
。在真正的GHCi中运行它应该可以正常工作。
答案 1 :(得分:3)
它与buffer settings有关。编译时,默认情况下, stdin 和 stdout 的BufferMode通常设置为LineBuffering,仅在换行,缓冲区溢出或手动刷新时打印。
GHCi的BufferMode设置为NoBuffering¹,它将立即打印您的结果。
如果是LineBuffering:
map (==5) [1..]
打印其结果,因为它的大输出会导致大量缓冲区溢出。 filter (==5) [1..]
从不填充缓冲区或写入换行符。所以它不打印。 ¹。 NoBuffering for stdin might not work on Windows cmd, when compiled with GHC.