/Retrie/PatternMap/Bag.hs
https://github.com/facebookincubator/retrie · Haskell · 164 lines · 104 code · 39 blank · 21 comment · 0 complexity · 563f640092df69b12bbfce9f5c5037ba MD5 · raw file
- -- Copyright (c) Facebook, Inc. and its affiliates.
- --
- -- This source code is licensed under the MIT license found in the
- -- LICENSE file in the root directory of this source tree.
- --
- {-# LANGUAGE InstanceSigs #-}
- {-# LANGUAGE TupleSections #-}
- {-# LANGUAGE TypeFamilies #-}
- {-# LANGUAGE DeriveFunctor #-}
- module Retrie.PatternMap.Bag where
- import qualified Data.Map as M
- import qualified Data.IntMap as I
- import Retrie.AlphaEnv
- import qualified Retrie.GHC as GHC
- import Retrie.PatternMap.Class
- import Retrie.Quantifiers
- import Retrie.Substitution
- data BoolMap a
- = EmptyBoolMap
- | BoolMap
- { bmTrue :: MaybeMap a
- , bmFalse :: MaybeMap a
- }
- deriving (Functor)
- instance PatternMap BoolMap where
- type Key BoolMap = Bool
- mEmpty :: BoolMap a
- mEmpty = EmptyBoolMap
- mUnion :: BoolMap a -> BoolMap a -> BoolMap a
- mUnion EmptyBoolMap m = m
- mUnion m EmptyBoolMap = m
- mUnion m1 m2 = BoolMap
- { bmTrue = unionOn bmTrue m1 m2
- , bmFalse = unionOn bmFalse m1 m2
- }
- mAlter
- :: AlphaEnv -> Quantifiers -> Key BoolMap -> A a -> BoolMap a -> BoolMap a
- mAlter env qs b f EmptyBoolMap = mAlter env qs b f (BoolMap mEmpty mEmpty)
- mAlter env qs b f m@BoolMap{}
- | b = m { bmTrue = mAlter env qs () f (bmTrue m) }
- | otherwise = m { bmFalse = mAlter env qs () f (bmFalse m) }
- mMatch
- :: MatchEnv
- -> Key BoolMap
- -> (Substitution, BoolMap a)
- -> [(Substitution, a)]
- mMatch _ _ (_, EmptyBoolMap) = []
- mMatch env b hs@(_, BoolMap{})
- | b = mapFor bmTrue hs >>= mMatch env ()
- | otherwise = mapFor bmFalse hs >>= mMatch env ()
- ------------------------------------------------------------------------
- newtype IntMap a = IntMap { unIntMap :: I.IntMap [a] }
- deriving (Functor)
- instance PatternMap IntMap where
- type Key IntMap = I.Key
- mEmpty :: IntMap a
- mEmpty = IntMap I.empty
- mUnion :: IntMap a -> IntMap a -> IntMap a
- mUnion (IntMap m1) (IntMap m2) = IntMap $ I.unionWith (++) m1 m2
- mAlter :: AlphaEnv -> Quantifiers -> Key IntMap -> A a -> IntMap a -> IntMap a
- mAlter _ _ i f (IntMap m) = IntMap $ I.alter (toAList f) i m
- mMatch
- :: MatchEnv
- -> Key IntMap
- -> (Substitution, IntMap a)
- -> [(Substitution, a)]
- mMatch _ i = maybeListMap (I.lookup i . unIntMap)
- ------------------------------------------------------------------------
- newtype Map k a = Map { unMap :: M.Map k [a] }
- deriving (Functor)
- mapAssocs :: Map k v -> [(k,v)]
- mapAssocs (Map m) = [ (k,v) | (k,vs) <- M.assocs m, v <- vs ]
- instance Ord k => PatternMap (Map k) where
- type Key (Map k) = k
- mEmpty :: Map k a
- mEmpty = Map M.empty
- mUnion :: Map k a -> Map k a -> Map k a
- mUnion (Map m1) (Map m2) = Map $ M.unionWith (++) m1 m2
- mAlter :: AlphaEnv -> Quantifiers -> Key (Map k) -> A a -> Map k a -> Map k a
- mAlter _ _ k f (Map m) = Map $ M.alter (toAList f) k m
- mMatch
- :: MatchEnv
- -> Key (Map k)
- -> (Substitution, Map k a)
- -> [(Substitution, a)]
- mMatch _ k = maybeListMap (M.lookup k . unMap)
- ------------------------------------------------------------------------
- -- Note [OccEnv]
- --
- -- We avoid using OccEnv because the Uniquable instance for OccName
- -- takes the NameSpace of the OccName into account, which we rarely actually
- -- want. (Doing so requires creating new RdrNames with the proper namespace,
- -- which is a bunch of fiddling for no obvious gain for our uses.) Instead
- -- we just use a map based on the FastString name.
- newtype FSEnv a =
- FSEnv { _unFSEnv :: UniqFM a } -- this is the UniqFM below, NOT GHC's UniqFM
- deriving (Functor)
- instance PatternMap FSEnv where
- type Key FSEnv = GHC.FastString
- mEmpty :: FSEnv a
- mEmpty = FSEnv mEmpty
- mUnion :: FSEnv a -> FSEnv a -> FSEnv a
- mUnion (FSEnv m1) (FSEnv m2) = FSEnv (mUnion m1 m2)
- mAlter :: AlphaEnv -> Quantifiers -> Key FSEnv -> A a -> FSEnv a -> FSEnv a
- mAlter env qs fs f (FSEnv m) = FSEnv (mAlter env qs (GHC.getUnique fs) f m)
- mMatch :: MatchEnv -> Key FSEnv -> (Substitution, FSEnv a) -> [(Substitution, a)]
- mMatch env fs (hs, FSEnv m) = mMatch env (GHC.getUnique fs) (hs, m)
- ------------------------------------------------------------------------
- newtype UniqFM a = UniqFM { unUniqFM :: GHC.UniqFM [a] }
- deriving (Functor)
- instance PatternMap UniqFM where
- type Key UniqFM = GHC.Unique
- mEmpty :: UniqFM a
- mEmpty = UniqFM GHC.emptyUFM
- mUnion :: UniqFM a -> UniqFM a -> UniqFM a
- mUnion (UniqFM m1) (UniqFM m2) = UniqFM $ GHC.plusUFM_C (++) m1 m2
- mAlter :: AlphaEnv -> Quantifiers -> Key UniqFM -> A a -> UniqFM a -> UniqFM a
- mAlter _ _ k f (UniqFM m) = UniqFM $ GHC.alterUFM (toAList f) m k
- mMatch
- :: MatchEnv
- -> Key UniqFM
- -> (Substitution, UniqFM a)
- -> [(Substitution, a)]
- mMatch _ k = maybeListMap (flip GHC.lookupUFM_Directly k . unUniqFM)
- ------------------------------------------------------------------------