我目前正在学习sml,但我有一个问题,我无法找到答案。我用谷歌搜索,但仍然没有找到任何东西。
这是我的代码:
fun diamond(n) =
if(n=1) then (
print("*")
) else (
print("*")
diamond(n-1)
)
diamond(5);
这不起作用。我希望代码显示尽可能多的*和数字n,我想用递归来做,但我不明白如何做到这一点。
当我尝试运行该代码时出现错误。这是错误:
新泽西州标准ML v110.78 [建造时间:2015年8月20日星期四19:23:18] [打开a4_p2.sml] a4_p2.sml:8.5-9.17错误:运算符不是a function [tycon mismatch] operator:表达式中的单位: (打印" *")diamond / usr / local / bin / sml:致命错误 - 未捕获异常错误,0引发 ../编译器/顶层/交互/ evalloop.sml:66.19-66.27
谢谢
答案 0 :(得分:2)
您可以使用';'在ML中进行副作用 它将评估';'之前的任何内容并丢弃其结果。
fun diamond(n) =
if(n=1)
then (print "*"; 1)
else (print "*"; diamond(n-1));
diamond(5);
错误的原因是因为ML是一种强类型语言,虽然您不需要明确指定类型,但它会在编译时根据环境因素推断它们。出于这个原因,每个函数评估,if
else
等语句都需要评估为明确的单数类型。
如果您被允许执行以下操作:
if(n=1)
then 1
else print "*";
然后编译器将分别为then
和else
分支输入不同的类型。
对于then
分支,类型为int -> int
,而else
分支的类型为int -> unit
在强类型语言下不允许这样的二分法。
当您需要评估单数类型时,您将理解ML不支持执行一个指令块,因为我们在其他范例中常见的转换为ML的天真将会呈现如下内容:
....
if(n=1)
then (print "1"
print "2"
)
else (print "3"
diamond(n-1)
)
...
因为then分支会评估什么类型? int -> unit
?那么其他印刷声明怎么样?声明必须返回一个单一的结果(即使它是一个复合词),所以这是没有意义的。那么int -> unit * unit
呢?没问题,除了从语法上讲,你没有将元组传递给编译器。
出于这个原因,以下WOULD工作:
fun diamond(n) =
if(n=1)
then (print "a", 1) /* A tuple of the type unit * int */
else diamond(n-1);
diamond(5);
在这种情况下,你有一个类型为int的函数 - > unit * int。
因此,为了满足强类型函数式编程范式的要求,我们努力构建评估一种结果类型的机制,因此我们需要与编译器进行通信,将某些语句作为指令执行。不得在所考虑的功能的类型下加入。 出于这个原因,你使用';'与编译器进行通信,以简单地评估该语句,并将其结果丢弃在函数的类型评估中。
就您的实际目标而言,以下是编写函数的更好方法,diamond类型为int - >字符串:
fun diamond(n) =
if(n=1)
then "*"
else "*" ^ diamond(n-1);
print( diamond(5) );
上述方法更多用于调试目的。