操作员和操作员不同意[需要相等的类型]

时间:2015-08-19 14:02:38

标签: sml ml

此函数计算列表中的计数元素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

我该如何解决它?

2 个答案:

答案 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)。