{-# LANGUAGE Safe, ExistentialQuantification #-}

module Control.CUtils.Dyn (Dyn, value, makeDyn, determineType) where

import Data.Typeable

data Dyn = forall t. (Eq t, Show t, Typeable t) => Dyn t deriving Typeable

value :: (Typeable t) => Dyn -> Maybe t
value (Dyn x) = cast x

makeDyn :: (Eq t, Show t, Typeable t) => t -> Dyn
makeDyn = Dyn

determineType :: Dyn -> TypeRep
determineType (Dyn x) = typeOf x

instance Eq Dyn where
	-- A notion of equality at multiple types considers two values to be equal
	-- iff they have the same type, and are equal according to the equality test
	-- at such type.
	Dyn x1 == Dyn x2 = maybe False(==x2) (cast x1)

instance Show Dyn where
	-- Show instance passes through to that of the underlying type.
	showsPrec prec (Dyn x) = showsPrec prec x