【问题标题】:What is the connection between primitive recursion and catamorphisms?原始递归和变态之间有什么联系?
【发布时间】:2020-10-10 22:47:54
【问题描述】:

对自然数使用以下变态,我可以实现各种算术算法,而无需处理递归:

cataNat :: b -> (b -> b) -> Natural -> b
cataNat zero succ = go
  where
    go n = if (n <= 0) then zero else succ (go (n - 1))

fib :: Natural -> Natural
fib = fst . cataNat (0, 1) (\(a, b) -> (b, a + b))

cataNat 在我看来类似于原始递归。无论提供zerosucc 的哪个组合,至少它的每个应用程序似乎都会终止。在每次迭代中,整个问题都被最小/最简单的问题实例分解。因此,即使它在技术上不是原始递归,它似乎也具有同样的表现力。如果这是真的,则意味着变态不足以表达一般递归。我们可能需要一个hylomorphism。我的推理是否正确,即是否对任何类型的变态都成立,而不仅仅是自然数?

【问题讨论】:

标签: haskell recursion functional-programming fold catamorphism


【解决方案1】:

原始递归直接对应于一个paramorphism。

你是正确的,变态与超态具有同等的理论能力,但它们在操作方面可能在重要方面有所不同。例如,让我们使用列表而不是 Nats。

cata :: b -> (a -> b -> b) -> [a] -> b
cata = flip foldr -- I'm lazy, but this argument order makes a bit more sense for this example

para :: b -> (a -> [a] -> b -> b) -> [a] -> b
para z _ []     = z
para z f (x:xs) = f x xs (para z f xs)

-- Removes the first element from the list which is equal to the other argument
delete1 :: Eq a => a -> [a] -> [a]
delete1 x xs = cata (const []) (\el k found -> if not found && el == x then k True else el : k found) xs False

-- Removes the first element from the list which is equal to the other argument
delete2 :: Eq a => a -> [a] -> [a]
delete2 x xs = para [] (\el raw processed -> if el == x then raw else el : processed) xs

看看delete1delete2 相比有多尴尬。您不仅必须通过将cata 的结果作为函数来扭曲您的逻辑,而且还会产生非常实际的运营成本。您必须在找到匹配元素后遍历列表中的所有内容,并重新创建所有 (:) 构造函数。这可能会在效率上产生显着的成本。相比之下,delete2 在找到目标元素时,可以直接使用列表的现有尾部作为剩余部分,甚至无需查看它。当然,foldr(现实世界,不是这个例子)的大多数用法都不会产生函数,也不想访问列表的未处理尾部。对他们来说,仅仅因为传递更少的数据,变质会稍微更有效率。

所以就理论能力而言,它们是等价的。在操作方面,每个都有用处,尽管变质现象更为常见。

对于更一般的概念的一些扩展,请参阅recursion-schemes 库。它使用了一种看起来相当不同的想法,以便它可以抽象出具有不同形状的数据类型,而不是需要为cata/para 为它们可以应用的每种数据类型使用不同的类型。但这实际上只是打包相同想法的另一种方式,并且还涵盖了其他类型的态射,包括许多moreniche(甚至possibly useless)的态射。

【讨论】:

  • 一个要点:foldr 的许多实际用途 产生一个功能!当您想通过列表计算从左到右传递一些“状态”时,这很有用。
猜你喜欢
  • 2011-05-31
  • 2012-12-04
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-28
  • 1970-01-01
相关资源
最近更新 更多