module Control.Distributed.Process.Internal.Dynamic
( Dynamic(..)
, toDyn
, fromDyn
, fromDynamic
, dynTypeRep
, dynApply
, dynApp
, GHC.unsafeCoerce#
) where
import Data.Typeable (Typeable, TypeRep, typeOf, funResultTy)
import qualified GHC.Prim as GHC (Any, unsafeCoerce#)
import Data.Maybe (fromMaybe)
data Dynamic = Dynamic TypeRep GHC.Any
toDyn :: Typeable a => a -> Dynamic
toDyn x = Dynamic (typeOf x) (GHC.unsafeCoerce# x)
fromDyn :: Typeable a => Dynamic -> a -> a
fromDyn (Dynamic rep val) a =
if rep == typeOf a
then GHC.unsafeCoerce# val
else a
fromDynamic :: forall a. Typeable a => Dynamic -> Maybe a
fromDynamic (Dynamic rep val) =
if rep == typeOf (undefined :: a)
then Just (GHC.unsafeCoerce# val)
else Nothing
dynTypeRep :: Dynamic -> TypeRep
dynTypeRep (Dynamic t _) = t
instance Show Dynamic where
show = show . dynTypeRep
dynApply :: Dynamic -> Dynamic -> Maybe Dynamic
dynApply (Dynamic t1 f) (Dynamic t2 x) =
case funResultTy t1 t2 of
Just t3 -> Just (Dynamic t3 (GHC.unsafeCoerce# f x))
Nothing -> Nothing
dynApp :: Dynamic -> Dynamic -> Dynamic
dynApp f x = fromMaybe (error typeError) (dynApply f x)
where
typeError = "Type error in dynamic application.\n"
++ "Can't apply function " ++ show f
++ " to argument " ++ show x