我正在测试列表是否是回文,因此我创建了一个名为reverse
的函数以反转列表,并创建了一个名为palindrome
的函数,该函数使用模式匹配来尝试查看列表是否与反转的列表匹配。但是我收到unbound variable or constructor
错误。
(* This function returns true for all patterns that match itself in reverse as well as for the empty list
Otherwise _ wildcard character we return False *)
fun palindrome (xs): bool =
let val rev = reverse(xs)
in
case xs of
rev => True
| [] => True
| _ => False
end;
输出:
Error: unbound variable or constructor: False
vaje1.sml:125.10-125.14 Error: unbound variable or constructor: True
vaje1.sml:123.9-123.13 Error: unbound variable or constructor: True
true
和false
之外,另一个错误在于如何比较两个列表是否相等。正如molbdnilo所指出的,最简单的方法是one = other
,即(使用内置的List.rev
函数):fun palindrome xs =
xs = List.rev xs
之所以有效,是因为,如果您拥有一个相等于相等性的值,那么这些值的列表会自动与相等性相比较。如果不是这种情况,则可以通过以下方式递归定义此类函数:
fun list_eq ([], []) = true | list_eq (x::xs, y::ys) = (x = y) andalso list_eq (xs, ys) | list_eq (_, _) = false (* lists of mismatching length *) (* one way *) fun palindrome xs = list_eq (xs, List.rev xs)
但是内置的=
已经做到了。您使用
case-of的方式似乎是尝试通过使用模式
xs
比较两个变量rev
和rev
(不是函数)是否相等,以期希望这样的模式指的是变量rev
:在Prolog和Erlang中是这样,但在SML中不是。如果必须使用这样的case-of,则可以执行以下操作(再次使用内置的List.rev
函数):fun palindrome xs = case List.rev xs of xs' => (xs = xs')
尽管这是不必要的,因为xs'
仅被引用一次。