{-# LANGUAGE MonoLocalBinds #-} import Type.Reflection import Data.Type.Equality data Eq3 = Equal | NotEqual | NotComparable deriving (Show, Eq, Enum, Bounded) dynamicEq' :: (Eq a) => Maybe (a :~: b) -> a -> b -> Eq3 dynamicEq' Nothing _ _ = NotComparable dynamicEq' (Just Refl) a b = if a == b then Equal else NotEqual dynamicEq :: (Eq a, Typeable a, Typeable b) => a -> b -> Eq3 dynamicEq a b = dynamicEq' (testEquality (typeOf a) (typeOf b)) a b scalar :: [Char] scalar = "Hello" maybe1 :: Maybe [Char] maybe1 = Just "Hello" maybe2 :: Maybe (Maybe [Char]) maybe2 = Just (Just "Hello") main = do print $ dynamicEq scalar "Hello" print $ dynamicEq maybe1 (Just "Hello") print $ dynamicEq maybe2 (Just (Just "Hello")) putStrLn "" print $ dynamicEq scalar "Jello" print $ dynamicEq maybe1 (Just "Mellow") print $ dynamicEq maybe2 (Just (Just "Fellow")) putStrLn "" print $ dynamicEq scalar maybe1 print $ dynamicEq maybe1 maybe2 print $ dynamicEq scalar maybe2