在 SML 中制作星形三角形

Making a Star Triangle in SML

我刚开始使用 SMLNJ 编码,但在制作 returns 三角形星形字符串的程序时遇到了一些麻烦。例如 triangle(5) 应该输出:

*****
****
***
**
*

到目前为止我的代码是:

fun triangle(x) =  
    if (x = 0) then "\n"  
    else   
        let  
            fun makeTriangle(n) =  
                if(n = 0) then "\n" else "*"^makeTriangle(n-1);  
        in  
            makeTriangle(x);  
        end  
        triangle(x-1)  

我收到错误 "triangle.sml:9.3 Error: syntax error: inserting EQUALOP"。任何帮助将不胜感激。

您的代码至少有两个问题:

首先,有一个简单的运算符优先级问题:

if(n = 0) then "\n" else "*"^makeTriangle(n-1)

解析为

(if(n = 0) then "\n" else "*") ^ makeTriangle(n-1)

而不是你想要的

if(n = 0) then "\n" else ("*" ^ makeTriangle(n-1))

解决方法是将需要的括号放入。

另一个问题是函数底部的杂散线 triangle(x-1)。它与上面的代码无关。如果您打算将其连接到函数调用 makeTriangle(x) 的结果,那么您需要进行显式连接。 end 之后的函数定义中真的不应该有任何内容,因为 end 终止了 else 部分。

一个小问题:由于您的函数 makeTriangle 插入了 "\n",您的代码(修复后)将在 two "\n"三角形的底部。如果那不是您想要的,也许您可​​以考虑基本情况 (n=0)。

由于 John 已经解释了您的代码的一些问题,并且这看起来像是一个练习,因此您可以通过以下两种不同的方式解决它:

  1. 递归,使用模式匹配:

    fun repeat (0, _) = []
      | repeat (n, x) = x :: repeat (n-1, x)
    
    fun triangle 0 = ""
      | triangle n = implode (repeat (n, #"*")) ^ "\n" ^ triangle (n-1)
    
  2. 有一个名为 List.tabulate 的库函数,其中 repeat 是一个特例:

    fun repeat (n, x) = List.tabulate (n, fn _ => x)
    

    但实际上,triangle 本身非常适合 List.tabulate:

    fun triangle n =
        concat (List.tabulate (n, fn i => implode (repeat (15 - i, #"*")) ^ "\n"))