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

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

那么编译器将分别为 thenelse 分支获得不同的类型。 then 分支的类型为 int -> intelse 分支的类型为 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) );

以上方式更多的是为了调试目的。