繁体   English   中英

在 Haskell 中编写 lambda 演算高阶递归方案

[英]Writing lambda calculus higher order recursion scheme in Haskell

[我在这里有新的理由,可能有一些模棱两可]

考虑递归器(它是对更高类型的原始递归的概括)

R_\sigma A B 0 = A
R_\sigma A B (S(C)) = B(R_\sigma A B C) C

其中 R 是 sigma 类型,A 是 sigma 类型,B 是 sigma -> N -> sigma 类型,C 是 N 类型。

如果我们将 sigma 的类型设为自然数,则递归是原始递归,我们可以使用它定义原始递归函数。 现在,如果我们将 sigma 的类型更改为 N -> N,我们可以使用 R 定义超出原始递归函数的函数,例如 Ackermann 函数,但定义的所有函数都是总计的。 我的兴趣是了解递归器的真正工作原理,因为这个概念在另一种情况下似乎很有用。

我遇到了一篇文章,上面定义了 R,并使用 lambda 演算来定义前任、加法和乘法的函数,如下所示(抱歉介绍 - 我没有发布图像的声誉)

Pred^{N->N} = R_N 0_N (\lambda a^N b^N.b)
Add^{N->N->N} = \lambda x^N. R_N x(\lambda a^N b^N.S_+ a)
Mult^{N->N->N} = \lambda x^N. R_N 0_N(\lambda a^N b^N. Add a x)

经过一些工作后,我无法在 Haskell 中定义函数或递归器。 我试图将递归定义为一个函数

rn :: Int -> (Int -> Int -> Int) -> Int -> Int
rn a b 0 = a
rn a b c = b(rn a b (c-1)) (c-1)

但是我不明白,例如,我如何使用它来定义乘法,因为我不明白应该如何输入/定义参数。 我应该为不同的递归方案实现两个不同的功能吗?

像这样写的前身似乎可以工作,我可以实现加法,但乘法却超出了我的想象。

project2to2 :: Int -> Int -> Int
project2to2 m n = n

predecessor :: Int -> Int
predecessor a = rn 0 project2to2 a

在 Haskell 中如何定义递归器和 Pred、Add 和 Mult 函数?

这似乎主要是具体语法的问题:

predecessor :: Int -> Int
predecessor = rn 0 (\a b -> b)

add :: Int -> Int -> Int
add = \x -> rn x (\a b -> 1+a)

mult :: Int -> Int -> Int
mult = \x -> rn 0 (\a b -> add a x)

暂无
暂无

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

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