简体   繁体   English

在Haskell中使用foldr实现尾部

[英]Implementing tails using foldr in Haskell

So earlier today I asked about implementing inits via foldr . 所以今天早些时候我问过通过foldr实现inits I have a similar question for tails now. 我现在有类似的尾巴问题。 First things first: I have A solution. 首先要做的是:我有一个解决方案。 However it's not the solution I need, but the solution I deserve. 然而,这不是我需要的解决方案,而是我应得的解决方案。 Or something like that: 或类似的东西:

Code: 码:

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

This provides correct results, however it does not fulfill the pattern our prof set for us. 这提供了正确的结果,但它不符合我们的教授为我们设定的模式。 The pattern looks like this: 模式看起来像这样:

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

So obviously my function needs tweaking, however I do not get my head around it, since I always fall back to my solution. 所以显然我的功能需要调整,但是我不会理解它,因为我总是回到我的解决方案。

Any tips on how to solve this better? 如何更好地解决这个问题的任何提示?

Thanks in advance. 提前致谢。

Solved: 解决了:

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

Some hints: 一些提示:

  • You know that tails [] == [[]] , so your initial value has to be [[]] , so you'll have 你知道tails [] == [[]] ,所以你的初始值必须是[[]] ,所以你会有

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

  • length (tails xs !! n) > length (tails xs !! (n+1)) , or in plain english: the length of each tail gets shorter as you go down the list. length (tails xs !! n) > length (tails xs !! (n+1)) ,或者用简单的英语:当你沿着列表向下时,每个尾部的长度变短。

  • What do you think about foldr (\\x (y:ys) -> undefined : undefined) [[]] ? 你怎么看待foldr (\\x (y:ys) -> undefined : undefined) [[]]

If you get stuck after a while again (or have already thought of these), leave a comment and I'll give you another nudge. 如果你再次陷入困境(或者已经考虑过这些),请留言,我会给你另一个推动。

Sidenote, its interesting to me that the Haskell community on this site generally don't like to give flat answers, so I guess I will follow the trend (also the OP did not ask for a flat out answer) 旁注,我觉得这个网站上的Haskell社区一般不喜欢给出平坦的答案,这让我很有兴趣,所以我想我会跟随这个趋势(OP也没有要求一个平坦的答案)

Here are some hints: 以下是一些提示:

  • foldr folds from right to left foldr从右到左折

  • Look at the output of tails "abc" , it's ["abc", "bc", "c", ""] . 查看tails "abc"输出tails "abc" ,它是["abc", "bc", "c", ""] How do you construct the list going from right to left? 你如何构建从右到左的列表? (or in other words, prepending things to the list) (或换句话说,在列表中添加内容)

  • What is the difference between the elements of the result, looking from right to left? 从右到左看结果的元素有什么区别? Is there a pattern? 有模式吗?

I don't know why, but I seem to be seeing unfolds everywhere of late, including in this question: 我不知道为什么,但我似乎最近到处都看到了展开,包括在这个问题中:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM