我有以下递归函数:
fun tester (f:'a -> 'b, tl:(string * 'a * 'b) list) =
case tl of
[] => []
| (t, c, e)::rest =>
let val tr = f (c)
in
if tr <> (e)
then ((t), (e), tr)::(tester (f, rest))
else tester (f, rest)
end;
加载时我得到“错误:操作符和操作数不同意[UBOUND match]”:
lec1test.sml:17.5-19.26 Error: operator and operand don't agree [UBOUND match]
operator domain: ''Z * ''Z
operand: 'b * 'Y
in expression:
tr <> e
uncaught exception Error
raised at: ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
../compiler/TopLevel/interact/evalloop.sml:44.55
../compiler/TopLevel/interact/evalloop.sml:296.17-296.20
我已经发现我认为它与tr的通用绑定有关,但我不明白为什么这是一个问题。我将tr
分配给来自f
的函数值,该值返回'b
。然后我将结果与元组中最后一个值'b
进行比较。有人可以解释为什么这会给我一个错误吗?
答案 0 :(得分:10)
并非所有类型都支持相等运算符=
和<>
,只有所谓的相等类型。例如,int
或string list
或bool * unit
是相等类型,但例如函数类型t -> u
永远不会,因为没有合理的(可判定的)方法来比较函数。
像'a
这样的多态类型的值也不是相等类型,因为类型变量可以通过任何类型实例化。要将多态类型限制为相等类型,您需要编写带有双重刻度的类型变量,例如''a
。
在您的情况下,将第一行更改为
fun tester (f : ''a -> ''b, tl : (string * ''a * ''b) list) =
应该为你解决。