首先,您应该知道每个运算符的作用: :: 将单个元素放入现有列表中,以便: 1::2::3::[] = [1,2,3] @ 将两个列表放在一起,以便: [1,2] @ [3,4] = [1,2,3,4]
您也可以使用 :: 将列表放在一起,但它会变成一个列表列表,例如: [1,2] :: [3,4] = [[1,2],[3,4]]
所以通过写 [x::y] 你是说 x 和 y 应该成为列表中的列表。
并且您不应该使用 if 语句来检查列表的结尾,而是可以使用模式来执行此操作:
fun listofnodes [] = []
| listofnodes ((x,y)::xs) = x :: y :: listofnodes(xs);
第一个模式确保当我们到达列表的末尾时,当您提取最终的元组时,您的 xs 绑定到一个它调用自身的空列表,它会留下一个空列表来放入所有元素,因此 [( 1,2) (3,4) (5,6) (1,5)] 会这样计算:
1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 1 :: 5 :: [] = [1,2,3,4,5,6,1,5]。
你也可以这样:
fun listofnodes [] = []
| listofnodes ((x,y)::xs) = [x,y] @ listofnodes(xs);
这样你就可以从每个元组中创建一个小的 2 元素列表,然后将所有这些小列表合并到一个大列表中。你真的不需要最后的空列表,但它是确保递归在列表末尾停止的唯一方法,你必须在等号的另一边放一些东西。它的评估如下:
[1,2] @ [3,4] @ [5,6] @ [1,5] @ [] = [1,2,3,4,5,6,1,5]。
您也将 x 和 y 转换为整数,但您不必这样做。如果你不这样做,它会得到类型“ ('a * 'a) list -> 'a list ”,这意味着它适用于所有输入类型,包括整数(只要元组不包含冲突类型,如 char 和一个整数)。我猜你知道这一点,但万一你不知道:你所说的对(1,2)被称为元组。