Skip to content

Commit fedeee2

Browse files
committed
Merge pull request purescript#1160 from puffnfresh/perf/dictionary-lookup
Improve performance of type-class dict lookup
2 parents 57f0976 + eb1018c commit fedeee2

File tree

4 files changed

+14
-9
lines changed

4 files changed

+14
-9
lines changed

src/Language/PureScript/CodeGen/Externs.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ moduleToPs (Module _ moduleName ds (Just exts)) env = intercalate "\n" . execWri
107107

108108
exportToPs (TypeInstanceRef ident) = do
109109
let TypeClassDictionaryInScope { tcdClassName = className, tcdInstanceTypes = tys, tcdDependencies = deps} =
110-
fromMaybe (error $ "Type class instance has no dictionary in exportToPs") . find (\tcd -> tcdName tcd == Qualified (Just moduleName) ident && tcdType tcd == TCDRegular) $ M.elems $ typeClassDictionaries env
110+
fromMaybe (error $ "Type class instance has no dictionary in exportToPs") . find (\tcd -> tcdName tcd == Qualified (Just moduleName) ident && tcdType tcd == TCDRegular) . maybe [] M.elems . M.lookup (Just moduleName) $ typeClassDictionaries env
111111
let constraintsText = case fromMaybe [] deps of
112112
[] -> ""
113113
cs -> "(" ++ intercalate ", " (map (\(pn, tys') -> show pn ++ " " ++ unwords (map prettyPrintTypeAtom tys')) cs) ++ ") => "

src/Language/PureScript/Environment.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ data Environment = Environment {
4949
-- |
5050
-- Available type class dictionaries
5151
--
52-
, typeClassDictionaries :: M.Map (Qualified Ident, Maybe ModuleName) TypeClassDictionaryInScope
52+
, typeClassDictionaries :: M.Map (Maybe ModuleName) (M.Map (Qualified Ident) TypeClassDictionaryInScope)
5353
-- |
5454
-- Type classes
5555
--

src/Language/PureScript/TypeChecker.hs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ addTypeClass moduleName pn args implies ds =
9090

9191
addTypeClassDictionaries :: [TypeClassDictionaryInScope] -> Check ()
9292
addTypeClassDictionaries entries =
93-
let mentries = M.fromList [ ((canonicalizeDictionary entry, mn), entry) | entry@TypeClassDictionaryInScope{ tcdName = Qualified mn _ } <- entries ]
94-
in modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = (typeClassDictionaries . checkEnv $ st) `M.union` mentries } }
93+
let mentries = M.fromListWith (M.union) [ (mn, M.singleton (canonicalizeDictionary entry) entry) | entry@TypeClassDictionaryInScope{ tcdName = Qualified mn _ } <- entries ]
94+
in modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = M.unionWith (M.union) (typeClassDictionaries . checkEnv $ st) mentries } }
9595

9696
checkDuplicateTypeArguments :: [String] -> Check ()
9797
checkDuplicateTypeArguments args = for_ firstDup $ \dup ->
@@ -223,8 +223,7 @@ typeCheckAll mainModuleName moduleName exps = go
223223
guardWith (errorMessage (OrphanFixityDeclaration name)) $ M.member (moduleName, Op name) $ names env
224224
return $ d : ds
225225
go (d@(ImportDeclaration importedModule _ _) : rest) = do
226-
tcds <- getTypeClassDictionaries
227-
let instances = filter (\tcd -> let Qualified (Just mn) _ = tcdName tcd in importedModule == mn) tcds
226+
instances <- lookupTypeClassDictionaries $ Just importedModule
228227
addTypeClassDictionaries [ tcd { tcdName = Qualified (Just moduleName) ident, tcdType = TCDAlias (canonicalizeDictionary tcd) }
229228
| tcd <- instances
230229
, tcdExported tcd

src/Language/PureScript/TypeChecker/Monad.hs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ withScopedTypeVars mn ks = bindTypes (M.fromList (map (\(name, k) -> (Qualified
6969
withTypeClassDictionaries :: (MonadState CheckState m) => [TypeClassDictionaryInScope] -> m a -> m a
7070
withTypeClassDictionaries entries action = do
7171
orig <- get
72-
let mentries = M.fromList [ ((canonicalizeDictionary entry, mn), entry) | entry@TypeClassDictionaryInScope{ tcdName = Qualified mn _ } <- entries ]
73-
modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = (typeClassDictionaries . checkEnv $ st) `M.union` mentries } }
72+
let mentries = M.fromListWith (M.union) [ (mn, M.singleton (canonicalizeDictionary entry) entry) | entry@TypeClassDictionaryInScope{ tcdName = Qualified mn _ } <- entries ]
73+
modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = M.unionWith (M.union) (typeClassDictionaries . checkEnv $ st) mentries } }
7474
a <- action
7575
modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = typeClassDictionaries . checkEnv $ orig } }
7676
return a
@@ -79,7 +79,13 @@ withTypeClassDictionaries entries action = do
7979
-- Get the currently available list of type class dictionaries
8080
--
8181
getTypeClassDictionaries :: (Functor m, MonadState CheckState m) => m [TypeClassDictionaryInScope]
82-
getTypeClassDictionaries = M.elems . typeClassDictionaries . checkEnv <$> get
82+
getTypeClassDictionaries = (>>= M.elems) . M.elems . typeClassDictionaries . checkEnv <$> get
83+
84+
-- |
85+
-- Lookup type class dictionaries in a module.
86+
--
87+
lookupTypeClassDictionaries :: (Functor m, MonadState CheckState m) => Maybe ModuleName -> m [TypeClassDictionaryInScope]
88+
lookupTypeClassDictionaries mn = maybe [] M.elems . M.lookup mn . typeClassDictionaries . checkEnv <$> get
8389

8490
-- |
8591
-- Temporarily bind a collection of names to local variables

0 commit comments

Comments
 (0)