打印字符串和调用递归函数

时间:2015-10-10 16:33:47

标签: recursion sml smlnj

我目前正在学习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

谢谢

1 个答案:

答案 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 "*";

然后编译器将分别为thenelse分支输入不同的类型。 对于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) );

上述方法更多用于调试目的。