The type `==` in Haskell must be `Eq ab => a & # 8594; b & # 8594; Bool`
We can define what in terms of Eq
and from . We can compare the types of things to see if they are of the same type. Typeable
Data.Typeable
Typeable
(?==) :: (Eq b, Typeable a, Typeable b) => a -> b -> Bool
x ?== y = cast x == Just y
cast
checks that a value of one type is Typeable
actually the same as another. It returns an Just
input if they are the same type or Nothing
if the types are different.
Here are some examples to demonstrate the desired behavior.
> 7 ?== 7
True
> 7 ?== "hello"
False
> 7 ?== 5
False
> (7 :: Int) ?== (7 :: Integer)
False
source to share
(==) :: Eq a b => a -> b -> Bool
will not be as useful as you think.
To define a 2-parameter instance Eq
, you need to know both types (enough to match the instance). Any subscribers of this ==
must either know specifically a
, and b
, or pass the restriction in their interface; then their own callers need to know what a
and b
, or pass the constraint to .... at some point an instance Eq
should be selected rather than exposed through the constraint, and this includes knowing a
and b
at compile time .
At this moment, why should you bother? If you know that a
both are the b
same, then one parameter is enough to compare them Eq
. And if you know they are different, then you know what the answer is False
, and you don't need any instance to tell you that. And if you don't know if they are the same or different, then by definition you don't know enough to select an instance Eq
, so you can't call ==
(or the Eq
-constrained function ) at all!
Thus, it does not help you to get a
and b
unknown types (which implements equality) from individual sources, and then compare them. They would have to merge with an instance Eq a b
, which is actually compile-time proof, whether they are of the same type or not.
The version Typeable
in @Cirdec's answer is very different and much more useful. Here each type supports independentlly Typeable
and one of them supports single parameter Eq
; you can get these two values ββfrom two different sources, where you don't know if they are the same or not, but you know that you can check the type of each one; the source a
must know a
well enough to select an instance Typeable
, and the source b
must know b
well enough to select instances of Typeable
and Eq
, but neither source has to know anything about the other type, and neither code must know both types well enough at once, to determine if they are the same (at compile time). 2-parameterEq
causes both types to be known at once, somewhere that would make it almost useless.
source to share
I think the philosophical answer to your question is that Haskell is similar in nature to mathematics, and when we put on our math hats and define equality for math objects, we usually consider two objects of the same type. For example. look at how equality of equality is defined.
Now, is the set of natural numbers equal to natural? or let go of the wild - the chair is an integer -7? etc. While I am tempted to let my intuition take over and scream "Of course not!", I really can't say that because the question itself is invalid, it's all very undefined. Equality between sets and natural undefined. Equality between chairs and an undefined integer.
Does this mean that you cannot define it? No, go ahead.
But this is not a very popular approach, so choosing a base library is very clear.
In response to your comment, this is correct. As it happens, the sets are so primitive that we can imagine something with them. This is just an example, and I don't know if you agree the same if we choose something else, but let's skate anyway.
In order for the set A to be equal to the set B, we need:
- Every element from A exists in B
- Every element from B exists in A
Keeping this very simple, does the set {1,2,3} match 7? I don't know, because saying that the element exists at 7 is undefined, the question is not valid.
But let's take a look at your approach and do as you say: take 7, put it in a pretty dress to lift it up, and call it set C, and even suppose C equals D to show how right you are. Ultimately you are allowed to demand equality between 7 and another set. But I just want you to notice how much work we had to do to get this done in the first place before we can do it. This is what Haskell would like to do, if possible. With sets in mathematics, this is almost always possible.
So, in both Haskell and math, we (still) can't even ask:
(a :: Set) == (7 :: Natural)
However, in both Haskell and mathematics, we can first bring it up so that we can look at it differently, and then we can ask:
(liftN :: Natural -> Set) (7 :: Natural) == (a :: Set)
Of course, RHS is set C.
And the gist of this answer is that Haskell is just idiomatic in general mathematical terms, defining equality the way he does it.
source to share
Haskell thinks it makes sense to test the equality of two values ββof the same type, i.e. checking for equality of two different typed values ββis pointless and very likely means that you are doing something wrong in your program. This is why type (==) is what it is.
Generally speaking, this is what it means to work in a powerful type system like Haskell's. It is designed for writing better and more meaningful programs.
source to share