module Acme.Smuggler
( inj, prj, smuggle, discover, mkId
) where
import Data.Typeable (Typeable)
import Data.Dynamic (toDyn, fromDynamic)
import System.IO.Unsafe (unsafePerformIO)
import Control.Exception (try, throw, evaluate)
inj :: Typeable t => t -> a
inj = smuggle
prj :: Typeable t => a -> Maybe t
prj = discover
smuggle :: Typeable t => t -> a
smuggle = throw . toDyn
discover :: Typeable t => a -> Maybe t
discover = either (fromDynamic) (const Nothing)
. unsafePerformIO
. try
. evaluate
mkId :: Typeable t => t -> (a -> a)
mkId t = const (smuggle t)