------------------------------------------------------------------------------------------- -- Abstraction of Map like datatypes providing lookup ------------------------------------------------------------------------------------------- module CHR.Data.Lookup ( module CHR.Data.Lookup.Types , module CHR.Data.Lookup.Instances , module CHR.Data.Lookup.Scoped , module CHR.Data.Lookup.Stacked , lookupResolveVar , lookupResolveVal , lookupResolveAndContinueM , inverse ) where ------------------------------------------------------------------------------------------- import Prelude hiding (lookup, map) import qualified Data.List as List import Control.Applicative import CHR.Data.Lookup.Types import CHR.Data.Lookup.Instances import CHR.Data.Lookup.Scoped (Scoped) import CHR.Data.Lookup.Stacked (Stacked) import CHR.Data.VarLookup (VarLookupKey, VarLookupVal) ------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------- --- Lookup and resolution ------------------------------------------------------------------------------------------- -- | Fully resolve lookup lookupResolveVar :: Lookup m (VarLookupKey m) (VarLookupVal m) => (VarLookupVal m -> Maybe (VarLookupKey m)) -> VarLookupKey m -> m -> Maybe (VarLookupVal m) lookupResolveVar isVar k m = lookup k m >>= \v -> lookupResolveVal isVar v m <|> return v -- | Fully resolve lookup lookupResolveVal :: Lookup m (VarLookupKey m) (VarLookupVal m) => (VarLookupVal m -> Maybe (VarLookupKey m)) -> VarLookupVal m -> m -> Maybe (VarLookupVal m) lookupResolveVal isVar v m = isVar v >>= \k -> lookupResolveVar isVar k m <|> return v -- | Monadically lookup a variable, resolve it, continue with either a fail or success monad continuation lookupResolveAndContinueM :: (Monad m, Lookup s (VarLookupKey s) (VarLookupVal s)) => (VarLookupVal s -> Maybe (VarLookupKey s)) -> (m s) -> (m a) -> (VarLookupVal s -> m a) -> VarLookupKey s -> m a lookupResolveAndContinueM tmIsVar gets failFind okFind k = gets >>= \s -> maybe failFind okFind $ lookupResolveVar tmIsVar k s ------------------------------------------------------------------------------------------- --- Utils ------------------------------------------------------------------------------------------- -- | Inverse of a lookup inverse :: (Lookup l1 k1 v1, Lookup l2 k2 v2) => (k1 -> v1 -> (k2,v2)) -> l1 -> l2 inverse mk = fromList . List.map (uncurry mk) . toList