在标准ML反向功能中输入错误

时间:2016-11-02 09:50:47

标签: sml

我对sml非常新。我无法看到我试图编写的这个简单的反向函数有什么问题。

fun reverse [] = [] | 
    reverse (v1::rest) = (reverse(tl(rest)) @ v1)

这是我尝试反向运行时的输出([1,2,3]);

poly: : error: Type error in function application.
Function: reverse : 'a list list -> 'a list
Argument: ([1, 2, 3]) : int list
Reason:
  Can't unify int (*In Basis*) with 'a list (*In Basis*)
     (Different type constructors)
Found near reverse ([1, 2, 3])
Static Errors

我可以看到它是一个类型错误。似乎反向正在寻找2个列表(我认为......'列表列表对我来说似乎是一种奇怪的类型)?如何设置模式/参数有问题吗?谢谢你的帮助。

1 个答案:

答案 0 :(得分:2)

让我们先解决错误的类型问题。

'a list list表示列表列表,如下所示:

[[1,2], [3,4], [5,6]] : int list list

这是整数列表的列表。

reverse功能的总体类型为

val reverse = fn : 'a list list -> 'a list

这是因为@运算符具有以下类型签名(您可以找到文档here)。

val @ : 'a list * 'a list -> 'a list

因此,类型推断机制推断v1'a list,但这意味着输入列表包含'a list类型的元素,因此应该是'a list list类型的元素

但你真正的意思是将元素v1追加到反尾的末尾,这可以通过将v1放入一个元素的列表中轻松实现:

some_list @ [v1]

接下来,您不需要tl(rest),因为rest已经是输入列表的尾部。作为旁注:写tl rest更加惯用,括号在这里是不必要的。

考虑到上述情况,我们得到以下实施:

fun rev [] = []
  | rev (h::tl) = rev tl @ [h]

我应该警告你,这个函数非常低效,因为它的时间复杂度是二次的(O(n ^ 2))。