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) -- | fancy name for smuggle inj :: Typeable t => t -> a inj = smuggle -- | fancy name for discover 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 -- | All functions of type (a -> a) are `id`. -- This helper lets you create arbitrary `id` functions of -- type (a -> a) which smuggle through a supplied value mkId :: Typeable t => t -> (a -> a) mkId t = const (smuggle t)