git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge pull request #237 from garyb/master

Explicit exports

commit7e087606a62dc77467c58a0f1269bfdeb8b0bd26 authorPhil Freeman <paf31@cantab.net> dateWed 5 Mar 2014, 16:27 (13 years ago) parentdc67f0439a3a3d
31 files changed+359−149
docgen/Main.hs+2−1 examples/failing/ExportExplicit.purs+16 examples/failing/ExportExplicit2.purs+13 examples/failing/ExportExplicit3.purs+5 examples/failing/ExportExplicit4.purs+14 examples/failing/ExportExplicit5.purs+5 examples/failing/ExportExplicit6.purs+13 examples/passing/ExportExplicit.purs+16 psci/Main.hs+3−2 purescript.cabal+1 src/Language/PureScript.hs+3−3 src/Language/PureScript/CodeGen/Externs.hs+2−1 src/Language/PureScript/CodeGen/JS.hs+8−10 src/Language/PureScript/CodeGen/Optimize.hs+1 src/Language/PureScript/DeadCodeElimination.hs+2−2 src/Language/PureScript/Declarations.hs+13−12 src/Language/PureScript/ModuleDependencies.hs+1−1 src/Language/PureScript/Parser/Declarations.hs+6−5 src/Language/PureScript/Parser/Types.hs+5−2 src/Language/PureScript/Pretty/Types.hs+1 src/Language/PureScript/Prim.hs+69 src/Language/PureScript/Sugar/BindingGroups.hs+3−3 src/Language/PureScript/Sugar/CaseDeclarations.hs+2−2 src/Language/PureScript/Sugar/Names.hs+146−54 src/Language/PureScript/Sugar/Operators.hs+2−2 src/Language/PureScript/Sugar/TypeClasses.hs+2−1 src/Language/PureScript/Sugar/TypeDeclarations.hs+1−1 src/Language/PureScript/TypeChecker.hs+1 src/Language/PureScript/TypeChecker/Monad.hs+2−11 src/Language/PureScript/TypeChecker/Types.hs+1 src/Language/PureScript/Types.hs−36
docgen/Main.hs+2−1
@@ -58,8 +58,9 @@ renderModules ms = do
5858 headerLevel 1 "Module Documentation"
5959 mapM_ renderModule ms
6060
61+-- TODO: filter everything by exports
6162renderModule :: P.Module -> Docs
62−renderModule (P.Module moduleName ds) = do
63+renderModule (P.Module moduleName ds exps) = do
6364 headerLevel 2 $ "Module " ++ P.runModuleName moduleName
6465 spacer
6566 headerLevel 3 "Types"
examples/failing/ExportExplicit.pursnew file+16
@@ -0,0 +1,16 @@
1+module M1 (X(..)) where
2+
3+ data X = X | Y
4+ data Z = Z
5+
6+module Main where
7+
8+ import M1
9+
10+ testX = X
11+ testY = Y
12+
13+ -- should fail as Z is not exported from M1
14+ testZ = Z
15+
16+ main = Debug.Trace.trace "Done"
examples/failing/ExportExplicit2.pursnew file+13
@@ -0,0 +1,13 @@
1+module M1 (x) where
2+
3+ x = 1
4+ y = 0
5+
6+module Main where
7+
8+ import M1
9+
10+ -- should fail as y is not exported from M1
11+ testY = y
12+
13+ main = Debug.Trace.trace "Done"
examples/failing/ExportExplicit3.pursnew file+5
@@ -0,0 +1,5 @@
1+-- should fail as z does not exist in the module
2+module M1 (x, y, z) where
3+
4+ x = 1
5+ y = 2
examples/failing/ExportExplicit4.pursnew file+14
@@ -0,0 +1,14 @@
1+module M1 (X(X)) where
2+
3+ data X = X | Y
4+
5+module Main where
6+
7+ import M1
8+
9+ testX = X
10+
11+ -- should fail as Y constructor is not exported from M1
12+ testY = Y
13+
14+ main = Debug.Trace.trace "Done"
examples/failing/ExportExplicit5.pursnew file+5
@@ -0,0 +1,5 @@
1+-- should fail as Y is not a data constructor for X
2+module M1 (X(Y)) where
3+
4+ data X = X
5+ data Y = Y
examples/failing/ExportExplicit6.pursnew file+13
@@ -0,0 +1,13 @@
1+module M1 (X(..)) where
2+
3+ data X = X | Y
4+ data Z = Z
5+
6+module Main where
7+
8+ import M1
9+
10+ -- should fail as Z is not exported from M1
11+ testZ = M1.Z
12+
13+ main = Debug.Trace.trace "Done"
examples/passing/ExportExplicit.pursnew file+16
@@ -0,0 +1,16 @@
1+module M1 (X(X), Z(..), foo) where
2+
3+ data X = X | Y
4+ data Z = Z
5+
6+ foo = 0
7+
8+module Main where
9+
10+ import M1
11+
12+ testX = X
13+ testZ = Z
14+ testFoo = foo
15+
16+ main = Debug.Trace.trace "Done"
psci/Main.hs+3−2
@@ -161,6 +161,7 @@ quitMessage = "See ya!"
161161
162162-- |
163163-- Loads module, function, and file completions.
164+-- TODO: filter names to only include exported decls
164165--
165166completion :: CompletionFunc (StateT PSCiState IO)
166167completion = completeWord Nothing " \t\n\r" findCompletions
@@ -176,7 +177,7 @@ completion = completeWord Nothing " \t\n\r" findCompletions
176177 getDeclName _ = Nothing
177178 names :: [P.Module] -> [String]
178179 names ms = nub [ show qual
179− | P.Module moduleName ds <- ms
180+ | P.Module moduleName ds _ <- ms
180181 , ident <- mapMaybe getDeclName ds
181182 , qual <- [ P.Qualified Nothing ident
182183 , P.Qualified (Just moduleName) ident]
@@ -207,7 +208,7 @@ createTemporaryModule exec PSCiState{psciImportedModuleNames = imports, psciLetB
207208 mainDecl = P.ValueDeclaration (P.Ident "main") [] Nothing mainValue
208209 decls = if exec then [itDecl, mainDecl] else [itDecl]
209210 in
210− P.Module moduleName $ map importDecl imports ++ decls
211+ P.Module moduleName ((importDecl `map` imports) ++ decls) Nothing
211212
212213-- |
213214-- Takes a value declaration and evaluates it with the current state.
purescript.cabal+1
@@ -64,6 +64,7 @@ library
6464 Language.PureScript.Pretty.Kinds
6565 Language.PureScript.Pretty.Types
6666 Language.PureScript.Pretty.Values
67+ Language.PureScript.Prim
6768 Language.PureScript.TypeChecker
6869 Language.PureScript.TypeChecker.Kinds
6970 Language.PureScript.TypeChecker.Monad
src/Language/PureScript.hs+3−3
@@ -33,7 +33,7 @@ import Language.PureScript.DeadCodeElimination as P
3333import Data.List (intercalate)
3434import Data.Maybe (mapMaybe)
3535import Control.Monad.State.Lazy
36−import Control.Applicative ((<$>))
36+import Control.Applicative ((<$>), (<*>), pure)
3737import qualified Data.Map as M
3838
3939-- |
@@ -59,9 +59,9 @@ compile :: Options -> [Module] -> Either String (String, String, Environment)
5959compile opts ms = do
6060 sorted <- sortModules ms
6161 desugared <- desugar sorted
62− (elaborated, env) <- runCheck $ forM desugared $ \(Module moduleName' decls) -> do
62+ (elaborated, env) <- runCheck $ forM desugared $ \(Module moduleName' decls exps) -> do
6363 modify (\s -> s { checkCurrentModule = Just moduleName' })
64− Module moduleName' <$> typeCheckAll mainModuleIdent moduleName' decls
64+ Module moduleName' <$> typeCheckAll mainModuleIdent moduleName' decls <*> pure exps
6565 regrouped <- createBindingGroupsModule . collapseBindingGroupsModule $ elaborated
6666 let entryPoints = moduleNameFromString `map` optionsModules opts
6767 let elim = if null entryPoints then regrouped else eliminateDeadCode env entryPoints regrouped
src/Language/PureScript/CodeGen/Externs.hs+2−1
@@ -27,9 +27,10 @@ import Data.List (intercalate)
2727
2828-- |
2929-- Generate foreign imports for all declarations in a module
30+-- TODO: only expose items listed in "exps"
3031--
3132moduleToPs :: Module -> Environment -> String
32−moduleToPs (Module mn decls) env =
33+moduleToPs (Module mn decls exps) env =
3334 "module " ++ runModuleName mn ++ " where\n" ++
3435 (intercalate "\n" . map (" " ++) . concatMap (declToPs mn env) $ decls)
3536
src/Language/PureScript/CodeGen/JS.hs+8−10
@@ -43,13 +43,14 @@ import Language.PureScript.CodeGen.JS.AST as AST
4343import Language.PureScript.Types
4444import Language.PureScript.CodeGen.Optimize
4545import Language.PureScript.CodeGen.Common
46+import Language.PureScript.Prim
4647
4748-- |
4849-- Generate code in the simplified Javascript intermediate representation for all declarations in a
4950-- module.
5051--
5152moduleToJs :: Options -> Module -> Environment -> Maybe JS
52−moduleToJs opts (Module name decls) env =
53+moduleToJs opts (Module name decls exps) env =
5354 case jsDecls of
5455 [] -> Nothing
5556 _ -> Just $ JSAssignment (JSAccessor (moduleNameToJs name) (JSVar "_ps")) $
@@ -63,17 +64,14 @@ moduleToJs opts (Module name decls) env =
6364--
6465declToJs :: Options -> ModuleName -> Declaration -> Environment -> Maybe [JS]
6566declToJs opts mp (ValueDeclaration ident _ _ val) e =
66− Just [ JSVariableIntroduction (identToJs ident) (Just (valueToJs opts mp e val))
67− , setExportProperty ident (var ident) ]
67+ Just $ export ident $ JSVariableIntroduction (identToJs ident) (Just (valueToJs opts mp e val))
6868declToJs opts mp (BindingGroupDeclaration vals) e =
6969 Just $ concatMap (\(ident, val) ->
70− [ JSVariableIntroduction (identToJs ident) (Just (valueToJs opts mp e val))
71− , setExportProperty ident (var ident) ]
70+ export ident $ JSVariableIntroduction (identToJs ident) (Just (valueToJs opts mp e val))
7271 ) vals
7372declToJs _ mp (DataDeclaration _ _ ctors) _ =
7473 Just $ flip concatMap ctors $ \(pn@(ProperName ctor), tys) ->
75− [ JSVariableIntroduction ctor (Just (go pn 0 tys []))
76− , setExportProperty (Escaped ctor) (JSVar ctor) ]
74+ export (Escaped ctor) $ JSVariableIntroduction ctor (Just (go pn 0 tys []))
7775 where
7876 go pn _ [] values =
7977 JSObjectLiteral [ ("ctor", JSStringLiteral (show (Qualified (Just mp) pn))), ("values", JSArrayLiteral $ reverse values) ]
@@ -83,15 +81,15 @@ declToJs _ mp (DataDeclaration _ _ ctors) _ =
8381declToJs opts mp (DataBindingGroupDeclaration ds) e =
8482 Just $ concat $ mapMaybe (flip (declToJs opts mp) e) ds
8583declToJs _ _ (ExternDeclaration _ ident (Just js) _) _ =
86− Just [js, setExportProperty ident (var ident)]
84+ Just $ export ident js
8785declToJs _ _ _ _ = Nothing
8886
8987-- |
9088-- Generate code in the simplified Javascript intermediate representation for exporting a
9189-- declaration from a module.
9290--
93−setExportProperty :: Ident -> JS -> JS
94−setExportProperty ident = JSAssignment (accessor ident (JSVar "module"))
91+export :: Ident -> JS -> [JS]
92+export ident value = [ value, JSAssignment (accessor ident (JSVar "module")) (var ident) ]
9593
9694-- |
9795-- Generate code in the simplified Javascript intermediate representation for a variable based on a
src/Language/PureScript/CodeGen/Optimize.hs+1
@@ -47,6 +47,7 @@ import Language.PureScript.CodeGen.JS.AST
4747import Language.PureScript.Options
4848import Language.PureScript.CodeGen.Common (identToJs)
4949import Language.PureScript.Types
50+import Language.PureScript.Prim
5051
5152-- |
5253-- Apply a series of optimizer passes to simplified Javascript code
src/Language/PureScript/DeadCodeElimination.hs+2−2
@@ -35,12 +35,12 @@ eliminateDeadCode env entryPoints ms =
3535 let declarations = concatMap (declarationsByModule env) ms
3636 (graph, _, vertexFor) = graphFromEdges $ map (\(key, deps) -> (key, key, deps)) declarations
3737 entryPointVertices = mapMaybe (vertexFor . fst) . filter (\((mn, _), _) -> mn `elem` entryPoints) $ declarations
38− in flip map ms $ \(Module moduleName ds) -> Module moduleName (filter (isUsed moduleName graph vertexFor entryPointVertices) ds)
38+ in flip map ms $ \(Module moduleName ds exps) -> Module moduleName (filter (isUsed moduleName graph vertexFor entryPointVertices) ds) exps
3939
4040type Key = (ModuleName, Either Ident ProperName)
4141
4242declarationsByModule :: Environment -> Module -> [(Key, [Key])]
43−declarationsByModule env (Module moduleName ds) = concatMap go ds
43+declarationsByModule env (Module moduleName ds _) = concatMap go ds
4444 where
4545 go :: Declaration -> [(Key, [Key])]
4646 go d@(ValueDeclaration name _ _ _) = [((moduleName, Left name), dependencies moduleName d)]
src/Language/PureScript/Declarations.hs+13−12
@@ -40,9 +40,10 @@ data Associativity = Infixl | Infixr deriving (Show, D.Data, D.Typeable)
4040data Fixity = Fixity Associativity Precedence deriving (Show, D.Data, D.Typeable)
4141
4242-- |
43−-- A module declaration, consisting of a module name and a list of declarations
43+-- A module declaration, consisting of a module name, a list of declarations, and a list of the
44+-- declarations that are explicitly imported. If the export list is Nothing, everything is exported.
4445--
45−data Module = Module ModuleName [Declaration] deriving (Show, D.Data, D.Typeable)
46+data Module = Module ModuleName [Declaration] (Maybe [DeclarationRef]) deriving (Show, D.Data, D.Typeable)
4647
4748-- |
4849-- The type of a foreign import
@@ -66,22 +67,22 @@ data ForeignImportType
6667 | TypeClassAccessorImport deriving (Show, Eq, D.Data, D.Typeable)
6768
6869-- |
69−-- An item in a list of explicit imports
70+-- An item in a list of explicit imports or exports
7071--
71−data ImportType
72+data DeclarationRef
7273 -- |
73− -- A type constructor import
74+ -- A type constructor with data constructors
7475 --
75− = TypeImport ProperName (Maybe [ProperName])
76+ = TypeRef ProperName (Maybe [ProperName])
7677 -- |
77− -- A declaration import
78+ -- A value
7879 --
79− | NameImport Ident
80+ | ValueRef Ident
8081 -- |
81− -- A type class import
82+ -- A type class
8283 --
83− | TypeClassImport ProperName
84− deriving (Show, D.Data, D.Typeable)
84+ | TypeClassRef ProperName
85+ deriving (Show, Eq, D.Data, D.Typeable)
8586
8687-- |
8788-- The data type of declarations
@@ -126,7 +127,7 @@ data Declaration
126127 -- |
127128 -- A module import (module name, optional set of identifiers to import)
128129 --
129− | ImportDeclaration ModuleName (Maybe [ImportType])
130+ | ImportDeclaration ModuleName (Maybe [DeclarationRef])
130131 -- |
131132 -- A type class declaration (name, argument, member declarations)
132133 --
src/Language/PureScript/ModuleDependencies.hs+1−1
@@ -51,7 +51,7 @@ usedModules = nub . everything (++) (mkQ [] qualifiedIdents `extQ` qualifiedProp
5151 imports _ = []
5252
5353getModuleName :: Module -> ModuleName
54−getModuleName (Module mn _) = mn
54+getModuleName (Module mn _ _) = mn
5555
5656-- |
5757-- Convert a strongly connected component of the module graph to a module
src/Language/PureScript/Parser/Declarations.hs+6−5
@@ -88,14 +88,14 @@ parseImportDeclaration = do
8888 reserved "import"
8989 indented
9090 moduleName' <- moduleName
91− idents <- P.optionMaybe $ parens $ commaSep1 parseExplicitImport
91+ idents <- P.optionMaybe $ parens $ commaSep1 parseDeclarationRef
9292 return $ ImportDeclaration moduleName' idents
9393
94−parseExplicitImport :: P.Parsec String ParseState ImportType
95−parseExplicitImport = NameImport <$> parseIdent
94+parseDeclarationRef :: P.Parsec String ParseState DeclarationRef
95+parseDeclarationRef = ValueRef <$> parseIdent
9696 <|> do name <- properName
9797 dctors <- P.optionMaybe $ parens (Just <$> commaSep1 properName <|> lexeme (P.string "..") *> pure Nothing)
98− return $ maybe (TypeClassImport name) (TypeImport name) dctors
98+ return $ maybe (TypeClassRef name) (TypeRef name) dctors
9999
100100parseTypeClassDeclaration :: P.Parsec String ParseState Declaration
101101parseTypeClassDeclaration = do
@@ -146,9 +146,10 @@ parseModule = do
146146 reserved "module"
147147 indented
148148 name <- moduleName
149+ exports <- P.optionMaybe $ parens $ commaSep1 parseDeclarationRef
149150 _ <- lexeme $ P.string "where"
150151 decls <- mark (P.many (same *> parseDeclaration))
151− return $ Module name decls
152+ return $ Module name decls exports
152153
153154-- |
154155-- Parse a collection of modules
src/Language/PureScript/Parser/Types.hs+5−2
@@ -19,13 +19,16 @@ module Language.PureScript.Parser.Types (
1919 parseTypeAtom
2020) where
2121
22+import Control.Applicative
23+import Control.Monad (when, unless)
24+
2225import Language.PureScript.Types
2326import Language.PureScript.Parser.State
2427import Language.PureScript.Parser.Common
25−import Control.Applicative
28+import Language.PureScript.Prim
29+
2630import qualified Text.Parsec as P
2731import qualified Text.Parsec.Expr as P
28−import Control.Monad (when, unless)
2932
3033parseNumber :: P.Parsec String ParseState Type
3134parseNumber = const tyNumber <$> reserved "Number"
src/Language/PureScript/Pretty/Types.hs+1
@@ -28,6 +28,7 @@ import Control.Monad.Unify
2828
2929import Language.PureScript.Types
3030import Language.PureScript.Pretty.Common
31+import Language.PureScript.Prim
3132
3233typeLiterals :: Pattern () Type String
3334typeLiterals = mkPattern match
src/Language/PureScript/Prim.hsnew file+69
@@ -0,0 +1,69 @@
1+-----------------------------------------------------------------------------
2+--
3+-- Module : Language.PureScript.Prim
4+-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5+-- License : MIT
6+--
7+-- Maintainer : Phil Freeman <paf31@cantab.net>
8+-- Stability : experimental
9+-- Portability :
10+--
11+-- |
12+--
13+-----------------------------------------------------------------------------
14+
15+module Language.PureScript.Prim where
16+
17+import Language.PureScript.Kinds
18+import Language.PureScript.Names
19+import Language.PureScript.Types
20+
21+import qualified Data.Map as M
22+
23+-- |
24+-- Type constructor for functions
25+--
26+tyFunction :: Type
27+tyFunction = TypeConstructor $ (Qualified $ Just $ ModuleName [ProperName "Prim"]) (ProperName "Function")
28+
29+-- |
30+-- Type constructor for strings
31+--
32+tyString :: Type
33+tyString = TypeConstructor $ (Qualified $ Just $ ModuleName [ProperName "Prim"]) (ProperName "String")
34+
35+-- |
36+-- Type constructor for numbers
37+--
38+tyNumber :: Type
39+tyNumber = TypeConstructor $ (Qualified $ Just $ ModuleName [ProperName "Prim"]) (ProperName "Number")
40+
41+-- |
42+-- Type constructor for booleans
43+--
44+tyBoolean :: Type
45+tyBoolean = TypeConstructor $ (Qualified $ Just $ ModuleName [ProperName "Prim"]) (ProperName "Boolean")
46+
47+-- |
48+-- Type constructor for arrays
49+--
50+tyArray :: Type
51+tyArray = TypeConstructor $ (Qualified $ Just $ ModuleName [ProperName "Prim"]) (ProperName "Array")
52+
53+-- |
54+-- Smart constructor for function types
55+--
56+function :: Type -> Type -> Type
57+function t1 = TypeApp (TypeApp tyFunction t1)
58+
59+-- |
60+-- The primitive types in the external javascript environment with their associated kinds.
61+--
62+primTypes :: M.Map (Qualified ProperName) Kind
63+primTypes = M.fromList [ (primName "Function" , FunKind Star (FunKind Star Star))
64+ , (primName "Array" , FunKind Star Star)
65+ , (primName "String" , Star)
66+ , (primName "Number" , Star)
67+ , (primName "Boolean" , Star) ]
68+ where
69+ primName name = Qualified (Just $ ModuleName [ProperName "Prim"]) (ProperName name)
src/Language/PureScript/Sugar/BindingGroups.hs+3−3
@@ -25,7 +25,7 @@ import Data.Data
2525import Data.Graph
2626import Data.Generics
2727import Data.List (nub, intersect)
28−import Control.Applicative ((<$>))
28+import Control.Applicative ((<$>), (<*>), pure)
2929
3030import Language.PureScript.Declarations
3131import Language.PureScript.Names
@@ -36,13 +36,13 @@ import Language.PureScript.Types
3636-- Replace all sets of mutually-recursive declarations in a module with binding groups
3737--
3838createBindingGroupsModule :: [Module] -> Either String [Module]
39−createBindingGroupsModule = mapM $ \(Module name ds) -> Module name <$> createBindingGroups name ds
39+createBindingGroupsModule = mapM $ \(Module name ds exps) -> Module name <$> createBindingGroups name ds <*> pure exps
4040
4141-- |
4242-- Collapse all binding groups in a module to individual declarations
4343--
4444collapseBindingGroupsModule :: [Module] -> [Module]
45−collapseBindingGroupsModule = map $ \(Module name ds) -> Module name (collapseBindingGroups ds)
45+collapseBindingGroupsModule = map $ \(Module name ds exps) -> Module name (collapseBindingGroups ds) exps
4646
4747-- |
4848-- Replace all sets of mutually-recursive declarations with binding groups
src/Language/PureScript/Sugar/CaseDeclarations.hs+2−2
@@ -35,7 +35,7 @@ import Language.PureScript.Scope
3535-- Replace all top-level binders in a module with case expressions.
3636--
3737desugarCasesModule :: [Module] -> Either String [Module]
38−desugarCasesModule ms = forM ms $ \(Module name ds) -> Module name <$> (desugarCases . desugarAbs $ ds)
38+desugarCasesModule ms = forM ms $ \(Module name ds exps) -> Module name <$> (desugarCases . desugarAbs $ ds) <*> pure exps
3939
4040desugarAbs :: [Declaration] -> [Declaration]
4141desugarAbs = everywhere (mkT replace)
@@ -54,7 +54,7 @@ desugarCases :: [Declaration] -> Either String [Declaration]
5454desugarCases = desugarRest <=< fmap join . mapM toDecls . groupBy inSameGroup
5555 where
5656 desugarRest :: [Declaration] -> Either String [Declaration]
57− desugarRest ((TypeInstanceDeclaration name constraints className tys ds) : rest) =
57+ desugarRest (TypeInstanceDeclaration name constraints className tys ds : rest) =
5858 (:) <$> (TypeInstanceDeclaration name constraints className tys <$> desugarCases ds) <*> desugarRest rest
5959 desugarRest (d : ds) = (:) d <$> desugarRest ds
6060 desugarRest [] = pure []
src/Language/PureScript/Sugar/Names.hs+146−54
@@ -20,18 +20,19 @@ import Data.Maybe (fromMaybe)
2020import Data.Data
2121import Data.Generics (extM, mkM, everywhereM)
2222import Data.Generics.Extras (mkS, extS, everywhereWithContextM')
23+import Data.List (find)
2324
2425import Control.Applicative (Applicative(..), (<$>), (<*>))
2526import Control.Monad (foldM)
2627import Control.Monad.Error
2728
2829import qualified Data.Map as M
29−import qualified Data.Set as S
3030
3131import Language.PureScript.Declarations
3232import Language.PureScript.Names
3333import Language.PureScript.Types
3434import Language.PureScript.Values
35+import Language.PureScript.Prim
3536
3637-- |
3738-- The global export environment - every declaration exported from every module.
@@ -45,14 +46,14 @@ data Exports = Exports
4546 -- |
4647 -- The types exported from each module
4748 --
48− { exportedTypes :: S.Set (ProperName, [ProperName])
49+ { exportedTypes :: [(ProperName, [ProperName])]
4950 -- |
5051 -- The classes exported from each module
5152 --
52− , exportedTypeClasses :: S.Set ProperName
53+ , exportedTypeClasses :: [ProperName]
5354 -- |
5455 -- The values exported from each module
55− , exportedValues :: S.Set Ident
56+ , exportedValues :: [Ident]
5657 --
5758 } deriving (Show)
5859
@@ -92,7 +93,7 @@ updateExportedModule env mn update = do
9293-- Adds an empty module to an ExportEnvironment.
9394--
9495addEmptyModule :: ExportEnvironment -> ModuleName -> ExportEnvironment
95−addEmptyModule env name = M.insert name (Exports S.empty S.empty S.empty) env
96+addEmptyModule env name = M.insert name (Exports [] [] []) env
9697
9798-- |
9899-- Adds a type belonging to a module to the export environment.
@@ -119,13 +120,14 @@ addValue env mn name = updateExportedModule env mn $ \m -> do
119120 return $ m { exportedValues = values }
120121
121122-- |
122−-- Adds an export to a map of exports of that type.
123+-- Adds an entry to a list of exports unless it is already present, in which case an error is
124+-- returned.
123125--
124−addExport :: (Ord s, Show s) => S.Set s -> s -> Either String (S.Set s)
126+addExport :: (Eq a, Show a) => [a] -> a -> Either String [a]
125127addExport exports name =
126− if S.member name exports
128+ if name `elem` exports
127129 then throwError $ "Multiple definitions for '" ++ show name ++ "'"
128− else return $ S.insert name exports
130+ else return $ name : exports
129131
130132-- |
131133-- Replaces all local names with qualified names within a set of modules.
@@ -137,22 +139,23 @@ desugarImports modules = do
137139 where
138140 renameInModule' exports m = rethrowForModule m $ do
139141 imports <- resolveImports exports m
140− renameInModule imports m
142+ renameInModule imports exports m
141143
142144-- |
143145-- Rethrow an error with the name of the current module in the case of a failure
144146--
145147rethrowForModule :: Module -> Either String a -> Either String a
146−rethrowForModule (Module mn _) = flip catchError $ \e -> throwError ("Error in module '" ++ show mn ++ "':\n" ++ e)
148+rethrowForModule (Module mn _ _) = flip catchError $ \e -> throwError ("Error in module '" ++ show mn ++ "':\n" ++ e)
147149
148150-- |
149−-- Replaces all local names with qualified names within a module.
151+-- Replaces all local names with qualified names within a module and checks that all existing
152+-- qualified names are valid.
150153--
151−renameInModule :: ImportEnvironment -> Module -> Either String Module
152−renameInModule imports (Module mn decls) =
153− Module mn <$> mapM updateDecl decls >>= everywhereM (mkM updateType `extM` updateValue `extM` updateBinder `extM` updateVars)
154+renameInModule :: ImportEnvironment -> ExportEnvironment -> Module -> Either String Module
155+renameInModule imports exports (Module mn decls exps) =
156+ Module mn <$> (mapM updateDecl decls >>= everywhereM (mkM updateType `extM` updateValue `extM` updateBinder `extM` updateVars)) <*> pure exps
154157 where
155− updateDecl (TypeInstanceDeclaration name cs (Qualified Nothing cn) ts ds) =
158+ updateDecl (TypeInstanceDeclaration name cs cn ts ds) =
156159 TypeInstanceDeclaration name <$> updateConstraints cs <*> updateClassName cn <*> pure ts <*> pure ds
157160 updateDecl d = return d
158161
@@ -161,43 +164,81 @@ renameInModule imports (Module mn decls) =
161164 ValueDeclaration name [] Nothing <$> everywhereWithContextM' [] (mkS bindFunctionArgs `extS` bindBinders) val
162165 where
163166 bindFunctionArgs bound (Abs (Left arg) val) = return (arg : bound, Abs (Left arg) val)
164− bindFunctionArgs bound (Var (Qualified Nothing ident)) | ident `notElem` bound = (,) bound <$> (Var <$> updateValueName ident)
167+ bindFunctionArgs bound (Var name@(Qualified Nothing ident)) | ident `notElem` bound = (,) bound <$> (Var <$> updateValueName name)
168+ bindFunctionArgs bound (Var name@(Qualified (Just _) _)) = (,) bound <$> (Var <$> updateValueName name)
165169 bindFunctionArgs bound other = return (bound, other)
166170 bindBinders :: [Ident] -> CaseAlternative -> Either String ([Ident], CaseAlternative)
167171 bindBinders bound c@(CaseAlternative bs _ _) = return (binderNames bs ++ bound, c)
168172 updateVars (ValueDeclaration name _ _ _) = error $ "Binders should have been desugared in " ++ show name
169173 updateVars other = return other
170−
171− updateValue (Constructor (Qualified Nothing nm)) =
172− Constructor <$> updateDataConstructorName nm
174+ updateValue (Constructor name) = Constructor <$> updateDataConstructorName name
173175 updateValue v = return v
174−
175− updateBinder (ConstructorBinder (Qualified Nothing nm) b) =
176− ConstructorBinder <$> updateDataConstructorName nm <*> pure b
176+ updateBinder (ConstructorBinder name b) = ConstructorBinder <$> updateDataConstructorName name <*> pure b
177177 updateBinder v = return v
178− updateType (TypeConstructor (Qualified Nothing nm)) =
179− TypeConstructor <$> updateTypeName nm
180− updateType (SaturatedTypeSynonym (Qualified Nothing nm) tys) =
181− SaturatedTypeSynonym <$> updateTypeName nm <*> mapM updateType tys
182− updateType (ConstrainedType cs t) =
183− ConstrainedType <$> updateConstraints cs <*> pure t
178+ updateType (TypeConstructor name) = TypeConstructor <$> updateTypeName name
179+ updateType (SaturatedTypeSynonym name tys) = SaturatedTypeSynonym <$> updateTypeName name <*> mapM updateType tys
180+ updateType (ConstrainedType cs t) = ConstrainedType <$> updateConstraints cs <*> pure t
184181 updateType t = return t
185− updateConstraints = mapM updateConstraint
186− updateConstraint (Qualified Nothing nm, ts) = (,) <$> updateClassName nm <*> pure ts
187− updateConstraint other = return other
188− updateTypeName = update "type" importedTypes
189− updateClassName = update "type class" importedTypeClasses
190− updateValueName = update "value" importedValues
191− updateDataConstructorName = update "data constructor" importedDataConstructors
192− update t get nm = maybe (throwError $ "Unknown " ++ t ++ " '" ++ show nm ++ "'") return $ M.lookup nm (get imports)
182+ updateConstraints = mapM (\(name, ts) -> (,) <$> updateClassName name <*> pure ts)
183+
184+ updateTypeName (Qualified Nothing name) = update "type" importedTypes name
185+ updateTypeName (Qualified (Just mn) name) = do
186+ modExports <- getExports mn
187+ case name `lookup` exportedTypes modExports of
188+ Nothing -> throwError $ "Unknown type '" ++ show (Qualified (Just mn) name) ++ "'"
189+ _ -> return $ Qualified (Just mn) name
190+
191+ updateDataConstructorName (Qualified Nothing name) = update "data constructor" importedDataConstructors name
192+ updateDataConstructorName (Qualified (Just mn) name) = do
193+ modExports <- getExports mn
194+ let allDcons = join $ snd `map` exportedTypes modExports
195+ if name `elem` allDcons
196+ then return $ Qualified (Just mn) name
197+ else throwError $ "Unknown data constructor '" ++ show (Qualified (Just mn) name) ++ "'"
198+
199+ updateClassName (Qualified Nothing name) = update "type class" importedTypeClasses name
200+ updateClassName (Qualified (Just mn) name) = check "type class" exportedTypeClasses mn name
201+
202+ updateValueName (Qualified Nothing name) = update "value" importedValues name
203+ updateValueName (Qualified (Just mn) name) = check "value" exportedValues mn name
204+
205+ -- Replace an unqualified name with a qualified
206+ update :: (Ord a, Show a) => String -> (ImportEnvironment -> M.Map a (Qualified a)) -> a -> Either String (Qualified a)
207+ update t get name = maybe (throwError $ "Unknown " ++ t ++ " '" ++ show name ++ "'") return $ M.lookup name (get imports)
208+
209+ -- Check that a qualified name is valid
210+ check :: (Show a, Eq a) => String -> (Exports -> [a]) -> ModuleName -> a -> Either String (Qualified a)
211+ check t get mn name = do
212+ modExports <- getExports mn
213+ if name `elem` get modExports
214+ then return $ Qualified (Just mn) name
215+ else throwError $ "Unknown " ++ t ++ " '" ++ show (Qualified (Just mn) name) ++ "'"
216+
217+ -- Gets the exports for a module, or an error message if the module doesn't exist
218+ getExports :: ModuleName -> Either String Exports
219+ getExports mn = maybe (throwError $ "Unknown module '" ++ show mn ++ "'") return $ M.lookup mn exports
193220
194221-- |
195222-- Finds all exported declarations in a set of modules.
196223--
197224findExports :: [Module] -> Either String ExportEnvironment
198−findExports = foldM addModule M.empty
225+findExports = foldM addModule $ M.singleton (ModuleName [ProperName "Prim"]) primExports
199226 where
200− addModule env m@(Module mn ds) = rethrowForModule m $ foldM (addDecl mn) (addEmptyModule env mn) ds
227+
228+ -- The exported types from the Prim module
229+ primExports = Exports (mkTypeEntry `map` M.keys primTypes) [] []
230+ where
231+ mkTypeEntry (Qualified _ name) = (name, [])
232+
233+ -- Add all of the exported declarations from a module to the global export environment
234+ addModule :: ExportEnvironment -> Module -> Either String ExportEnvironment
235+ addModule env m@(Module mn ds Nothing) = rethrowForModule m $ foldM (addDecl mn) (addEmptyModule env mn) ds
236+ addModule env m@(Module mn ds (Just exps)) = rethrowForModule m $ do
237+ env' <- foldM (addDecl mn) (addEmptyModule env mn) ds
238+ filterExports mn exps env'
239+
240+ -- Add a declaration from a module to the global export environment
241+ addDecl :: ModuleName -> ExportEnvironment -> Declaration -> Either String ExportEnvironment
201242 addDecl mn env (TypeClassDeclaration tcn _ ds) = do
202243 env' <- addTypeClass env mn tcn
203244 foldM (\env'' (TypeDeclaration name _) -> addValue env'' mn name) env' ds
@@ -208,10 +249,61 @@ findExports = foldM addModule M.empty
208249 addDecl mn env (ExternDeclaration _ name _ _) = addValue env mn name
209250 addDecl _ env _ = return env
210251
252+-- |
253+-- Filters the exports for a module to ensure only explicit exports are kept in the global exports
254+-- environment.
255+--
256+filterExports :: ModuleName -> [DeclarationRef] -> ExportEnvironment -> Either String ExportEnvironment
257+filterExports mn exps env = do
258+ let moduleExports = fromMaybe (error "Module is missing") (mn `M.lookup` env)
259+ moduleExports' <- filterModule exps moduleExports
260+ return $ M.insert mn moduleExports' env
261+ where
262+
263+ -- Filter the exports for the specific module
264+ filterModule :: [DeclarationRef] -> Exports -> Either String Exports
265+ filterModule exps exported = do
266+ types <- foldM (filterTypes $ exportedTypes exported) [] exps
267+ values <- foldM (filterValues $ exportedValues exported) [] exps
268+ classes <- foldM (filterClasses $ exportedTypeClasses exported) [] exps
269+ return exported { exportedTypes = types, exportedTypeClasses = classes, exportedValues = values }
270+
271+ -- Ensure the exported types and data constructors exist in the module and add them to the set of
272+ -- exports
273+ filterTypes :: [(ProperName, [ProperName])] -> [(ProperName, [ProperName])] -> DeclarationRef -> Either String [(ProperName, [ProperName])]
274+ filterTypes exps result (TypeRef name expDcons) = do
275+ dcons <- maybe (throwError $ "Cannot export undefined type '" ++ show name ++ "'") return $ name `lookup` exps
276+ dcons' <- maybe (return dcons) (foldM (filterDcons name dcons) []) expDcons
277+ return $ (name, dcons') : result
278+ filterTypes exps result _ = return result
279+
280+ -- Ensure the exported data constructors exists for a type and add them to the list of exports
281+ filterDcons :: ProperName -> [ProperName] -> [ProperName] -> ProperName -> Either String [ProperName]
282+ filterDcons tcon exps result name =
283+ if name `elem` exps
284+ then return $ name : result
285+ else throwError $ "Cannot export undefined data constructor '" ++ show name ++ "' for type '" ++ show tcon ++ "'"
286+
287+ -- Ensure the exported classes exist in the module and add them to the set of exports
288+ filterClasses :: [ProperName] -> [ProperName] -> DeclarationRef -> Either String [ProperName]
289+ filterClasses exps result (TypeClassRef name) =
290+ if name `elem` exps
291+ then return $ name : result
292+ else throwError $ "Cannot export undefined type class '" ++ show name ++ "'"
293+ filterClasses exps result _ = return result
294+
295+ -- Ensure the exported values exist in the module and add them to the set of exports
296+ filterValues :: [Ident] -> [Ident] -> DeclarationRef -> Either String [Ident]
297+ filterValues exps result (ValueRef name) =
298+ if name `elem` exps
299+ then return $ name : result
300+ else throwError $ "Cannot export undefined value '" ++ show name ++ "'"
301+ filterValues exps result _ = return result
302+
211303-- |
212304-- Type representing a set of declarations being explicitly imported from a module
213305--
214−type ExplicitImports = [ImportType]
306+type ExplicitImports = [DeclarationRef]
215307
216308-- |
217309-- Finds the imports within a module, mapping the imported module name to an optional set of
@@ -227,7 +319,7 @@ findImports = foldl findImports' M.empty
227319-- Constructs a local environment for a module.
228320--
229321resolveImports :: ExportEnvironment -> Module -> Either String ImportEnvironment
230−resolveImports env (Module currentModule decls) =
322+resolveImports env (Module currentModule decls _) =
231323 foldM resolveImport' (ImportEnvironment M.empty M.empty M.empty M.empty) (M.toList scope)
232324 where
233325 -- A Map from module name to imports from that module, where Nothing indicates everything is to be imported
@@ -249,34 +341,34 @@ resolveImport currentModule importModule exp imp i = case i of
249341 -- Import everything from a module
250342 importAll :: ImportEnvironment -> Either String ImportEnvironment
251343 importAll imp = do
252− imp' <- foldM (\m (name, dctors) -> importExplicit m (TypeImport name (Just dctors))) imp (S.toList $ exportedTypes exp)
253− imp'' <- foldM (\m name -> importExplicit m (NameImport name)) imp' (S.toList $ exportedValues exp)
254− foldM (\m name -> importExplicit m (TypeClassImport name)) imp'' (S.toList $ exportedTypeClasses exp)
344+ imp' <- foldM (\m (name, dctors) -> importExplicit m (TypeRef name (Just dctors))) imp (exportedTypes exp)
345+ imp'' <- foldM (\m name -> importExplicit m (ValueRef name)) imp' (exportedValues exp)
346+ foldM (\m name -> importExplicit m (TypeClassRef name)) imp'' (exportedTypeClasses exp)
255347
256348 -- Import something explicitly
257− importExplicit :: ImportEnvironment -> ImportType -> Either String ImportEnvironment
258− importExplicit imp (NameImport name) = do
349+ importExplicit :: ImportEnvironment -> DeclarationRef -> Either String ImportEnvironment
350+ importExplicit imp (ValueRef name) = do
259351 checkImportExists "value" values name
260352 values' <- updateImports (importedValues imp) name
261353 return $ imp { importedValues = values' }
262− importExplicit imp (TypeImport name dctors) = do
354+ importExplicit imp (TypeRef name dctors) = do
263355 checkImportExists "type" types name
264356 types' <- updateImports (importedTypes imp) name
265357 let allDctors = allExportedDataConstructors name
266358 dctors' <- maybe (return allDctors) (mapM $ checkDctorExists allDctors) dctors
267359 dctors'' <- foldM updateImports (importedDataConstructors imp) dctors'
268360 return $ imp { importedTypes = types', importedDataConstructors = dctors'' }
269− importExplicit imp (TypeClassImport name) = do
361+ importExplicit imp (TypeClassRef name) = do
270362 checkImportExists "type class" classes name
271363 typeClasses' <- updateImports (importedTypeClasses imp) name
272364 return $ imp { importedTypeClasses = typeClasses' }
273365
274366 -- Find all exported data constructors for a given type
275367 allExportedDataConstructors :: ProperName -> [ProperName]
276− allExportedDataConstructors name = fromMaybe [] $ name `lookup` S.toList (exportedTypes exp)
368+ allExportedDataConstructors name = fromMaybe [] $ name `lookup` exportedTypes exp
277369
278370 -- Add something to the ImportEnvironment if it does not already exist there
279− updateImports :: (Ord id, Show id) => M.Map id (Qualified id) -> id -> Either String (M.Map id (Qualified id))
371+ updateImports :: (Ord a, Show a) => M.Map a (Qualified a) -> a -> Either String (M.Map a (Qualified a))
280372 updateImports m name = case M.lookup name m of
281373 Nothing -> return $ M.insert name (Qualified (Just importModule) name) m
282374 Just x@(Qualified (Just mn) _) -> throwError $
@@ -286,18 +378,18 @@ resolveImport currentModule importModule exp imp i = case i of
286378
287379 -- The available values, types, and classes in the module being imported
288380 values = exportedValues exp
289− types = fst `S.map` exportedTypes exp
381+ types = fst `map` exportedTypes exp
290382 classes = exportedTypeClasses exp
291383
292384 -- Ensure that an explicitly imported data constructor exists for the type it is being imported
293385 -- from
294386 checkDctorExists :: [ProperName] -> ProperName -> Either String ProperName
295− checkDctorExists names = checkImportExists "data constructor" (S.fromList names)
387+ checkDctorExists = checkImportExists "data constructor"
296388
297389 -- Check that an explicitly imported item exists in the module it is being imported from
298− checkImportExists :: (Show a, Ord a, Eq a) => String -> S.Set a -> a -> Either String a
390+ checkImportExists :: (Eq a, Show a) => String -> [a] -> a -> Either String a
299391 checkImportExists t exports item =
300− if item `S.member` exports
392+ if item `elem` exports
301393 then return item
302394 else throwError $ "Unable to find " ++ t ++ " '" ++ show (Qualified (Just importModule) item) ++ "'"
303395
src/Language/PureScript/Sugar/Operators.hs+2−2
@@ -49,11 +49,11 @@ rebracket :: [Module] -> Either String [Module]
4949rebracket = go M.empty []
5050 where
5151 go _ rb [] = return . reverse $ rb
52− go m rb (Module name ds : ms) = do
52+ go m rb (Module name ds exps : ms) = do
5353 m' <- M.union m <$> collectFixities m name ds
5454 let opTable = customOperatorTable m'
5555 ds' <- G.everywhereM' (G.mkM (matchOperators name opTable)) ds
56− go m' (Module name (G.everywhere (G.mkT removeParens) ds') : rb) ms
56+ go m' (Module name (G.everywhere (G.mkT removeParens) ds') exps : rb) ms
5757
5858removeParens :: Value -> Value
5959removeParens (Parens val) = val
src/Language/PureScript/Sugar/TypeClasses.hs+2−1
@@ -25,6 +25,7 @@ import Language.PureScript.Types
2525import Language.PureScript.Values
2626import Language.PureScript.CodeGen.JS.AST
2727import Language.PureScript.Sugar.CaseDeclarations
28+import Language.PureScript.Prim
2829
2930import qualified Data.Map as M
3031
@@ -47,7 +48,7 @@ desugarTypeClasses :: [Module] -> Either String [Module]
4748desugarTypeClasses = flip evalStateT M.empty . mapM desugarModule
4849
4950desugarModule :: Module -> Desugar Module
50−desugarModule (Module name decls) = Module name <$> concat <$> mapM (desugarDecl name) decls
51+desugarModule (Module name decls exps) = Module name <$> concat <$> mapM (desugarDecl name) decls <*> pure exps
5152
5253-- |
5354-- Desugar type class and type class instance declarations
src/Language/PureScript/Sugar/TypeDeclarations.hs+1−1
@@ -30,7 +30,7 @@ import Language.PureScript.Values
3030-- Replace all top level type declarations in a module with type annotations
3131--
3232desugarTypeDeclarationsModule :: [Module] -> Either String [Module]
33−desugarTypeDeclarationsModule ms = forM ms $ \(Module name ds) -> Module name <$> desugarTypeDeclarations ds
33+desugarTypeDeclarationsModule ms = forM ms $ \(Module name ds exps) -> Module name <$> desugarTypeDeclarations ds <*> pure exps
3434
3535-- |
3636-- Replace all top level type declarations with type annotations
src/Language/PureScript/TypeChecker.hs+1
@@ -37,6 +37,7 @@ import Language.PureScript.Values
3737import Language.PureScript.Kinds
3838import Language.PureScript.Declarations
3939import Language.PureScript.Sugar.TypeClasses
40+import Language.PureScript.Prim
4041
4142addDataType :: ModuleName -> ProperName -> [String] -> [(ProperName, [Type])] -> Kind -> Check ()
4243addDataType moduleName name args dctors ctorKind = do
src/Language/PureScript/TypeChecker/Monad.hs+2−11
@@ -23,6 +23,7 @@ import Language.PureScript.Kinds
2323import Language.PureScript.Values
2424import Language.PureScript.Names
2525import Language.PureScript.Declarations
26+import Language.PureScript.Prim
2627
2728import Data.Data
2829import Data.Maybe
@@ -83,21 +84,11 @@ data Environment = Environment {
8384 , typeClassDictionaries :: [TypeClassDictionaryInScope]
8485 } deriving (Show)
8586
86−-- |
87−-- The basic types existing in the external javascript environment
88−--
89−jsTypes ::M.Map (Qualified ProperName) Kind
90−jsTypes = M.fromList [ (Qualified (Just $ ModuleName [ProperName "Prim"]) (ProperName "Function"), FunKind Star (FunKind Star Star))
91− , (Qualified (Just $ ModuleName [ProperName "Prim"]) (ProperName "Array"), FunKind Star Star)
92− , (Qualified (Just $ ModuleName [ProperName "Prim"]) (ProperName "String"), Star)
93− , (Qualified (Just $ ModuleName [ProperName "Prim"]) (ProperName "Number"), Star)
94− , (Qualified (Just $ ModuleName [ProperName "Prim"]) (ProperName "Boolean"), Star) ]
95−
9687-- |
9788-- The initial environment with no values and only the default javascript types defined
9889--
9990initEnvironment :: Environment
100−initEnvironment = Environment M.empty jsTypes M.empty M.empty []
91+initEnvironment = Environment M.empty primTypes M.empty M.empty []
10192
10293-- |
10394-- Temporarily bind a collection of names to values
src/Language/PureScript/TypeChecker/Types.hs+1
@@ -56,6 +56,7 @@ import Language.PureScript.TypeChecker.Monad
5656import Language.PureScript.TypeChecker.Kinds
5757import Language.PureScript.TypeChecker.Synonyms
5858import Language.PureScript.Pretty
59+import Language.PureScript.Prim
5960
6061import Control.Monad.State
6162import Control.Monad.Error
src/Language/PureScript/Types.hs−36
@@ -88,42 +88,6 @@ data Type
8888 --
8989 | PrettyPrintArray Type deriving (Show, Eq, Data, Typeable)
9090
91−-- |
92−-- Type constructor for functions
93−--
94−tyFunction :: Type
95−tyFunction = TypeConstructor $ (Qualified $ Just $ ModuleName [ProperName "Prim"]) (ProperName "Function")
96−
97−-- |
98−-- Type constructor for strings
99−--
100−tyString :: Type
101−tyString = TypeConstructor $ (Qualified $ Just $ ModuleName [ProperName "Prim"]) (ProperName "String")
102−
103−-- |
104−-- Type constructor for numbers
105−--
106−tyNumber :: Type
107−tyNumber = TypeConstructor $ (Qualified $ Just $ ModuleName [ProperName "Prim"]) (ProperName "Number")
108−
109−-- |
110−-- Type constructor for booleans
111−--
112−tyBoolean :: Type
113−tyBoolean = TypeConstructor $ (Qualified $ Just $ ModuleName [ProperName "Prim"]) (ProperName "Boolean")
114−
115−-- |
116−-- Type constructor for arrays
117−--
118−tyArray :: Type
119−tyArray = TypeConstructor $ (Qualified $ Just $ ModuleName [ProperName "Prim"]) (ProperName "Array")
120−
121−-- |
122−-- Smart constructor for function types
123−--
124−function :: Type -> Type -> Type
125−function t1 = TypeApp (TypeApp tyFunction t1)
126−
12791-- |
12892-- Convert a row to a list of pairs of labels and types
12993--