open-witness-0.5: src/Data/OpenWitness/Dynamic.hs
-- | This is an approximate re-implementation of "Data.Dynamic" using open witnesses.
module Data.OpenWitness.Dynamic where
import Data.Kind
import Data.OpenWitness.TypeRep
import Data.OpenWitness.Typeable
import Data.Type.Heterogeneous
import Data.Witness
import Prelude
-- * The @Dynamic@ type
type Dynamic = AnyValue TypeRep
-- * Converting to and from @Dynamic@
toDyn ::
forall (a :: Type). Typeable a
=> a
-> Dynamic
toDyn = MkAnyValue typeRep
fromDyn :: Typeable a => Dynamic -> a -> a
fromDyn dyn def =
case fromDynamic dyn of
Just a -> a
_ -> def
fromDynamic ::
forall (a :: Type). Typeable a
=> Dynamic
-> Maybe a
fromDynamic (MkAnyValue uq a) = do
Refl <- testEquality uq (typeRep :: TypeRep a)
return a
-- * Applying functions of dynamic type
dynApply :: Dynamic -> Dynamic -> Maybe Dynamic
dynApply (MkAnyValue (ApplyTypeRep (ApplyTypeRep repFn' rx') ry) f) (MkAnyValue rx x) = do
HRefl <- testHetEquality repFn' (typeRep :: TypeRep (->))
HRefl <- testHetEquality rx' rx
return (MkAnyValue ry (f x))
dynApply _ _ = Nothing
dynApp :: Dynamic -> Dynamic -> Dynamic
dynApp a b =
case (dynApply a b) of
Just d -> d
_ -> error "Type error in dynamic application.\nCan't apply function to argument"
dynTypeRep :: Dynamic -> AnyW (TypeRep :: Type -> Type)
dynTypeRep (MkAnyValue r _) = MkAnyW r