我对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个列表(我认为......'列表列表对我来说似乎是一种奇怪的类型)?如何设置模式/参数有问题吗?谢谢你的帮助。
答案 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))。