我们如何在SML中编写递归函数?

问题描述

这是我正在实现的递归函数的python代码。

def f(x):
  return x+1
def iter(n,f,x):
  if n == 0:
    return x
  return iter(n-1,f(x))

调用iter

iter(7,9)

如何用SML编写它?

fun iter 0 f x = x
  |iter n f x = iter(n-1,f(x));    

解决方法

OP代码将咖喱函数符号与元组符号混合在一起。 OP定义了一个curried函数,但是随后在递归调用中将一个元组传递给它。有两种明显的解决方案:决定要使用咖喱符号还是元组符号,并始终使用。

使用元组符号iter会包含包含参数的 tuple ,即,此处iter实际上仅接受一个参数,该参数是一种包含参数的数据类型。也就是说,元组iter的类型为:fn : int * ('a -> 'a) * 'a -> 'a

fun iter (0,_,x) = x
  | iter (n,f,x) = iter(n-1,f x);

上面的描述可能有所不同,例如iter((n-1),(f x))iter((n-1),f(x))

使用咖喱符号iter接受一个int参数,并返回一个接受函数参数的函数,返回一个接受与传递的函数匹配的参数的函数。也就是说,咖喱iter的类型为fn : int -> ('a -> 'a) -> 'a -> 'a

fun iter 0 _ x = x
  | iter n f x = iter (n-1) f (f x);

元组版本和咖喱版本是两种截然不同的情况。在元组版本中,如果您传递的“参数”少于三个,则会出现类型错误,例如:

- iter(2,double);
stdIn:1.2-1.17 Error: operator and operand do not agree [tycon mismatch]
  operator domain: int * ('Z -> 'Z) * 'Z
  operand:         'Y[INT] * (int -> int)
  in expression:
    iter (2,double)

问题在于元组版本需要一个包含三个字段的元组参数。通过少于三个字段的元组违反了这种期望。

但是在咖喱版本中,如果您传递的参数少于三个,则将具有部分函数应用程序:

- val doubleTwice = iter 2 double;
val doubleTwice = fn : int -> int
- doubleTwice 3;
val it = 12 : int
- doubleTwice 5;
val it = 20 : int

这里,仅将两个参数传递给已管理的iter,其中一个参数是将double翻倍的int函数,返回的函数会将输入值翻倍两次。咖喱函数可能非常有用,您需要了解这两种样式之间的区别。

,

语法是:

fun iter 0 f x = x
  | iter n f x = iter (n-1) f (f x);

注意:由于f不会出现在结果表达式中,因此您可以在第1行将_替换为f

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...