Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing equality between two heterogeneous values

I'm using the -XExistentialQuantification GHC extension to create a heterogeneous container for values of a specific type class (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 instances of Shape are also instances of Eq, is there a way to make Object an instance of Eq as well?

like image 662
Tom Savage Avatar asked Oct 22 '12 16:10

Tom Savage


1 Answers

It's possible if you add a Typeable constraint:

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 of y' (inferred from the use of == with x) matches the actual type of y, and Nothing otherwise.

like image 61
hammar Avatar answered Oct 16 '22 16:10

hammar