{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE GADTs #-}
module Haskus.Utils.Dynamic
(
module Data.Dynamic
, DynEq (..)
, toDynEq
, fromDynEq
, fromDynEqMaybe
)
where
import Data.Dynamic
import Type.Reflection
data DynEq where
DynEq :: forall a. (Eq a, Ord a) => TypeRep a -> a -> DynEq
instance Eq DynEq where
(DynEq tra a) == (DynEq trb b) = case tra `eqTypeRep` trb of
Nothing -> False
Just HRefl -> a == b
instance Ord DynEq where
compare (DynEq tra a) (DynEq trb b) = case tra `eqTypeRep` trb of
Nothing -> compare (SomeTypeRep tra) (SomeTypeRep trb)
Just HRefl -> compare a b
toDynEq :: (Typeable a, Eq a, Ord a) => a -> DynEq
toDynEq a = DynEq typeRep a
fromDynEq :: Typeable a => DynEq -> a -> a
fromDynEq (DynEq tr a) def = case tr `eqTypeRep` typeOf def of
Nothing -> def
Just HRefl -> a
fromDynEqMaybe :: forall a. Typeable a => DynEq -> Maybe a
fromDynEqMaybe (DynEq tr a) = case tr `eqTypeRep` (typeRep :: TypeRep a) of
Nothing -> Nothing
Just HRefl -> Just a