【问题标题】:operator and operand don't agree [equality type required]运算符和操作数不一致 [需要相等类型]
【发布时间】:2015-08-20 16:13:06
【问题描述】:

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

我该如何解决这个问题?

【问题讨论】:

    标签: sml ml


    【解决方案1】:

    real 不是 SML 97 中的相等类型。这意味着您不能使用 = 来比较两个 reals。

    【讨论】:

    • 如何检查通用列表是否在 ml 中有重复元素?
    • @alex:你不能。如果您看不到两个元素是否相等,则根据定义,您无法知道是否有重复。
    • 所有元素都是相同的类型。例如 [1.0,1.0,2.0] 返回 true
    【解决方案2】:

    标准 ML 有一个“相等类型”的概念,或“承认相等”的类型;或者,更重要的是,它有一个承认相等的类型的概念。您只能在确实承认相等的类型上使用=。 (这就是为什么它的类型是''a * ''a -> bool 而不是'a * 'a -> bool。以'' 开头的类型变量只能实例化为相等类型。)

    在 SML '97 中,real 是一种承认平等的类型;因此,以下代码不会进行类型检查:

    val oneIsOne = (1.0 = 1.0)    (* FAIL! *)
    

    做出这个设计决定的原因是 IEEE 754(定义浮点数的标准)以一种相当奇怪的方式定义了“平等”——NaN 不等于它自己,而0.0 等于 @ 987654330@ 即使1 / 0.0 不等于1 / ~0.0。语言设计者决定他们不希望 = 与 IEEE 754 指定的语义不同,但他们也不希望 = 的语义对于 real 与所有其他类型的语义不同语言。相反,他们完全消除了real=,并使IEEE 754 定义语义可用作Real.== [link]。所以,你可以写:

    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 的类型为real -> real list -> int)。

    【讨论】:

    • 如何检查类型是否真实?我需要所有类型的工作
    • real 表示,浮点数;示例包括 1.11.0~1.01e8。您不能使这项工作适用于所有类型;你能做的最好的就是创建一个函数fun countMatchingElements f y xs = List.length (List.filter (fn x => f (x,y)) xs),这样(例如)countMatchingElements op= 1 [1,2,3,4]1countMatchingElements Real.== 1.1 [1.1,2.1,3.1,4.1] 也是。
    • 如何在运行时识别类型(int 或 real)?
    • 使用代数数据类型作为包装器;例如,datatype intOrReal = Int of int | Real of real。 (标准 ML 中没有反射;所有类型都是静态/编译时类型。)
    猜你喜欢
    • 2017-06-28
    • 2020-05-19
    • 1970-01-01
    • 2021-05-17
    • 2018-04-28
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    相关资源
    最近更新 更多