Sml 标准ML递归函数错误

Sml 标准ML递归函数错误,sml,Sml,所以我刚开始学习ML编程,我在一本书中找到了这个练习。练习要求构建一个递归函数,该函数接受一个整数和一个列表。如果L=[a1,a2,a3],那么期望的结果是[ai+1,ai+2,…,an,a1,a2,…,ai]。所以我写了一个函数,几个小时后,我把错误缩小到了我无法理解的程度。以下是我的功能: fun cycle L i = if i = 0 then L else (cycle tl(L) (i-1)) @ [hd(L)]; 我会上传一张带有错误信息的图片,以便有人能向我解

所以我刚开始学习ML编程,我在一本书中找到了这个练习。练习要求构建一个递归函数,该函数接受一个整数和一个列表。如果L=[a1,a2,a3],那么期望的结果是[ai+1,ai+2,…,an,a1,a2,…,ai]。所以我写了一个函数,几个小时后,我把错误缩小到了我无法理解的程度。以下是我的功能:

fun cycle L i = 
    if i = 0 then L
    else (cycle tl(L) (i-1)) @ [hd(L)];
我会上传一张带有错误信息的图片,以便有人能向我解释口译员想对我说什么


“a”旁边的数字只显示这些元素在列表中的顺序。因此对于L=[1,2,3,4,5]和i=2,期望的结果是列表L=[3,4,5,1,2]。我不认为列表的类型在这个问题上是必要的。希望这个进一步的解释有帮助

这是递归调用的语法问题
循环tl(L)(i-1)

在SML中,函数应用程序的语法是并置的,而不是括号。在您的例子中,
tl(L)
确实使用参数
L
调用函数
tl
,但这相当于
tl
。括号是多余的,因此被忽略

现在,如果在原始调用中替换最小版本,您将得到以下结果:
循环tll(i-1)
。它用三个参数而不是两个参数调用
cycle


正确的写作方法应该是:
cycle(tll)(i-1)

Ionuț已经对语法问题给出了充分的答案;以下是一些进一步的建议:

  • 使用模式匹配,而不是
    hd
    tl

  • 考虑基本情况;你能想到的最简单的子问题是什么?例如,循环空列表将始终给出空列表,而不管n,循环l0次将始终返回L。将两个基本情况都作为模式会有所帮助

  • 考虑递归情况;循环顶部元素(假设它存在)并将i减少1,直到最终i为0或L为空。因为第二个基本情况捕获空列表,所以我们可以自由地假设L在这里不是空的,在这种情况下,它将匹配模式
    x::xs

    fun cycle 0 xs = xs
      | cycle i [] = []
      | cycle i (x::xs) = cycle (i-1) (xs @ [x])
    

  • 取决于
    0这本书的翻译是否丢失了某些内容,因为在您对任务的描述中,没有说明i或n是什么,也没有说明它们与a1、a2和a3的关系。不知何故,a1是在A之后出现的。我可以是任何类型的列表,还是int列表?结果列表中有多少个元素;n+?。也许如果你写的是作业的实际文本,或者书的名称和作业的编号,可能会更有意义。“a”旁边的数字只是表示这些元素在列表中的顺序。因此对于L=[1,2,3,4,5]和i=2,期望的结果是列表L=[3,4,5,1,2]。我不认为列表的类型在这个问题上是必要的。希望这个进一步的解释有帮助
    
    fun cycle i ys =
        let fun fun cycle' 0 xs = xs
                  | cycle' i [] = []
                  | cycle' i (x::xs) = cycle' (i-1) (xs @ [x])
        in
          if 0 <= i andalso i <= length xs
          then cycle' i ys
          else raise Domain
        end
    
    val cycle_test_1 = (cycle 5 [1,2,3,4] = [2,3,4,1])