如何使用fold?
在Haskell中实现takeWhile函数takeWhile :: (a -> Bool) -> [a] -> [a]
我尝试了一种类似于实现此过滤器的策略
filter :: (a -> Bool) -> [a] -> [a]
filter f = foldr (\x acc -> if f x then x : acc else acc) []
但是当f x为假时我怎么能停止?
答案 0 :(得分:8)
只需在acc
分支中将[]
更改为else
:
takeWhile f = foldr (\x acc -> if f x then x : acc else []) []
这个想法是你在使用输入列表中的元素时懒得构建结果列表,所以当你想终止结果列表时返回[]
。
takeWhile (< 3) [0..]
=
0 : takeWhile (< 3) [1..]
=
0 : 1 : takeWhile (< 3) [2..]
=
0 : 1 : 2 : takeWhile (< 3) [3..]
=
0 : 1 : 2 : []
=
[0, 1, 2]
这也说明了Haskell列表实际上是 streams 的值。右侧折叠是小型状态机,它们逐步移动输入流以生成输出流。