使用文件夹实现汇整 [英] Implementing take using foldr

查看:88
本文介绍了使用文件夹实现汇整的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我使用foldrtake版本:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆