Reputation: 59
This function calculate count element y in list
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
But, when I write func 1.1 [1.1,2.1,3.1,4.1]; I get error:
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
How can I solve it problem ?
Upvotes: 3
Views: 1729
Reputation: 183602
Standard ML has a concept of "equality types", or types that "admit equality"; or, more to the point, it has a concept of types that do not admit equality. You can only use =
on types that do admit equality. (This is why its type is ''a * ''a -> bool
rather than 'a * 'a -> bool
. Type variables that start with ''
can only be instantiated to equality types.)
In SML '97, real
is one type that does not admit equality; so, the following code will not type-check:
val oneIsOne = (1.0 = 1.0) (* FAIL! *)
The reason for this design decision is that IEEE 754 (the standard that defines floating-point numbers) defines "equality" in a rather strange way — NaN
is not equal to itself, and 0.0
is equal to ~0.0
even though 1 / 0.0
is not equal to 1 / ~0.0
. The language designers decided that they didn't want =
to differ from the semantics specified by IEEE 754, but that they also didn't want the semantics of =
to be different for real
than for all other types in the language. Instead, they completely eliminated =
for real
, and made the IEEE 754 definition semantics available as Real.==
[link]. So, you can write:
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 *)
(where countRealElement
has type real -> real list -> int
).
Upvotes: 2
Reputation: 122538
real
is not an equality type in SML 97. That means you cannot use =
to compare two real
s.
Upvotes: 3