@@ -12,6 +12,9 @@
1212--
1313-----------------------------------------------------------------------------
1414
15+{-# LANGUAGE FlexibleContexts #-}
16+{-# LANGUAGE ScopedTypeVariables #-}
17+
1518module Language.PureScript.Sugar.Names (
1619 desugarImports
1720) where
@@ -84,7 +87,7 @@ data ImportEnvironment = ImportEnvironment
8487-- Updates the exports for a module from the global environment. If the module was not previously
8588-- present in the global environment, it is created.
8689--
87−updateExportedModule :: ExportEnvironment -> ModuleName -> (Exports -> Either ErrorStack Exports) -> Either ErrorStack ExportEnvironment
90+updateExportedModule :: (Applicative m, MonadError ErrorStack m) => ExportEnvironment -> ModuleName -> (Exports -> m Exports) -> m ExportEnvironment
8891updateExportedModule env mn update = do
8992 let exports = fromMaybe (error "Module was undefined in updateExportedModule") $ mn `M.lookup` env
9093 exports' <- update exports
@@ -93,7 +96,7 @@ updateExportedModule env mn update = do
9396-- |
9497-- Adds an empty module to an ExportEnvironment.
9598--
96−addEmptyModule :: ExportEnvironment -> ModuleName -> Either ErrorStack ExportEnvironment
99+addEmptyModule :: (Applicative m, MonadError ErrorStack m) => ExportEnvironment -> ModuleName -> m ExportEnvironment
97100addEmptyModule env name =
98101 if name `M.member` env
99102 then throwError $ mkErrorStack ("Module '" ++ show name ++ "' has been defined more than once") Nothing
@@ -102,7 +105,7 @@ addEmptyModule env name =
102105-- |
103106-- Adds a type belonging to a module to the export environment.
104107--
105−addType :: ExportEnvironment -> ModuleName -> ProperName -> [ProperName] -> Either ErrorStack ExportEnvironment
108+addType :: (Applicative m, MonadError ErrorStack m) => ExportEnvironment -> ModuleName -> ProperName -> [ProperName] -> m ExportEnvironment
106109addType env mn name dctors = updateExportedModule env mn $ \m -> do
107110 let exTypes = exportedTypes m
108111 let exDctors = snd `concatMap` exTypes
@@ -117,7 +120,7 @@ addType env mn name dctors = updateExportedModule env mn $ \m -> do
117120-- |
118121-- Adds a class to the export environment.
119122--
120−addTypeClass :: ExportEnvironment -> ModuleName -> ProperName -> Either ErrorStack ExportEnvironment
123+addTypeClass :: (Applicative m, MonadError ErrorStack m) => ExportEnvironment -> ModuleName -> ProperName -> m ExportEnvironment
121124addTypeClass env mn name = updateExportedModule env mn $ \m -> do
122125 let exTypes = exportedTypes m
123126 let exDctors = snd `concatMap` exTypes
@@ -129,7 +132,7 @@ addTypeClass env mn name = updateExportedModule env mn $ \m -> do
129132-- |
130133-- Adds a class to the export environment.
131134--
132−addValue :: ExportEnvironment -> ModuleName -> Ident -> Either ErrorStack ExportEnvironment
135+addValue :: (Applicative m, MonadError ErrorStack m) => ExportEnvironment -> ModuleName -> Ident -> m ExportEnvironment
133136addValue env mn name = updateExportedModule env mn $ \m -> do
134137 values <- addExport "value" (exportedValues m) name
135138 return $ m { exportedValues = values }
@@ -138,7 +141,7 @@ addValue env mn name = updateExportedModule env mn $ \m -> do
138141-- Adds an entry to a list of exports unless it is already present, in which case an error is
139142-- returned.
140143--
141−addExport :: (Eq a, Show a) => String -> [a] -> a -> Either ErrorStack [a]
144+addExport :: (Applicative m, MonadError ErrorStack m, Eq a, Show a) => String -> [a] -> a -> m [a]
142145addExport what exports name =
143146 if name `elem` exports
144147 then throwMultipleDefError what name
@@ -147,7 +150,7 @@ addExport what exports name =
147150-- |
148151-- Replaces all local names with qualified names within a set of modules.
149152--
150−desugarImports :: [Module] -> Either ErrorStack [Module]
153+desugarImports :: forall m. (Applicative m, MonadError ErrorStack m) => [Module] -> m [Module]
151154desugarImports modules = do
152155 unfilteredExports <- findExports modules
153156 exports <- foldM filterModuleExports unfilteredExports modules
@@ -157,13 +160,13 @@ desugarImports modules = do
157160 -- Filters the exports for a module in the global exports environment so that only explicitly
158161 -- exported members remain. If the module does not explicitly export anything, everything is
159162 -- exported.
160− filterModuleExports :: ExportEnvironment -> Module -> Either ErrorStack ExportEnvironment
163+ filterModuleExports :: ExportEnvironment -> Module -> m ExportEnvironment
161164 filterModuleExports env (Module mn _ (Just exps)) = filterExports mn exps env
162165 filterModuleExports env _ = return env
163166
164167 -- Rename and check all the names within a module. We tweak the global exports environment so
165168 -- the module has access to an unfiltered list of its own members.
166− renameInModule' :: ExportEnvironment -> ExportEnvironment -> Module -> Either ErrorStack Module
169+ renameInModule' :: ExportEnvironment -> ExportEnvironment -> Module -> m Module
167170 renameInModule' unfilteredExports exports m@(Module mn _ _) =
168171 rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $ do
169172 let env = M.update (\_ -> M.lookup mn unfilteredExports) mn exports
@@ -202,13 +205,13 @@ elaborateImports (Module mn decls exps) = Module mn decls' exps
202205-- Replaces all local names with qualified names within a module and checks that all existing
203206-- qualified names are valid.
204207--
205−renameInModule :: ImportEnvironment -> ExportEnvironment -> Module -> Either ErrorStack Module
208+renameInModule :: forall m. (Applicative m, MonadError ErrorStack m) => ImportEnvironment -> ExportEnvironment -> Module -> m Module
206209renameInModule imports exports (Module mn decls exps) =
207210 Module mn <$> parU decls go <*> pure exps
208211 where
209212 (go, _, _, _, _) = everywhereWithContextOnValuesM (Nothing, []) updateDecl updateValue updateBinder updateCase defS
210213
211− updateDecl :: (Maybe SourceSpan, [Ident]) -> Declaration -> Either ErrorStack ((Maybe SourceSpan, [Ident]), Declaration)
214+ updateDecl :: (Maybe SourceSpan, [Ident]) -> Declaration -> m ((Maybe SourceSpan, [Ident]), Declaration)
212215 updateDecl (_, bound) d@(PositionedDeclaration pos _ _) = return ((Just pos, bound), d)
213216 updateDecl (pos, bound) (DataDeclaration dtype name args dctors) =
214217 (,) (pos, bound) <$> (DataDeclaration dtype name args <$> mapM (sndM (mapM (updateTypesEverywhere pos))) dctors)
@@ -226,7 +229,7 @@ renameInModule imports exports (Module mn decls exps) =
226229 (,) (pos, name : bound) <$> (ExternDeclaration fit name js <$> updateTypesEverywhere pos ty)
227230 updateDecl s d = return (s, d)
228231
229− updateValue :: (Maybe SourceSpan, [Ident]) -> Expr -> Either ErrorStack ((Maybe SourceSpan, [Ident]), Expr)
232+ updateValue :: (Maybe SourceSpan, [Ident]) -> Expr -> m ((Maybe SourceSpan, [Ident]), Expr)
230233 updateValue (_, bound) v@(PositionedValue pos' _ _) = return ((Just pos', bound), v)
231234 updateValue (pos, bound) (Abs (Left arg) val') = return ((pos, arg : bound), Abs (Left arg) val')
232235 updateValue (pos, bound) (Let ds val') = do
@@ -244,12 +247,12 @@ renameInModule imports exports (Module mn decls exps) =
244247 updateValue s@(pos, _) (TypedValue check val ty) = (,) s <$> (TypedValue check val <$> updateTypesEverywhere pos ty)
245248 updateValue s v = return (s, v)
246249
247− updateBinder :: (Maybe SourceSpan, [Ident]) -> Binder -> Either ErrorStack ((Maybe SourceSpan, [Ident]), Binder)
250+ updateBinder :: (Maybe SourceSpan, [Ident]) -> Binder -> m ((Maybe SourceSpan, [Ident]), Binder)
248251 updateBinder (_, bound) v@(PositionedBinder pos _ _) = return ((Just pos, bound), v)
249252 updateBinder s@(pos, _) (ConstructorBinder name b) = (,) s <$> (ConstructorBinder <$> updateDataConstructorName name pos <*> pure b)
250253 updateBinder s v = return (s, v)
251254
252− updateCase :: (Maybe SourceSpan, [Ident]) -> CaseAlternative -> Either ErrorStack ((Maybe SourceSpan, [Ident]), CaseAlternative)
255+ updateCase :: (Maybe SourceSpan, [Ident]) -> CaseAlternative -> m ((Maybe SourceSpan, [Ident]), CaseAlternative)
253256 updateCase (pos, bound) c@(CaseAlternative bs _) = return ((pos, concatMap binderNames bs ++ bound), c)
254257
255258 letBoundVariable :: Declaration -> Maybe Ident
@@ -257,10 +260,10 @@ renameInModule imports exports (Module mn decls exps) =
257260 letBoundVariable (PositionedDeclaration _ _ d) = letBoundVariable d
258261 letBoundVariable _ = Nothing
259262
260− updateTypesEverywhere :: Maybe SourceSpan -> Type -> Either ErrorStack Type
263+ updateTypesEverywhere :: Maybe SourceSpan -> Type -> m Type
261264 updateTypesEverywhere pos0 = everywhereOnTypesM (updateType pos0)
262265 where
263− updateType :: Maybe SourceSpan -> Type -> Either ErrorStack Type
266+ updateType :: Maybe SourceSpan -> Type -> m Type
264267 updateType pos (TypeConstructor name) = TypeConstructor <$> updateTypeName name pos
265268 updateType pos (SaturatedTypeSynonym name tys) = SaturatedTypeSynonym <$> updateTypeName name pos <*> pure tys
266269 updateType pos (ConstrainedType cs t) = ConstrainedType <$> updateConstraints pos cs <*> pure t
@@ -280,7 +283,7 @@ renameInModule imports exports (Module mn decls exps) =
280283 -> (Exports -> a -> Bool)
281284 -> Qualified a
282285 -> Maybe SourceSpan
283− -> Either ErrorStack (Qualified a)
286+ -> m (Qualified a)
284287 update t getI checkE qname@(Qualified mn' name) pos = positioned $ case (M.lookup qname imports', mn') of
285288 (Just qname', _) -> return qname'
286289 (Nothing, Just mn'') -> do
@@ -299,13 +302,13 @@ renameInModule imports exports (Module mn decls exps) =
299302 Just pos' -> rethrowWithPosition pos' err
300303
301304 -- Gets the exports for a module, or an error message if the module doesn't exist
302− getExports :: ModuleName -> Either ErrorStack Exports
305+ getExports :: ModuleName -> m Exports
303306 getExports mn' = maybe (throwError $ mkErrorStack ("Unknown module '" ++ show mn' ++ "'") Nothing) return $ M.lookup mn' exports
304307
305308-- |
306309-- Finds all exported declarations in a set of modules.
307310--
308−findExports :: [Module] -> Either ErrorStack ExportEnvironment
311+findExports :: forall m. (Applicative m, MonadError ErrorStack m) => [Module] -> m ExportEnvironment
309312findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) primExports
310313 where
311314
@@ -315,13 +318,13 @@ findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) pri
315318 mkTypeEntry (Qualified _ name) = (name, [])
316319
317320 -- Add all of the exported declarations from a module to the global export environment
318− addModule :: ExportEnvironment -> Module -> Either ErrorStack ExportEnvironment
321+ addModule :: ExportEnvironment -> Module -> m ExportEnvironment
319322 addModule env (Module mn ds _) = do
320323 env' <- addEmptyModule env mn
321324 rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $ foldM (addDecl mn) env' ds
322325
323326 -- Add a declaration from a module to the global export environment
324− addDecl :: ModuleName -> ExportEnvironment -> Declaration -> Either ErrorStack ExportEnvironment
327+ addDecl :: ModuleName -> ExportEnvironment -> Declaration -> m ExportEnvironment
325328 addDecl mn env (TypeClassDeclaration tcn _ _ ds) = do
326329 env' <- addTypeClass env mn tcn
327330 foldM go env' ds
@@ -341,7 +344,7 @@ findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) pri
341344-- Filters the exports for a module to ensure only explicit exports are kept in the global exports
342345-- environment.
343346--
344−filterExports :: ModuleName -> [DeclarationRef] -> ExportEnvironment -> Either ErrorStack ExportEnvironment
347+filterExports :: forall m. (Applicative m, MonadError ErrorStack m) => ModuleName -> [DeclarationRef] -> ExportEnvironment -> m ExportEnvironment
345348filterExports mn exps env = do
346349 let moduleExports = fromMaybe (error "Module is missing") (mn `M.lookup` env)
347350 moduleExports' <- rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $ filterModule moduleExports
@@ -349,7 +352,7 @@ filterExports mn exps env = do
349352 where
350353
351354 -- Filter the exports for the specific module
352− filterModule :: Exports -> Either ErrorStack Exports
355+ filterModule :: Exports -> m Exports
353356 filterModule exported = do
354357 types' <- foldM (filterTypes $ exportedTypes exported) [] exps
355358 values <- foldM (filterValues $ exportedValues exported) [] exps
@@ -358,7 +361,7 @@ filterExports mn exps env = do
358361
359362 -- Ensure the exported types and data constructors exist in the module and add them to the set of
360363 -- exports
361− filterTypes :: [(ProperName, [ProperName])] -> [(ProperName, [ProperName])] -> DeclarationRef -> Either ErrorStack [(ProperName, [ProperName])]
364+ filterTypes :: [(ProperName, [ProperName])] -> [(ProperName, [ProperName])] -> DeclarationRef -> m [(ProperName, [ProperName])]
362365 filterTypes expTys result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterTypes expTys result r
363366 filterTypes expTys result (TypeRef name expDcons) = do
364367 dcons <- maybe (throwError $ mkErrorStack ("Cannot export undefined type '" ++ show name ++ "'") Nothing) return $ name `lookup` expTys
@@ -367,14 +370,14 @@ filterExports mn exps env = do
367370 filterTypes _ result _ = return result
368371
369372 -- Ensure the exported data constructors exists for a type and add them to the list of exports
370− filterDcons :: ProperName -> [ProperName] -> [ProperName] -> ProperName -> Either ErrorStack [ProperName]
373+ filterDcons :: ProperName -> [ProperName] -> [ProperName] -> ProperName -> m [ProperName]
371374 filterDcons tcon exps' result name =
372375 if name `elem` exps'
373376 then return $ name : result
374377 else throwError $ mkErrorStack ("Cannot export undefined data constructor '" ++ show name ++ "' for type '" ++ show tcon ++ "'") Nothing
375378
376379 -- Ensure the exported classes exist in the module and add them to the set of exports
377− filterClasses :: [ProperName] -> [ProperName] -> DeclarationRef -> Either ErrorStack [ProperName]
380+ filterClasses :: [ProperName] -> [ProperName] -> DeclarationRef -> m [ProperName]
378381 filterClasses exps' result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterClasses exps' result r
379382 filterClasses exps' result (TypeClassRef name) =
380383 if name `elem` exps'
@@ -383,7 +386,7 @@ filterExports mn exps env = do
383386 filterClasses _ result _ = return result
384387
385388 -- Ensure the exported values exist in the module and add them to the set of exports
386− filterValues :: [Ident] -> [Ident] -> DeclarationRef -> Either ErrorStack [Ident]
389+ filterValues :: [Ident] -> [Ident] -> DeclarationRef -> m [Ident]
387390 filterValues exps' result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterValues exps' result r
388391 filterValues exps' result (ValueRef name) =
389392 if name `elem` exps'
@@ -405,7 +408,7 @@ findImports = foldl (findImports' Nothing) M.empty
405408-- |
406409-- Constructs a local environment for a module.
407410--
408−resolveImports :: ExportEnvironment -> Module -> Either ErrorStack ImportEnvironment
411+resolveImports :: forall m. (Applicative m, MonadError ErrorStack m) => ExportEnvironment -> Module -> m ImportEnvironment
409412resolveImports env (Module currentModule decls _) =
410413 foldM resolveImport' (ImportEnvironment M.empty M.empty M.empty M.empty) (M.toList scope)
411414 where
@@ -416,7 +419,7 @@ resolveImports env (Module currentModule decls _) =
416419 scope :: M.Map ModuleName (Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)
417420 scope = M.insert currentModule (Nothing, Unqualified, Nothing) (findImports decls)
418421
419− resolveImport' :: ImportEnvironment -> (ModuleName, (Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)) -> Either ErrorStack ImportEnvironment
422+ resolveImport' :: ImportEnvironment -> (ModuleName, (Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)) -> m ImportEnvironment
420423 resolveImport' imp (mn, (pos, typ, impQual)) = do
421424 modExports <- positioned $ maybe (throwError $ mkErrorStack ("Cannot import unknown module '" ++ show mn ++ "'") Nothing) return $ mn `M.lookup` env
422425 positioned $ resolveImport currentModule mn modExports imp impQual typ
@@ -428,19 +431,19 @@ resolveImports env (Module currentModule decls _) =
428431-- |
429432-- Extends the local environment for a module by resolving an import of another module.
430433--
431−resolveImport :: ModuleName -> ModuleName -> Exports -> ImportEnvironment -> Maybe ModuleName -> ImportDeclarationType -> Either ErrorStack ImportEnvironment
434+resolveImport :: forall m. (Applicative m, MonadError ErrorStack m) => ModuleName -> ModuleName -> Exports -> ImportEnvironment -> Maybe ModuleName -> ImportDeclarationType -> m ImportEnvironment
432435resolveImport currentModule importModule exps imps impQual =
433436 resolveByType
434437 where
435438
436− resolveByType :: ImportDeclarationType -> Either ErrorStack ImportEnvironment
439+ resolveByType :: ImportDeclarationType -> m ImportEnvironment
437440 resolveByType Unqualified = importAll importExplicit
438441 resolveByType (Qualifying explImports) = (checkedRefs >=> foldM importExplicit imps) explImports
439442 resolveByType (Hiding hiddenImports) = do
440443 hiddenImports' <- checkedRefs hiddenImports
441444 importAll (importNonHidden hiddenImports')
442445
443− importNonHidden :: [DeclarationRef] -> ImportEnvironment -> DeclarationRef -> Either ErrorStack ImportEnvironment
446+ importNonHidden :: [DeclarationRef] -> ImportEnvironment -> DeclarationRef -> m ImportEnvironment
444447 importNonHidden hidden m ref =
445448 if isHidden hidden ref
446449 then return m
@@ -459,14 +462,14 @@ resolveImport currentModule importModule exps imps impQual =
459462 isHidden hidden ref = ref `elem` hidden
460463
461464 -- Import all symbols
462− importAll :: (ImportEnvironment -> DeclarationRef -> Either ErrorStack ImportEnvironment) -> Either ErrorStack ImportEnvironment
465+ importAll :: (ImportEnvironment -> DeclarationRef -> m ImportEnvironment) -> m ImportEnvironment
463466 importAll importer = do
464467 imp' <- foldM (\m (name, dctors) -> importer m (TypeRef name (Just dctors))) imps (exportedTypes exps)
465468 imp'' <- foldM (\m name -> importer m (ValueRef name)) imp' (exportedValues exps)
466469 foldM (\m name -> importer m (TypeClassRef name)) imp'' (exportedTypeClasses exps)
467470
468471 -- Import something explicitly
469− importExplicit :: ImportEnvironment -> DeclarationRef -> Either ErrorStack ImportEnvironment
472+ importExplicit :: ImportEnvironment -> DeclarationRef -> m ImportEnvironment
470473 importExplicit imp (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ importExplicit imp r
471474 importExplicit imp (ValueRef name) = do
472475 values' <- updateImports (importedValues imp) name
@@ -483,7 +486,7 @@ resolveImport currentModule importModule exps imps impQual =
483486 importExplicit _ _ = error "Invalid argument to importExplicit"
484487
485488 -- Check if DeclarationRef points to an existent symbol
486− checkedRefs :: [DeclarationRef] -> Either ErrorStack [DeclarationRef]
489+ checkedRefs :: [DeclarationRef] -> m [DeclarationRef]
487490 checkedRefs = mapM check
488491 where
489492 check (PositionedDeclarationRef pos _ r) =
@@ -504,7 +507,7 @@ resolveImport currentModule importModule exps imps impQual =
504507 allExportedDataConstructors name = fromMaybe [] $ name `lookup` exportedTypes exps
505508
506509 -- Add something to the ImportEnvironment if it does not already exist there
507− updateImports :: (Ord a, Show a) => M.Map (Qualified a) (Qualified a) -> a -> Either ErrorStack (M.Map (Qualified a) (Qualified a))
510+ updateImports :: (Ord a, Show a) => M.Map (Qualified a) (Qualified a) -> a -> m (M.Map (Qualified a) (Qualified a))
508511 updateImports m name = case M.lookup (Qualified impQual name) m of
509512 Nothing -> return $ M.insert (Qualified impQual name) (Qualified (Just importModule) name) m
510513 Just (Qualified Nothing _) -> error "Invalid state in updateImports"
@@ -521,11 +524,11 @@ resolveImport currentModule importModule exps imps impQual =
521524
522525 -- Ensure that an explicitly imported data constructor exists for the type it is being imported
523526 -- from
524− checkDctorExists :: [ProperName] -> ProperName -> Either ErrorStack ProperName
527+ checkDctorExists :: [ProperName] -> ProperName -> m ProperName
525528 checkDctorExists = checkImportExists "data constructor"
526529
527530 -- Check that an explicitly imported item exists in the module it is being imported from
528− checkImportExists :: (Eq a, Show a) => String -> [a] -> a -> Either ErrorStack a
531+ checkImportExists :: (Eq a, Show a) => String -> [a] -> a -> m a
529532 checkImportExists t exports item =
530533 if item `elem` exports
531534 then return item
@@ -534,7 +537,7 @@ resolveImport currentModule importModule exps imps impQual =
534537-- |
535538-- Raises an error for when there is more than one definition for something.
536539--
537−throwMultipleDefError :: (Show a) => String -> a -> Either ErrorStack b
540+throwMultipleDefError :: (Applicative m, MonadError ErrorStack m, Show a) => String -> a -> m b
538541throwMultipleDefError what name = throwError $
539542 mkErrorStack ("Multiple definitions for " ++ what ++ " '" ++ show name ++ "'") Nothing
540543
@@ -542,7 +545,7 @@ throwMultipleDefError what name = throwError $
542545-- Raises an error for when there is a conflicting definition for something, for example, a type
543546-- class and data constructor of the same name.
544547--
545−throwConflictingDefError :: (Show a) => String -> String -> a -> Either ErrorStack b
548+throwConflictingDefError :: (Applicative m, MonadError ErrorStack m, Show a) => String -> String -> a -> m b
546549throwConflictingDefError what1 what2 name = throwError $
547550 mkErrorStack (what1 ++ " '" ++ show name ++ "' cannot be defined in the same module as a " ++ what2 ++ " of the same name") Nothing
548551