{-# LANGUAGE RankNTypes, GADTs, ConstraintKinds, FlexibleInstances #-} module Data.Dyn where import Type.Reflection data Dyn ctx where Dyn :: ctx a => TypeRep a -> a -> Dyn ctx toDyn :: (Typeable a, ctx a) => a -> Dyn ctx toDyn val = Dyn (typeOf val) val withDyns :: Dyn ctx -> Dyn ctx -> (forall a. ctx a => a -> a -> b) -> (SomeTypeRep -> SomeTypeRep -> b) -> b withDyns (Dyn ty1 v1) (Dyn ty2 v2) f def = case eqTypeRep ty1 ty2 of Nothing -> def (SomeTypeRep ty1) (SomeTypeRep ty2) Just HRefl -> f v1 v2 instance Eq (Dyn Ord) where d1 == d2 = withDyns d1 d2 (==) (\_ _ -> False) instance Ord (Dyn Ord) where compare d1 d2 = withDyns d1 d2 compare compare