如何递归地创建列表列表 SML/NJ

How to recursively make a list of lists in SML/NJ

I'm brand new to SML/NJ and I'm trying to make a recursive function that makes a listOfLists. Ex: listOf([1,2,3,4]) will output [[1],[2],[3],[4]]. I've found a recursive merge in SML/NJ, and I'm trying to use it as kind've an outline:

- fun merge(xs,nil) = xs
= | merge(nil,ys) = ys
= | merge(x::xs, y::ys) =
= if (x < y) then x::merge(xs, y::ys) else y::merge(x::xs,ys);

- fun listOf(xs) = xs
= | listOf(x::xs) = [x]::listOf(xs);

I'm trying to use pattern match and I'm a little confused on it. I'm pretty sure x is the head and then xs is the tail, but I could be wrong. So what I'm trying to do is use the head of the list, make it a list, and then add it to the rest of the list. But when trying to do this function, I get the error:

stdIn:15.19-15.34 Error: operator and operand don't agree [circularity]
  operator domain: 'Z list * 'Z list list
  operand:         'Z list * 'Z list
  in expression:
    (x :: nil) :: listOf xs

This error is foreign to me because I don't have really any experience with sml/nj. How can I fix my listOf function?

你很接近。问题是在模式匹配中,像 xs 这样的模式(只是一个变量)可以匹配 任何东西 。您以 s 结尾的事实并不意味着该模式只能匹配列表的尾部。以这种方式使用 s 只是 SML 中的程序员约定。

因此,在您的定义中:

fun listOf(xs) = xs
|   listOf(x::xs) = [x]::listOf(xs);

第一行告诉SML return 所有值不变,这显然不是你的本意。 SML 检测到这与您 试图更改值的第二行不一致。

您需要更改第一行,使其不匹配所有内容。将 merge 函数视为模板,您需要一些与基本情况相匹配的东西。自然基例是nil(也可以写成[])。请注意 nilmerge 的定义中扮演的角色。如果您在函数定义的第一行中使用 nil 而不是 xs 作为模式,则您的第二行将完全按照您的要求运行,并且该函数将按预期工作:

fun listOf(nil) = nil
|   listOf(x::xs) = [x]::listOf(xs);