【问题标题】:Implementing tails using foldr in Haskell在 Haskell 中使用 foldr 实现尾部
【发布时间】:2014-06-09 21:10:27
【问题描述】:

所以今天早些时候我询问了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) [[]]

【问题讨论】:

  • 提示:根据教授的模式,在每一步,y 需要等于tails xs,其中xs 是原始列表中x 右侧的部分,并且undefined : undefined 必须是使用 x 和 y 为 tails (x:xs) 构建正确值的东西。

标签: haskell fold


【解决方案1】:

一些提示:

  • 你知道tails [] == [[]],所以你的初始值必须是[[]],所以你会有

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

  • length (tails xs !! n) > length (tails xs !! (n+1)),或者用简单的英语:每条尾巴的长度随着列表的向下而变短。

  • 你觉得foldr (\x (y:ys) -> undefined : undefined) [[]]怎么样?

如果您在一段时间后再次陷入困境(或已经想到这些),请发表评论,我会再推给您一次。

【讨论】:

  • 累加器值没问题。我的问题是,我必须在列表的前面附加一个项目(即 x 或 [],因为 y 不是正确的类型)。这只是让我不知何故。对于最内层的迭代(给定列表和累加器的最右边的值)很好,但是过去我只是被迷惑了
  • @powlomat 这主要是我最后的提示。如果您将累加器 (y) 上的模式匹配为 y:ys,则改为 y :: [a]、x :: a 和 ys :: [[a]]。你能用它做什么?
  • 是的,我很乐意这样做,但它会导致不被接受的模式匹配(在我们使用的更正工具中):( 我只是被允许替换“未定义”术语,而不是任何东西否则:/
  • @powlomat 然后用head y 和tail y 分别替换y 和ys,如果你被允许使用这些函数的话。
  • 谢谢,我可以利用它来解决它。将更新问题
【解决方案2】:

旁注,有趣的是,这个网站上的 Haskell 社区通常不喜欢给出平淡的答案,所以我想我会顺应潮流(OP 也没有要求平淡的答案)

这里有一些提示:

  • foldr 从右向左折叠

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

  • 从右到左看,结果的元素有什么区别?有规律吗?

【讨论】:

  • 我认为这是因为如果一个问题作为家庭作业出现,提示会比您可以复制和编译的内容为学生带来更多的学习。
【解决方案3】:

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

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

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

【讨论】:

  • listToMaybe 的用法似乎非常尴尬。 tails = unfoldr (\ xs -> do {(_ : tl) <- return xs; return (xs, tl)}) 怎么样?
  • 也许更好:定义uncons [] = Nothing、uncons (x:xs) = Just (x,xs)(这可能在某个库中,但我只为Text 和ByteString 找到它)。然后使用tails = unfoldr (\xs -> uncons xs >>= \(_, tl) -> Just (xs, tl))
  • 有一个严重的问题:tails 不是展开;没有办法得到空尾巴。我们想要unfold f [] = [[]],这意味着f [] = Just ([], something),但是f something必须是Nothing,并且没有可用于something的实际列表!
  • 啊,是的,没错,(空列表的情况)。
  • @dfeuer 就像我们的 found out few weeks later,它可以用同态来完成;可以通过带有嵌套Maybe 的标准展开器来模拟。我想这就是你提出这个问题的方式,也许吧。
猜你喜欢
  • 2016-09-04
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 2010-09-19
  • 2013-03-30
相关资源
最近更新 更多