Checking Equality Between Two Heterogeneous Values

I use the -XExistentialQuantification GHC extension to create a heterogeneous container for the values โ€‹โ€‹of a particular class type ( Shape ):

 -- Container type data Object = forall a. Shape a => Object a -- 'Shape' class. Methods not important class Eq s => Shape s where doStuff :: s -> s 

Given that all Shape instances are also Eq instances, is there a way to make an Object instance of Eq ?

+7
source share
3 answers

Maybe if you added a Typeable restriction:

 import Data.Typeable data Object = forall a. (Shape a, Typeable a) => Object a instance Eq Object where Object x == Object y = case cast y of Just y' -> x == y' Nothing -> False 

Here cast y will return Just y' if the desired type is y' (output from using == with x ) matches the real type of y and Nothing otherwise.

+17
source

No, because Eq a says that you can compare two values โ€‹โ€‹of type a . An Eq instance on your object would allow you to compare any pairs of values โ€‹โ€‹(of any type that is an instance of Shape ).

If I have instances of Shape Int and Shape Bool , how can I compare Object True with Object 1 for equality?

+2
source

The value of a type that implements Eq can only be compared with another value of the same type โ€” not any other type that implements Eq . Therefore, if you have two values โ€‹โ€‹of different types, you cannot compare them, even if they are both instances of Shape (and therefore Eq ). Therefore, it is also impossible to have an Eq instance for Object , because an Object can contain values โ€‹โ€‹of different types - at least using instances of type instances.

You will need a function like (Shape a, Shape b) => a -> b -> Bool , which can be used to compare any shape with any other shape. If you have such a function, you can use it to create an Eq instance for Object . However, you cannot define such a function in such a way that it matches instances of Eq types.

+1
source