{-# LANGUAGE CPP #-}
module Control.Super.Plugin.ClassDict
( ClassDict
, Optional
, emptyClsDict
, insertClsDict, insertOptionalClsDict
, lookupClsDict
, isOptionalClass
, lookupClsDictClass, lookupClsDictInstances
, allClsDictKeys, allClsDictEntries ) where
import qualified Data.Set as S
import qualified Data.Map.Strict as M
#if MIN_VERSION_GLASGOW_HASKELL(8,0,0,0)
import Data.Semigroup ( Semigroup(..) )
#endif
import Control.Monad ( join )
import Class ( Class )
import InstEnv ( ClsInst(..) )
import qualified Outputable as O
type Optional = Bool
newtype ClassDict = ClassDict (M.Map String (Optional, Maybe (Class, [ClsInst])))
#if MIN_VERSION_GLASGOW_HASKELL(8,0,0,0)
instance Semigroup ClassDict where
(<>) (ClassDict clsDictA) (ClassDict clsDictB) = ClassDict $ mappend clsDictA clsDictB
#endif
instance Monoid ClassDict where
mempty = emptyClsDict
mappend (ClassDict clsDictA) (ClassDict clsDictB) = ClassDict $ mappend clsDictA clsDictB
instance O.Outputable ClassDict where
ppr (ClassDict clsDict) = O.text "ClassDict " O.<> O.parens (O.ppr clsDict)
emptyClsDict :: ClassDict
emptyClsDict = ClassDict $ M.empty
insertClsDict :: String -> Optional -> Class -> [ClsInst] -> ClassDict -> ClassDict
insertClsDict key opt cls insts (ClassDict dict) = ClassDict $ M.insert key (opt, Just (cls, insts)) dict
insertOptionalClsDict :: String -> ClassDict -> ClassDict
insertOptionalClsDict key (ClassDict dict) = ClassDict $ M.insert key (True, Nothing) dict
isOptionalClass :: String -> ClassDict -> Bool
isOptionalClass key (ClassDict dict) = case M.lookup key dict of
Nothing -> False
Just (opt, _) -> opt
lookupClsDict :: String -> ClassDict -> Maybe (Class, [ClsInst])
lookupClsDict key (ClassDict dict) = join $ fmap snd $ M.lookup key dict
lookupClsDictClass :: String -> ClassDict -> Maybe Class
lookupClsDictClass key dict = fmap fst $ lookupClsDict key dict
lookupClsDictInstances :: String -> ClassDict -> Maybe [ClsInst]
lookupClsDictInstances key dict = fmap snd $ lookupClsDict key dict
allClsDictKeys :: ClassDict -> S.Set String
allClsDictKeys (ClassDict dict) = M.keysSet dict
allClsDictEntries :: ClassDict -> [(Optional, Maybe (Class, [ClsInst]))]
allClsDictEntries (ClassDict dict) = M.elems dict