【问题标题】:Reversing a list in another list in Haskell在 Haskell 中反转另一个列表中的列表
【发布时间】:2016-08-18 15:13:23
【问题描述】:

我对 Haskell 很陌生,我正在尝试反转一个列表。同时我想反转该列表中的列表。比如:

Prelude> rev [[3,4,5],[7,5,2]]
[[2,5,7],[5,4,3]]

我知道下面的代码反转了一个列表:

rev :: [[a]] -> [[a]]
rev [[]] = [[]]
rev [[x]] = [[x]]
rev xs = last xs : reverse (init xs)

我已经苦苦挣扎了一段时间,我对代码做了一些补充,但它仍然无法正常工作,我被卡住了。

rev :: [[a]] -> [[a]]
rev [[]] = [[]]
rev [[x]] = [[x]]
rev xs = last xs : reverse (init xs)
rev [xs] = last [xs] : reverse (init [xs])

如果有任何帮助,我将不胜感激。提前致谢。

【问题讨论】:

  • 无积分,这只是rev = reverse . map reverse
  • 顺便说一句,通过模式匹配编写reverse 的自然方式是使用辅助函数和累加列表;先rev ls = loop [] ls 然后loop acc [] = acc; loop acc (a:as) = loop (a:acc) ls

标签: list haskell functional-programming reverse


【解决方案1】:

我们必须颠倒内部列表和外部列表。要反转内部列表,您可以使用mapreverse 应用于列表的每个元素:map reverse [[3,4,5],[7,5,2]] == [[5,4,3],[2,5,7]]。然后再次反转结果reverse $ map reverse [[3,4,5],[7,5,2]] == [[2,5,7],[5,4,3]]

执行此操作的函数只是reversemap reverse 的组合,所以rev = reverse . map reverse

这里我们先反转内部列表,然后反转外部列表,但顺序无关紧要,我们可以反过来:rev = map reverse . reverse

【讨论】:

  • 先反转内部列表还是外部列表都没关系。
  • @Ingo 你说得对,这只是一种方便的谈话方式,可以使解决方案更清晰,思维过程更清晰;)但我会添加一个精确度
【解决方案2】:

最自然的方法当然是map reverse . reversereverse . map reverse。然而,明确地交错操作可能是最有效的:

revrev :: [[a]] -> [[a]]
revrev = foldl (\ acc xs -> reverse xs : acc) []

如果你想玩代码高尔夫,你可以这样写

revrev=foldl(flip((:).reverse))[]

但不要那样做。

【讨论】:

    猜你喜欢
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多