打印字符串并调用递归函数
printing string and calling recursive function
我目前正在学习 sml,但我有一个问题找不到答案。我用谷歌搜索但仍然没有找到任何东西。
这是我的代码:
fun diamond(n) =
if(n=1) then (
print("*")
) else (
print("*")
diamond(n-1)
)
diamond(5);
那是行不通的。我希望代码显示与数字 n 一样多的 * 并且我想通过递归来做到这一点,但我不知道该怎么做。
当我尝试 运行 该代码时出现错误。这是错误:
Standard ML of New Jersey v110.78 [built: Thu Aug 20 19:23:18 2015]
[opening a4_p2.sml] a4_p2.sml:8.5-9.17 Error: operator is not a
function [tycon mismatch] operator: unit in expression:
(print "*") diamond /usr/local/bin/sml: Fatal error -- Uncaught exception Error with 0 raised at
../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
谢谢
您可以使用“;”在 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
?那么另一个打印语句呢?一个语句必须 return 一个单一的结果(即使它是一个复合的)这样就没有意义了。 int -> unit * unit
呢?没问题,除了从语法上讲,你未能将元组传达给编译器。
出于这个原因,以下将起作用:
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 的函数。
因此,为了满足强类型函数式编程范式的要求,我们努力构建评估为一种结果类型的机制,因此我们需要与编译器沟通,某些语句将作为说明,并且不会被纳入正在考虑的功能的类型中。
因此,您使用“;”与编译器通信以简单地评估该语句并丢弃其结果,使其不被合并到函数的类型评估中。
就您的实际 objective 而言,以下是编写函数的更好方法,钻石类型为 int -> 字符串:
fun diamond(n) =
if(n=1)
then "*"
else "*" ^ diamond(n-1);
print( diamond(5) );
以上方式更多的是为了调试目的。
我目前正在学习 sml,但我有一个问题找不到答案。我用谷歌搜索但仍然没有找到任何东西。
这是我的代码:
fun diamond(n) =
if(n=1) then (
print("*")
) else (
print("*")
diamond(n-1)
)
diamond(5);
那是行不通的。我希望代码显示与数字 n 一样多的 * 并且我想通过递归来做到这一点,但我不知道该怎么做。
当我尝试 运行 该代码时出现错误。这是错误:
Standard ML of New Jersey v110.78 [built: Thu Aug 20 19:23:18 2015] [opening a4_p2.sml] a4_p2.sml:8.5-9.17 Error: operator is not a function [tycon mismatch] operator: unit in expression: (print "*") diamond /usr/local/bin/sml: Fatal error -- Uncaught exception Error with 0 raised at ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
谢谢
您可以使用“;”在 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
?那么另一个打印语句呢?一个语句必须 return 一个单一的结果(即使它是一个复合的)这样就没有意义了。 int -> unit * unit
呢?没问题,除了从语法上讲,你未能将元组传达给编译器。
出于这个原因,以下将起作用:
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 的函数。
因此,为了满足强类型函数式编程范式的要求,我们努力构建评估为一种结果类型的机制,因此我们需要与编译器沟通,某些语句将作为说明,并且不会被纳入正在考虑的功能的类型中。 因此,您使用“;”与编译器通信以简单地评估该语句并丢弃其结果,使其不被合并到函数的类型评估中。
就您的实际 objective 而言,以下是编写函数的更好方法,钻石类型为 int -> 字符串:
fun diamond(n) =
if(n=1)
then "*"
else "*" ^ diamond(n-1);
print( diamond(5) );
以上方式更多的是为了调试目的。