使用文件夹实现汇整 [英] Implementing take using foldr
问题描述
这是我使用foldr
的take
版本:
myTake n list = foldr step [] list
where step x y | (length y) < n = x : y
| otherwise = y
main = do print $ myTake 2 [1,2,3,4]
输出不是我期望的:
[3,4]
然后我尝试通过将y
的长度插入自身来进行调试,结果是:
I then tried to debug by inserting the length of y
into itself and the result was:
[3,2,1,0]
我不明白为什么长度要按降序插入.也许我错过了一些明显的事情?
I don't understand why the lengths are inserted in decreasing order. Perhaps something obvious I missed?
推荐答案
如果要使用foldr
实现take
,则需要模拟从左到右遍历列表.关键是使折叠功能依赖于一个额外的参数,该参数对所需的逻辑进行编码,而不仅取决于列表的折叠尾巴.
If you want to implement take
using foldr
you need to simulate traversing the list from left to right. The point is to make the folding function depend on an extra argument which encodes the logic you want and not only depend on the folded tail of the list.
take :: Int -> [a] -> [a]
take n xs = foldr step (const []) xs n
where
step x g 0 = []
step x g n = x:g (n-1)
在这里,foldr
返回一个函数,该函数接受一个数字参数,并从左到右遍历列表,并从列表中取出所需的数量.由于懒惰,这也将适用于无限列表.一旦多余的参数达到零,foldr
就会短路并返回一个空列表.
Here, foldr
returns a function which takes a numeric argument and traverses the list from left to right taking from it the amount required. This will also work on infinite lists due to laziness. As soon as the extra argument reaches zero, foldr
will short-circuit and return an empty list.
这篇关于使用文件夹实现汇整的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!