module Rasa.Internal.Extensions
( Ext(..)
, ExtMap
, HasExts(..)
, HasExtMonad(..)
, ext
) where
import Control.Lens
import Data.Default
import Data.Map
import Data.Dynamic
import Data.Maybe
import Unsafe.Coerce
data Ext = forall a. Show a => Ext a
instance Show Ext where
show (Ext a) = show a
type ExtMap = Map TypeRep Ext
class HasExts s where
exts :: Lens' s (Map TypeRep Ext)
ext
:: forall a e.
(Show a, Typeable a, Default a, HasExts e)
=> Lens' e a
ext = lens getter setter
where
getter s =
fromMaybe def $ s ^.exts . at (typeRep (Proxy :: Proxy a)) .
mapping coerce
setter s new =
set
(exts . at (typeRep (Proxy :: Proxy a)) . mapping coerce)
(Just new)
s
coerce = iso (\(Ext x) -> unsafeCoerce x) Ext
class (Typeable m, Monad m) => HasExtMonad m where
getExt :: (Typeable ext, Show ext, Default ext) => m ext
setExt :: (Typeable ext, Show ext, Default ext) => ext -> m ()
overExt :: (Typeable ext, Show ext, Default ext) => (ext -> ext) -> m ()
overExt f = getExt >>= setExt . f