【问题标题】:Implement recursion using foldl in haskell在haskell中使用foldl实现递归
【发布时间】:2016-05-24 21:07:19
【问题描述】:

给定以下代码

pair :: [String] -> [(String,String)]
pair [] = []
pair (x:xs)= zip [x] xs ++ pair xs

如何使用 Fold 重写它以避免重复?

【问题讨论】:

  • 你已经尝试过什么了吗?
  • 我试过这个 f= foldl (++) [] 一个对列表并返回一个对列表
  • 酷。最好将您的代码放入您的问题中,以便其他人知道可能导致问题/错误的原因。您还可以输入您期望的输出吗?您使用 fold 的版本返回的结果与您的原始代码不同。
  • 如果“避免重复”是指编写更少的代码,甚至可以避免使用 fold 并尝试类似:zip xs (tail xs)
  • x:xs 的递归分支仅依赖于xf xs 时,您可以使用foldr。你的也依赖于xs。 (可以使用更复杂的折叠,无论如何都可以实现,但它不可读)

标签: haskell functional-programming


【解决方案1】:

对于这个特殊问题,折叠会有点混乱,因为您的折叠功能取决于列表中先前访问过的元素,并且列表最小值为二值。而且由于一次折叠访问一个元素,当列表中只有一个元素时,您必须决定要做什么。

下面是一个示例,它为单例列表案例创建一个虚拟元素并使用init 将其丢弃。

pair :: [String] -> [(String, String)]
pair = init . foldr f []
  where
    f x acc =
      case acc of
        [] -> [(x, "discarded")]
        z@(y:_) -> (x, fst y) : z

如果您的任务是学习折叠,请花一点时间了解为什么我们必须以如此不令人满意的方式处理它。否则,如果您希望以最少的代码量来执行此操作,请参阅上面的@DavideSpataro 对zip xs (tail xs) 的回答。

【讨论】:

    猜你喜欢
    • 2016-09-04
    • 2019-08-26
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2018-02-28
    • 1970-01-01
    • 2021-12-20
    相关资源
    最近更新 更多