{-# LANGUAGE TypeFamilies #-} module Data.Predicate.Env ( Env , empty , lookup , insert ) where import Prelude hiding (lookup) import Control.Monad.State.Strict import Data.ByteString (ByteString) import Data.Dynamic import qualified Data.Map.Strict as M -- | An environment for predicates, consisting of -- mappings form 'ByteString's to 'Dynamic' values. newtype Env = Env { _unenv :: M.Map ByteString Dynamic } -- | An empty environment. empty :: Env empty = Env M.empty -- | Try to get the associated value for the given key. -- Only successful iff, (i) 'Env' contains a binding for 'k' -- and (ii) the type of value and target match. lookup :: (MonadState m, StateType m ~ Env, Typeable a) => ByteString -> m (Maybe a) lookup k = gets $ maybe Nothing fromDynamic . M.lookup k . _unenv -- | Add a binding from key to value to 'Env', overriding -- previous bindings if existing. insert :: (MonadState m, StateType m ~ Env, Typeable a) => ByteString -> a -> m () insert k v = modify $ Env . M.insert k (toDyn v) . _unenv