首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何迭代或重复非类型化函数n次?

问如何迭代或重复非类型化函数n次?
EN

Stack Overflow用户
提问于 2021-03-17 02:37:55
回答 1查看 260关注 0票数 0

我正在使用OCaml编译器进行实践,我正在执行一项小任务,我们必须实现教会数字,定义为:

zz = pair c0 c0; ss = λp. pair ( snd p) ( plus c1 (snd p)); prd = λm. fst (m ss zz );

为了计算我想要实现的ss加上:

plus = λm. λn. λs. λz. m s (n s z)

所以我的问题是,如何实现函数加,像n倍succ 0?

我尝试过类似于plus = lambda m. lambda n. lambda s. lambda z. m s (n s z);,但在编译器中它是不正确的。

我注意到我在OCaml编译器中工作,并将我的所有函数都写在函数.f文件中,而不是在.ml文件中

代码来自那里,全类型文件夹

EN

回答 1

Stack Overflow用户

发布于 2021-03-17 10:45:10

而不是像在lambda演算中那样使用lambda,而是使用fun在OCaml中对教会数字进行编码。将数字定义为采用一元函数( s表示“后继”)和基值(z表示“零”)的函数。例如,三个是:

代码语言:javascript
复制
# let three = fun s z -> (s (s (s z)));;
val three : ('a -> 'a) -> 'a -> 'a = <fun>

如果要将此表示形式转换为OCaml整数,则定义:

代码语言:javascript
复制
# let int_succ x = x + 1;;

然后,您可以通过如下方式调用OCaml整数表示three:

代码语言:javascript
复制
# three int_succ 0;;
- : int = 3

它有效地在0上连续调用int_succ,在最内部的结果(即。1)等,直到你得到3。

但你可以在他们的教会代表中操纵这些数字,如下所示。例如,要计算任意旋转数n的后续教会数,请执行以下操作:

代码语言:javascript
复制
# let succ n = fun s z -> (s (n s z));;

我们必须返回一个教堂数,结果是两个参数的函数,s和z。它还需要一个单一的输入,教堂号码n。结果是在s上调用(n s z),即数字n的后继。例如:

代码语言:javascript
复制
# (succ three) int_succ 0;;
- : int = 4

同样,我们可以定义add

代码语言:javascript
复制
# let add x y = (fun s z -> (x s (y s z)));;
val add : ('a -> 'b -> 'c) -> ('a -> 'd -> 'b) -> 'a -> 'd -> 'c = <fun>

在这里,函数需要两个数字。表达式(y s z)表示在数字y上所做的计算,并用作在(x s (y s z))中应用x时的基值。如果将int_succ和0用于s和z,则可以看到(y s z)将从y编码的0倍增加到由x编码的值的0倍。

例如:

代码语言:javascript
复制
# let two = fun s z -> (s (s z)) ;;
val two : ('a -> 'a) -> 'a -> 'a = <fun>

然后:

代码语言:javascript
复制
# let five = add two three;;
val five : ('_weak4 -> '_weak4) -> '_weak4 -> '_weak4 = <fun>

注意,类型是弱的,您不需要太担心它,但这意味着一旦使用给定的s和z调用了five,就无法使用不同类型的five。

代码语言:javascript
复制
# five int_succ 0;;
- : int = 5

现在,这种类型是众所周知的:

代码语言:javascript
复制
# five;;
- : (int -> int) -> int -> int = <fun>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66666235

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档