SML列表等式异常

SML列表等式异常,sml,smlnj,Sml,Smlnj,我有一段代码: fun foldr2(f, x::xs) = if xs = [] then x else f(x, foldr2(f, xs)) 带类型签名 (''a * ''a -> ''a) * ''a list -> ''a 看起来很简单,它采用了一个在等式类型上工作的函数和一个等式类型列表作为参数,这是因为xs=[]比较。然而,由于某些原因,当在SML/NJ reals中不是相等类型时,它可以在输入上工作,例如(op+,[2.3,

我有一段代码:

fun foldr2(f, x::xs) =
    if xs = [] then
      x
    else
      f(x, foldr2(f, xs))
带类型签名

(''a * ''a -> ''a) * ''a list -> ''a

看起来很简单,它采用了一个在等式类型上工作的函数和一个等式类型列表作为参数,这是因为
xs=[]
比较。然而,由于某些原因,当在SML/NJ reals中不是相等类型时,它可以在输入上工作,例如
(op+,[2.3,2.7,4.0])
。有谁能帮我解释一下为什么会发生这种神奇的事情吗?

我相信这与
+
对于real来说过载的神奇方式有关。对我来说,这几乎是一个编译器错误,尽管我必须查看SML97的定义,以确定正确的行为是什么。
+
上的重载在SML、IMHO中是一个令人讨厌的黑暗角落

例如,如果定义类型为
real*real->real
的函数,并将其作为参数传递给
foldr2
,则会得到预期的类型错误:

fun f (x : real * real) = 134.5
foldr2 (f, [1.4, 2.25, 7.0])
  stdIn:8.1-8.29 Error: operator and operand don't agree [equality type required]

如果你只是在
op++
中添加一个类型注释,你甚至可以导致类型错误,这基本上让我得出结论,就是
++
的重载导致了这种神秘的效果。

+1,我也想知道为什么会这样。这就像SML/NJ将条件块转换为“null[2.3,2.7,4.0]”或类似内容一样。