此函数计算列表中的计数元素y
fun func y xs=List.length(List.filter(fn x => x=y) xs);
val countElement = fn : ''a -> ''a ?.list -> int
func 1 [1,2,3,4];
val it = 1 : int
但是,当我写func 1.1 [1.1,2.1,3.1,4.1];我收到错误:
stdIn:64.1-64.35 Error: operator and operand don't agree [equality type required]
operator domain: ''Z
operand: real
in expression:
countElement 1.1
我该如何解决它?
答案 0 :(得分:2)
real
在SML 97中不是相等类型。这意味着您无法使用=
来比较两个real
。
答案 1 :(得分:1)
标准ML有一个"相等类型"的概念,或者#34;允许相等的类型&#34 ;;或者更重要的是,它有一个不承认相等的类型概念。您只能对执行承认相等的类型使用=
。 (这就是它的类型为''a * ''a -> bool
而不是'a * 'a -> bool
的原因。以''
开头的类型变量只能实例化为相等类型。)
在SML' 97中,real
是不允许相等的一种类型;所以,以下代码不会进行类型检查:
val oneIsOne = (1.0 = 1.0) (* FAIL! *)
这个设计决策的原因是IEEE 754(定义浮点数的标准)定义了"相等"以一种相当奇怪的方式 - NaN
不等于它自己,0.0
等于~0.0
,即使1 / 0.0
不等于1 / ~0.0
。语言设计者认为他们并不希望=
与IEEE 754指定的语义不同,但他们也不希望=
的语义与real
的语义不同{ {1}}比语言中的所有其他类型。相反,他们完全取消=
的{{1}},并将IEEE 754定义语义作为real
[link]提供。所以,你可以写:
Real.==
(其中fun countRealElement y xs = List.length (List.filter (fn x => Real.== (x,y)) xs)
val it = countRealElement 1.1 [1.1,2.1,3.1,4.1] (* 1 *)
的类型为countRealElement
)。