在Haskell中编写Lambda微积分高阶递归方案

发布于 2025-02-11 18:21:32 字数 1140 浏览 0 评论 0原文

[我在这里的新理由,可能有一些歧义]

考虑递归(这是对较高类型的原始递归的概括),

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

其中r是Sigma型,A是Sigma类型的Sigma,B是Sigma类型 - &GT类型; n-> Sigma和C是N型。

如果我们将Sigma的类型视为自然数,则递归是原始的递归,因此我们可以定义原始的递归函数。现在,如果我们将Sigma的类型更改为n - > n,我们可以使用r来定义超过原始递归函数的函数,一个示例是ackermann函数,但定义的所有函数将是总的。我的兴趣是了解递归的真正工作原理,因为该概念在另一种情况下似乎有用。

我遇到了一篇文章,该文章将R定义为上述,并使用lambda cyculus来定义前任,加法和乘法的功能,如下所示(对介绍 - 对介绍 - 我没有声誉来发布图像

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,添加和多函数?

[I'm on new grounds here, there might be some ambiguities]

Consider the recursor (which is a generalization of primitive recursion over higher types)

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

Where R is of type sigma, A is of type sigma, B is of type sigma -> N -> sigma and C is of type N.

If we take the type of sigma to be a natural number, the recursor is primitive recursion and with it we can define the primitive recursive functions. Now, if we change the type of sigma to be N -> N, we can use R to define functions that outgrow primitive recursive functions, an example being Ackermann function, but all the functions defined will be total. My interest is to understand how the recursor really works, because the concept seems useful in another context.

I came across an article that defines R as above and uses lambda calculus to define the functions of predecessor, addition and multiplication as follows (sorry about the presentation - I don't have reputation to post images)

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)

After some working on this I was not able to define the functions nor the recursor in Haskell. I tried to define the recursor as a function

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

But I don't understand, for example, how I can use this to define the multiplication because I don't understand how the parameters should be fed/defined. Should I implement two different functions for the different recursion schemes?

The predecessor seems to work when written like this, and I can get the addition implemented, but multiplication goes over my head.

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

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

How would one define the recursor and the Pred, Add and Mult functions with it in Haskell?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

紫﹏色ふ单纯 2025-02-18 18:21:32

这似乎主要是混凝土语法的问题:

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)

This seems mainly an issue of concrete syntax:

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文