在Haskell中使用foldr实现尾部

时间:2014-06-09 21:10:27

标签: haskell fold

今天早些时候我问过implementing inits via foldr。我现在有类似的尾巴问题。 首先要做的是:我有一个解决方案。然而,它不是我需要的解决方案,而是我应得的解决方案。或类似的东西:

代码:

tails :: [a] -> [[a]]
tails = foldr ( \ x y ->  reverse([] : reverse(map (x:) y) )) [[]]

这提供了正确的结果,但它不符合我们的教授为我们设定的模式。模式看起来像这样:

tails :: [a] -> [[a]]
tails = foldr ( \ x y -> undefined : undefined ) undefined

所以显然我的功能需要调整,但是我不会理解它,因为我总是回到我的解决方案。

有关如何更好地解决这个问题的任何提示?

提前致谢。

解决:

tails :: [a] -> [[a]]
tails = foldr ( \ x y -> (x : (head y)) : y) [[]]

3 个答案:

答案 0 :(得分:4)

一些提示:

  • 您知道tails [] == [[]],因此您的初始值必须为[[]],因此您将

    tails = foldr (\x y -> undefined : undefined) [[]]

  • length (tails xs !! n) > length (tails xs !! (n+1)),或者用简单的英语:每个尾部的长度都会随着你的列表而缩短。

  • 您如何看待foldr (\x (y:ys) -> undefined : undefined) [[]]

如果你再次陷入困境(或者已经想到这些),请发表评论,我会给你另一个推动。

答案 1 :(得分:3)

旁注,我觉得这个网站上的Haskell社区一般不喜欢给出平坦的答案,所以我想我会跟随这个趋势(OP也没有要求一个平坦的答案)

以下是一些提示:

  • foldr从右到左折叠

  • 查看tails "abc"的输出,它是["abc", "bc", "c", ""]。你如何构建从右到左的列表? (或换句话说,在列表中添加内容)

  • 从右到左看结果的元素有什么区别?有模式吗?

答案 2 :(得分:0)

我不知道为什么,但我似乎最近到处都看到了展开,包括在这个问题中:

import Data.List (unfoldr)
import Data.Maybe (listToMaybe)

tails :: [a] -> [[a]]
tails = unfoldr (\ xs -> listToMaybe xs >> Just (xs, tail xs))