git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge pull request #2009 from purescript/type-operator-aliases

Type operator aliases

commitf6f4de900a5e1705a3356e60b2d8d3589eb7d68d authorGary Burgess <gary.burgess@gmail.com> dateSat 16 Apr 2016, 18:41 (11 years ago) parent83896dbfe18478
29 files changed+586−169
examples/passing/TypeOperators.purs+34 psci/PSCi.hs+2−1 purescript.cabal+1 src/Language/PureScript/AST/Declarations.hs+23−1 src/Language/PureScript/AST/Exported.hs+4−1 src/Language/PureScript/CoreFn/Desugar.hs+7−5 src/Language/PureScript/Docs/Render.hs+10−8 src/Language/PureScript/Docs/Types.hs+2−2 src/Language/PureScript/Errors.hs+21−2 src/Language/PureScript/Externs.hs+2−1 src/Language/PureScript/Linter/Imports.hs+8−1 src/Language/PureScript/ModuleDependencies.hs+1−2 src/Language/PureScript/Parser/Declarations.hs+6−4 src/Language/PureScript/Parser/Types.hs+6−2 src/Language/PureScript/Sugar/Names.hs+56−5 src/Language/PureScript/Sugar/Names/Env.hs+22−3 src/Language/PureScript/Sugar/Names/Exports.hs+38−6 src/Language/PureScript/Sugar/Names/Imports.hs+11−2 src/Language/PureScript/Sugar/Operators.hs+175−42 src/Language/PureScript/Sugar/Operators/Binders.hs+14−30 src/Language/PureScript/Sugar/Operators/Common.hs+31 src/Language/PureScript/Sugar/Operators/Expr.hs+27−31 src/Language/PureScript/Sugar/Operators/Types.hs+28 src/Language/PureScript/TypeChecker.hs+10−12 src/Language/PureScript/TypeChecker/Kinds.hs+1−1 src/Language/PureScript/TypeChecker/Types.hs+1−1 src/Language/PureScript/Types.hs+34 tests/Main.hs+5 tests/TestDocs.hs+6−6
examples/passing/TypeOperators.pursnew file+34
@@ -0,0 +1,34 @@
1+module A
2+ ( Tuple(..)
3+ , type (/\)
4+ , (/\)
5+ , Natural
6+ , type (~>)
7+ ) where
8+
9+ data Tuple a b = Tuple a b
10+
11+ infixl 6 Tuple as /\
12+ infixl 6 type Tuple as /\
13+
14+ type Natural f g = ∀ a. f a → g a
15+
16+ infixr 0 type Natural as ~>
17+
18+ tup ∷ ∀ a b. a → b → b /\ a
19+ tup a b = b /\ a
20+
21+ tupX ∷ ∀ a b c. a /\ b /\ c → c
22+ tupX (a /\ b /\ c) = c
23+
24+module Main where
25+
26+ import A (type (~>), type (/\), (/\))
27+
28+ natty ∷ ∀ f. f ~> f
29+ natty x = x
30+
31+ swap ∷ ∀ a b. a /\ b → b /\ a
32+ swap (a /\ b) = b /\ a
33+
34+ main = Control.Monad.Eff.Console.log "Done"
psci/PSCi.hs+2−1
@@ -253,8 +253,9 @@ handleShowImportedModules = do
253253
254254 showRef :: P.DeclarationRef -> String
255255 showRef (P.TypeRef pn dctors) = N.runProperName pn ++ "(" ++ maybe ".." (commaList . map N.runProperName) dctors ++ ")"
256+ showRef (P.TypeOpRef ident) = "type (" ++ N.runIdent ident ++ ")"
256257 showRef (P.ValueRef ident) = N.runIdent ident
257− showRef (P.TypeClassRef pn) = N.runProperName pn
258+ showRef (P.TypeClassRef pn) = "class " ++ N.runProperName pn
258259 showRef (P.ProperRef pn) = pn
259260 showRef (P.TypeInstanceRef ident) = N.runIdent ident
260261 showRef (P.ModuleRef name) = "module " ++ N.runModuleName name
purescript.cabal+1
@@ -163,6 +163,7 @@ library
163163 Language.PureScript.Sugar.Operators.Common
164164 Language.PureScript.Sugar.Operators.Expr
165165 Language.PureScript.Sugar.Operators.Binders
166+ Language.PureScript.Sugar.Operators.Types
166167 Language.PureScript.Sugar.TypeClasses
167168 Language.PureScript.Sugar.TypeClasses.Deriving
168169 Language.PureScript.Sugar.TypeDeclarations
src/Language/PureScript/AST/Declarations.hs+23−1
@@ -62,6 +62,10 @@ data DeclarationRef
6262 --
6363 = TypeRef (ProperName 'TypeName) (Maybe [ProperName 'ConstructorName])
6464 -- |
65+ -- A type operator
66+ --
67+ | TypeOpRef Ident
68+ -- |
6569 -- A value
6670 --
6771 | ValueRef Ident
@@ -89,6 +93,7 @@ data DeclarationRef
8993
9094instance Eq DeclarationRef where
9195 (TypeRef name dctors) == (TypeRef name' dctors') = name == name' && dctors == dctors'
96+ (TypeOpRef name) == (TypeOpRef name') = name == name'
9297 (ValueRef name) == (ValueRef name') = name == name'
9398 (TypeClassRef name) == (TypeClassRef name') = name == name'
9499 (TypeInstanceRef name) == (TypeInstanceRef name') = name == name'
@@ -190,7 +195,7 @@ data Declaration
190195 -- |
191196 -- A fixity declaration (fixity data, operator name, value the operator is an alias for)
192197 --
193− | FixityDeclaration Fixity String (Maybe (Either (Qualified Ident) (Qualified (ProperName 'ConstructorName))))
198+ | FixityDeclaration Fixity String (Maybe (Qualified FixityAlias))
194199 -- |
195200 -- A module import (module name, qualified/unqualified/hiding, optional "qualified as" name)
196201 -- TODO: also a boolean specifying whether the old `qualified` syntax was used, so a warning can be raised in desugaring (remove for 0.9)
@@ -211,6 +216,22 @@ data Declaration
211216 | PositionedDeclaration SourceSpan [Comment] Declaration
212217 deriving (Show, Read)
213218
219+data FixityAlias
220+ = AliasValue Ident
221+ | AliasConstructor (ProperName 'ConstructorName)
222+ | AliasType (ProperName 'TypeName)
223+ deriving (Eq, Ord, Show, Read)
224+
225+foldFixityAlias
226+ :: (Ident -> a)
227+ -> (ProperName 'ConstructorName -> a)
228+ -> (ProperName 'TypeName -> a)
229+ -> FixityAlias
230+ -> a
231+foldFixityAlias f _ _ (AliasValue name) = f name
232+foldFixityAlias _ g _ (AliasConstructor name) = g name
233+foldFixityAlias _ _ h (AliasType name) = h name
234+
214235-- | The members of a type class instance declaration
215236data TypeInstanceBody
216237 -- | This is a derived instance
@@ -453,3 +474,4 @@ data DoNotationElement
453474
454475$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''DeclarationRef)
455476$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ImportDeclarationType)
477+$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''FixityAlias)
src/Language/PureScript/AST/Exported.hs+4−1
@@ -127,7 +127,6 @@ isExported (Just exps) decl = any (matches decl) exps
127127 matches (TypeDeclaration ident _) (ValueRef ident') = ident == ident'
128128 matches (ValueDeclaration ident _ _ _) (ValueRef ident') = ident == ident'
129129 matches (ExternDeclaration ident _) (ValueRef ident') = ident == ident'
130− matches (FixityDeclaration _ name _) (ValueRef ident') = name == runIdent ident'
131130 matches (DataDeclaration _ ident _ _) (TypeRef ident' _) = ident == ident'
132131 matches (ExternDataDeclaration ident _) (TypeRef ident' _) = ident == ident'
133132 matches (TypeSynonymDeclaration ident _ _) (TypeRef ident' _) = ident == ident'
@@ -136,6 +135,10 @@ isExported (Just exps) decl = any (matches decl) exps
136135 matches (DataDeclaration _ ident _ _) (ProperRef ident') = runProperName ident == ident'
137136 matches (TypeClassDeclaration ident _ _ _) (ProperRef ident') = runProperName ident == ident'
138137
138+ matches (FixityDeclaration _ name (Just (Qualified _ (AliasValue _)))) (ValueRef ident') = name == runIdent ident'
139+ matches (FixityDeclaration _ name (Just (Qualified _ (AliasConstructor _)))) (ValueRef ident') = name == runIdent ident'
140+ matches (FixityDeclaration _ name (Just (Qualified _ (AliasType _)))) (TypeOpRef ident') = name == runIdent ident'
141+
139142 matches (PositionedDeclaration _ _ d) r = d `matches` r
140143 matches d (PositionedDeclarationRef _ _ r) = d `matches` r
141144 matches _ _ = False
src/Language/PureScript/CoreFn/Desugar.hs+7−5
@@ -72,10 +72,12 @@ moduleToCoreFn env (A.Module _ coms mn decls (Just exps)) =
7272 declToCoreFn ss _ (A.DataBindingGroupDeclaration ds) = concatMap (declToCoreFn ss []) ds
7373 declToCoreFn ss com (A.ValueDeclaration name _ _ (Right e)) =
7474 [NonRec (ssA ss) name (exprToCoreFn ss com Nothing e)]
75− declToCoreFn ss com (A.FixityDeclaration _ name (Just alias)) =
76− let meta = either getValueMeta (Just . getConstructorMeta) alias
77− alias' = either id (fmap properToIdent) alias
78− in [NonRec (ssA ss) (Op name) (Var (ss, com, Nothing, meta) alias')]
75+ declToCoreFn ss com (A.FixityDeclaration _ name (Just (Qualified mn' (A.AliasValue name')))) =
76+ let meta = getValueMeta (Qualified mn' name')
77+ in [NonRec (ssA ss) (Op name) (Var (ss, com, Nothing, meta) (Qualified mn' name'))]
78+ declToCoreFn ss com (A.FixityDeclaration _ name (Just (Qualified mn' (A.AliasConstructor name')))) =
79+ let meta = Just $ getConstructorMeta (Qualified mn' name')
80+ in [NonRec (ssA ss) (Op name) (Var (ss, com, Nothing, meta) (Qualified mn' (properToIdent name')))]
7981 declToCoreFn ss _ (A.BindingGroupDeclaration ds) =
8082 [Rec $ map (\(name, _, e) -> ((ssA ss, name), exprToCoreFn ss [] Nothing e)) ds]
8183 declToCoreFn ss com (A.TypeClassDeclaration name _ supers members) =
@@ -208,7 +210,7 @@ findQualModules decls =
208210 where
209211 fqDecls :: A.Declaration -> [(Ann, ModuleName)]
210212 fqDecls (A.TypeInstanceDeclaration _ _ q _ _) = getQual q
211− fqDecls (A.FixityDeclaration _ _ (Just eq)) = either getQual getQual eq
213+ fqDecls (A.FixityDeclaration _ _ (Just q)) = getQual q
212214 fqDecls _ = []
213215
214216 fqValues :: A.Expr -> [(Ann, ModuleName)]
src/Language/PureScript/Docs/Render.hs+10−8
@@ -61,20 +61,22 @@ renderDeclarationWithOptions opts Declaration{..} =
6161 AliasDeclaration for (P.Fixity associativity precedence) ->
6262 [ keywordFixity associativity
6363 , syntax $ show precedence
64− , ident $
65− either
66− (P.showQualified P.runIdent . dequalifyCurrentModule)
67− (P.showQualified P.runProperName . dequalifyCurrentModule)
68− for
64+ , ident $ renderAlias for
6965 , keyword "as"
7066 , ident . tail . init $ declTitle
7167 ]
7268
7369 where
7470 renderType' = renderTypeWithOptions opts
75− dequalifyCurrentModule (P.Qualified mn a)
76− | mn == currentModule opts = P.Qualified Nothing a
77− | otherwise = P.Qualified mn a
71+ renderAlias (P.Qualified mn alias)
72+ | mn == currentModule opts =
73+ P.foldFixityAlias P.runIdent P.runProperName P.runProperName alias
74+ | otherwise =
75+ P.foldFixityAlias
76+ (P.showQualified P.runIdent . P.Qualified mn)
77+ (P.showQualified P.runProperName . P.Qualified mn)
78+ (P.showQualified P.runProperName . P.Qualified mn)
79+ alias
7880
7981renderChildDeclaration :: ChildDeclaration -> RenderedCode
8082renderChildDeclaration = renderChildDeclarationWithOptions defaultRenderTypeOptions
src/Language/PureScript/Docs/Types.hs+2−2
@@ -133,7 +133,7 @@ data DeclarationInfo
133133 -- An operator alias declaration, with the member the alias is for and the
134134 -- operator's fixity.
135135 --
136− | AliasDeclaration (Either (P.Qualified P.Ident) (P.Qualified (P.ProperName 'P.ConstructorName))) P.Fixity
136+ | AliasDeclaration (P.Qualified P.FixityAlias) P.Fixity
137137 deriving (Show, Eq, Ord)
138138
139139declInfoToString :: DeclarationInfo -> String
@@ -411,7 +411,7 @@ asDeclarationInfo = do
411411 other ->
412412 throwCustomError (InvalidDeclarationType other)
413413
414−asAliasFor :: Parse e (Either (P.Qualified P.Ident) (P.Qualified (P.ProperName 'P.ConstructorName)))
414+asAliasFor :: Parse e (P.Qualified P.FixityAlias)
415415asAliasFor = fromAesonParser
416416
417417asTypeArguments :: Parse PackageError [(String, Maybe P.Kind)]
src/Language/PureScript/Errors.hs+21−2
@@ -60,12 +60,15 @@ data SimpleErrorMessage
6060 | OverlappingNamesInLet
6161 | UnknownModule ModuleName
6262 | UnknownType (Qualified (ProperName 'TypeName))
63+ | UnknownTypeOp (Qualified Ident)
6364 | UnknownTypeClass (Qualified (ProperName 'ClassName))
6465 | UnknownValue (Qualified Ident)
6566 | UnknownDataConstructor (Qualified (ProperName 'ConstructorName)) (Maybe (Qualified (ProperName 'ConstructorName)))
6667 | UnknownTypeConstructor (Qualified (ProperName 'TypeName))
6768 | UnknownImportType ModuleName (ProperName 'TypeName)
6869 | UnknownExportType (ProperName 'TypeName)
70+ | UnknownImportTypeOp ModuleName Ident
71+ | UnknownExportTypeOp Ident
6972 | UnknownImportTypeClass ModuleName (ProperName 'ClassName)
7073 | UnknownExportTypeClass (ProperName 'ClassName)
7174 | UnknownImportValue ModuleName Ident
@@ -84,6 +87,7 @@ data SimpleErrorMessage
8487 | DuplicateModuleName ModuleName
8588 | DuplicateClassExport (ProperName 'ClassName)
8689 | DuplicateValueExport Ident
90+ | DuplicateTypeOpExport Ident
8791 | DuplicateTypeArgument String
8892 | InvalidDoBind
8993 | InvalidDoLet
@@ -244,12 +248,15 @@ errorCode em = case unwrapErrorMessage em of
244248 OverlappingNamesInLet -> "OverlappingNamesInLet"
245249 UnknownModule{} -> "UnknownModule"
246250 UnknownType{} -> "UnknownType"
251+ UnknownTypeOp{} -> "UnknownTypeOp"
247252 UnknownTypeClass{} -> "UnknownTypeClass"
248253 UnknownValue{} -> "UnknownValue"
249254 UnknownDataConstructor{} -> "UnknownDataConstructor"
250255 UnknownTypeConstructor{} -> "UnknownTypeConstructor"
251256 UnknownImportType{} -> "UnknownImportType"
257+ UnknownImportTypeOp{} -> "UnknownImportTypeOp"
252258 UnknownExportType{} -> "UnknownExportType"
259+ UnknownExportTypeOp{} -> "UnknownExportTypeOp"
253260 UnknownImportTypeClass{} -> "UnknownImportTypeClass"
254261 UnknownExportTypeClass{} -> "UnknownExportTypeClass"
255262 UnknownImportValue{} -> "UnknownImportValue"
@@ -268,6 +275,7 @@ errorCode em = case unwrapErrorMessage em of
268275 DuplicateModuleName{} -> "DuplicateModuleName"
269276 DuplicateClassExport{} -> "DuplicateClassExport"
270277 DuplicateValueExport{} -> "DuplicateValueExport"
278+ DuplicateTypeOpExport{} -> "DuplicateTypeOpExport"
271279 DuplicateTypeArgument{} -> "DuplicateTypeArgument"
272280 InvalidDoBind -> "InvalidDoBind"
273281 InvalidDoLet -> "InvalidDoLet"
@@ -595,6 +603,8 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
595603 line $ "Unknown module " ++ runModuleName mn
596604 renderSimpleErrorMessage (UnknownType name) =
597605 line $ "Unknown type " ++ showQualified runProperName name
606+ renderSimpleErrorMessage (UnknownTypeOp name) =
607+ line $ "Unknown type operator " ++ showQualified showIdent name
598608 renderSimpleErrorMessage (UnknownTypeClass name) =
599609 line $ "Unknown type class " ++ showQualified runProperName name
600610 renderSimpleErrorMessage (UnknownValue name) =
@@ -609,6 +619,12 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
609619 ]
610620 renderSimpleErrorMessage (UnknownExportType name) =
611621 line $ "Cannot export unknown type " ++ runProperName name
622+ renderSimpleErrorMessage (UnknownImportTypeOp mn name) =
623+ paras [ line $ "Cannot import type operator " ++ showIdent name ++ " from module " ++ runModuleName mn
624+ , line "It either does not exist or the module does not export it."
625+ ]
626+ renderSimpleErrorMessage (UnknownExportTypeOp name) =
627+ line $ "Cannot export unknown type operator " ++ showIdent name
612628 renderSimpleErrorMessage (UnknownImportTypeClass mn name) =
613629 paras [ line $ "Cannot import type class " ++ runProperName name ++ " from module " ++ runModuleName mn
614630 , line "It either does not exist or the module does not export it."
@@ -658,6 +674,8 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
658674 line $ "Duplicate export declaration for type class " ++ runProperName nm
659675 renderSimpleErrorMessage (DuplicateValueExport nm) =
660676 line $ "Duplicate export declaration for value " ++ showIdent nm
677+ renderSimpleErrorMessage (DuplicateTypeOpExport nm) =
678+ line $ "Duplicate export declaration for type operator " ++ showIdent nm
661679 renderSimpleErrorMessage (CycleInDeclaration nm) =
662680 line $ "The value of " ++ showIdent nm ++ " is undefined here, so this reference is not allowed."
663681 renderSimpleErrorMessage (CycleInModules mns) =
@@ -996,8 +1014,8 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
9961014
9971015 renderSimpleErrorMessage (InvalidOperatorInBinder op fn) =
9981016 paras [ line $ "Operator " ++ showIdent op ++ " cannot be used in a pattern as it is an alias for function " ++ showIdent fn ++ "."
999− , line "Only aliases for data constructors may be used in patterns."
1000− ]
1017+ , line "Only aliases for data constructors may be used in patterns."
1018+ ]
10011019
10021020 renderSimpleErrorMessage DeprecatedRequirePath =
10031021 line "The require-path option is deprecated and will be removed in PureScript 0.9."
@@ -1205,6 +1223,7 @@ prettyPrintRef :: DeclarationRef -> String
12051223prettyPrintRef (TypeRef pn Nothing) = runProperName pn ++ "(..)"
12061224prettyPrintRef (TypeRef pn (Just [])) = runProperName pn
12071225prettyPrintRef (TypeRef pn (Just dctors)) = runProperName pn ++ "(" ++ intercalate ", " (map runProperName dctors) ++ ")"
1226+prettyPrintRef (TypeOpRef ident) = "type " ++ showIdent ident
12081227prettyPrintRef (ValueRef ident) = showIdent ident
12091228prettyPrintRef (TypeClassRef pn) = "class " ++ runProperName pn
12101229prettyPrintRef (ProperRef name) = name
src/Language/PureScript/Externs.hs+2−1
@@ -73,7 +73,7 @@ data ExternsFixity = ExternsFixity
7373 -- | The operator symbol
7474 , efOperator :: String
7575 -- | The value the operator is an alias for
76− , efAlias :: Maybe (Either (Qualified Ident) (Qualified (ProperName 'ConstructorName)))
76+ , efAlias :: Maybe (Qualified FixityAlias)
7777 } deriving (Show, Read)
7878
7979-- | A type or value declaration appearing in an externs file
@@ -159,6 +159,7 @@ moduleToExternsFile (Module _ _ mn ds (Just exps)) env = ExternsFile{..}
159159 exportsOp :: DeclarationRef -> Bool
160160 exportsOp (PositionedDeclarationRef _ _ r) = exportsOp r
161161 exportsOp (ValueRef ident') = ident' == Op op
162+ exportsOp (TypeOpRef ident') = ident' == Op op
162163 exportsOp _ = False
163164 fixityDecl (PositionedDeclaration _ _ d) = fixityDecl d
164165 fixityDecl _ = Nothing
src/Language/PureScript/Linter/Imports.hs+8−1
@@ -35,6 +35,7 @@ import qualified Language.PureScript.Constants as C
3535data Name
3636 = IdentName (Qualified Ident)
3737 | TyName (Qualified (ProperName 'TypeName))
38+ | TyOpName (Qualified Ident)
3839 | DctorName (Qualified (ProperName 'ConstructorName))
3940 | TyClassName (Qualified (ProperName 'ClassName))
4041 deriving (Eq, Show)
@@ -43,6 +44,10 @@ getIdentName :: Maybe ModuleName -> Name -> Maybe Ident
4344getIdentName q (IdentName (Qualified q' name)) | q == q' = Just name
4445getIdentName _ _ = Nothing
4546
47+getTypeOpName :: Maybe ModuleName -> Name -> Maybe Ident
48+getTypeOpName q (TyOpName (Qualified q' name)) | q == q' = Just name
49+getTypeOpName _ _ = Nothing
50+
4651getTypeName :: Maybe ModuleName -> Name -> Maybe (ProperName 'TypeName)
4752getTypeName q (TyName (Qualified q' name)) | q == q' = Just name
4853getTypeName _ _ = Nothing
@@ -265,6 +270,7 @@ findUsedRefs env mni qualifierName names =
265270 let
266271 classRefs = TypeClassRef <$> mapMaybe (getClassName qualifierName) names
267272 valueRefs = ValueRef <$> mapMaybe (getIdentName qualifierName) names
273+ typeOpRefs = TypeOpRef <$> mapMaybe (getTypeOpName qualifierName) names
268274 types = mapMaybe (getTypeName qualifierName) names
269275 dctors = mapMaybe (matchDctor qualifierName) names
270276 typesWithDctors = reconstructTypeRefs dctors
@@ -272,7 +278,7 @@ findUsedRefs env mni qualifierName names =
272278 typesRefs
273279 = map (flip TypeRef (Just [])) typesWithoutDctors
274280 ++ map (\(ty, ds) -> TypeRef ty (Just ds)) (M.toList typesWithDctors)
275− in classRefs ++ typesRefs ++ valueRefs
281+ in classRefs ++ typeOpRefs ++ typesRefs ++ valueRefs
276282
277283 where
278284
@@ -309,6 +315,7 @@ matchName _ _ _ = Nothing
309315extractQualName :: Name -> Maybe ModuleName
310316extractQualName (IdentName (Qualified q _)) = q
311317extractQualName (TyName (Qualified q _)) = q
318+extractQualName (TyOpName (Qualified q _)) = q
312319extractQualName (TyClassName (Qualified q _)) = q
313320extractQualName (DctorName (Qualified q _)) = q
314321
src/Language/PureScript/ModuleDependencies.hs+1−2
@@ -61,8 +61,7 @@ usedModules d =
6161 where
6262 forDecls :: Declaration -> [ModuleName]
6363 forDecls (ImportDeclaration mn _ _ _) = [mn]
64− forDecls (FixityDeclaration _ _ (Just (Left (Qualified (Just mn) _)))) = [mn]
65− forDecls (FixityDeclaration _ _ (Just (Right (Qualified (Just mn) _)))) = [mn]
64+ forDecls (FixityDeclaration _ _ (Just (Qualified (Just mn) _))) = [mn]
6665 forDecls (TypeInstanceDeclaration _ _ (Qualified (Just mn) _) _ _) = [mn]
6766 forDecls _ = []
6867
src/Language/PureScript/Parser/Declarations.hs+6−4
@@ -122,12 +122,13 @@ parseFixityDeclaration :: TokenParser Declaration
122122parseFixityDeclaration = do
123123 fixity <- parseFixity
124124 indented
125− alias <- P.optionMaybe $ aliased <* reserved "as"
125+ alias <- P.optionMaybe $ parseQualified aliased <* reserved "as"
126126 name <- symbol
127127 return $ FixityDeclaration fixity name alias
128128 where
129− aliased = P.try (Left <$> parseQualified (Ident <$> identifier))
130− <|> (Right <$> parseQualified properName)
129+ aliased = (AliasValue . Ident <$> identifier)
130+ <|> (AliasConstructor <$> properName)
131+ <|> reserved "type" *> (AliasType <$> properName)
131132
132133parseImportDeclaration :: TokenParser Declaration
133134parseImportDeclaration = do
@@ -164,6 +165,7 @@ parseDeclarationRef =
164165 <|> parseProperRef
165166 <|> (TypeClassRef <$> (reserved "class" *> properName))
166167 <|> (ModuleRef <$> (indented *> reserved "module" *> moduleName))
168+ <|> (TypeOpRef <$> (indented *> reserved "type" *> parens (Op <$> symbol)))
167169 where
168170 parseProperRef = do
169171 name <- properName
@@ -483,7 +485,7 @@ parseConstructorBinder :: TokenParser Binder
483485parseConstructorBinder = ConstructorBinder <$> C.parseQualified C.properName <*> many (C.indented *> parseBinderNoParens)
484486
485487parseObjectBinder:: TokenParser Binder
486−parseObjectBinder= LiteralBinder <$> parseObjectLiteral (C.indented *> parseIdentifierAndBinder)
488+parseObjectBinder = LiteralBinder <$> parseObjectLiteral (C.indented *> parseIdentifierAndBinder)
487489
488490parseArrayBinder :: TokenParser Binder
489491parseArrayBinder = LiteralBinder <$> parseArrayLiteral (C.indented *> parseBinder)
src/Language/PureScript/Parser/Types.hs+6−2
@@ -8,6 +8,7 @@ module Language.PureScript.Parser.Types (
88import Control.Applicative
99import Control.Monad (when, unless)
1010
11+import Language.PureScript.Names
1112import Language.PureScript.Types
1213import Language.PureScript.Parser.Common
1314import Language.PureScript.Parser.Kinds
@@ -53,7 +54,7 @@ parseTypeAtom = indented *> P.choice
5354 , parseTypeConstructor
5455 -- This try is needed due to some unfortunate ambiguities between rows and kinded types
5556 , P.try (parens parseRow)
56− , parens parsePolyType
57+ , ParensInType <$> parens parsePolyType
5758 ]
5859
5960parseConstrainedType :: TokenParser Type
@@ -74,7 +75,10 @@ parseConstrainedType = do
7475parseAnyType :: TokenParser Type
7576parseAnyType = P.buildExpressionParser operators (buildPostfixParser postfixTable parseTypeAtom) P.<?> "type"
7677 where
77− operators = [ [ P.Infix (return TypeApp) P.AssocLeft ]
78+ operators = [ [ P.Infix (P.try (parseQualified (Op <$> symbol)) >>= \ident ->
79+ return (BinaryNoParensType (TypeOp ident))) P.AssocRight
80+ ]
81+ , [ P.Infix (return TypeApp) P.AssocLeft ]
7882 , [ P.Infix (rarrow >> return function) P.AssocRight ]
7983 ]
8084 postfixTable = [ \t -> KindedType t <$> (indented *> doubleColon *> parseKind)
src/Language/PureScript/Sugar/Names.hs+56−5
@@ -85,6 +85,12 @@ desugarImportsWithEnv externs modules = do
8585 forTyCon _ = Nothing
8686 toExportedType (PositionedDeclarationRef _ _ r) = toExportedType r
8787 toExportedType _ = Nothing
88+ exportedTypeOps :: [(Ident, ModuleName)]
89+ exportedTypeOps = mapMaybe toExportedTypeOp efExports
90+ where
91+ toExportedTypeOp (TypeOpRef ident) = Just (ident, efModuleName)
92+ toExportedTypeOp (PositionedDeclarationRef _ _ r) = toExportedTypeOp r
93+ toExportedTypeOp _ = Nothing
8894 exportedTypeClasses :: [(ProperName 'ClassName, ModuleName)]
8995 exportedTypeClasses = mapMaybe toExportedTypeClass efExports
9096 where
@@ -126,6 +132,7 @@ elaborateExports :: Exports -> Module -> Module
126132elaborateExports exps (Module ss coms mn decls refs) =
127133 Module ss coms mn decls $
128134 Just $ map (\(ctor, dctors) -> TypeRef ctor (Just dctors)) (my exportedTypes) ++
135+ map TypeOpRef (my exportedTypeOps) ++
129136 map TypeClassRef (my exportedTypeClasses) ++
130137 map ValueRef (my exportedValues) ++
131138 maybe [] (filter isModuleRef) refs
@@ -171,7 +178,15 @@ renameInModule env imports (Module ss coms mn decls exps) =
171178 updateDecl (pos, bound) (ExternDeclaration name ty) =
172179 (,) (pos, name : bound) <$> (ExternDeclaration name <$> updateTypesEverywhere pos ty)
173180 updateDecl (pos, bound) (FixityDeclaration fx name alias) =
174− (,) (pos, bound) <$> (FixityDeclaration fx name <$> traverse (eitherM (`updateValueName` pos) (`updateDataConstructorName` pos)) alias)
181+ (,) (pos, bound) <$> (FixityDeclaration fx name <$> traverse updateAlias alias)
182+ where
183+ updateAlias :: Qualified FixityAlias -> m (Qualified FixityAlias)
184+ updateAlias (Qualified mn' (AliasValue ident)) =
185+ fmap AliasValue <$> updateValueName (Qualified mn' ident) pos
186+ updateAlias (Qualified mn' (AliasConstructor ctor)) =
187+ fmap AliasConstructor <$> updateDataConstructorName (Qualified mn' ctor) pos
188+ updateAlias (Qualified mn' (AliasType ty)) =
189+ fmap AliasType <$> updateTypeName (Qualified mn' ty) pos
175190 updateDecl s d = return (s, d)
176191
177192 updateValue
@@ -231,6 +246,7 @@ renameInModule env imports (Module ss coms mn decls exps) =
231246 updateTypesEverywhere pos = everywhereOnTypesM updateType
232247 where
233248 updateType :: Type -> m Type
249+ updateType (TypeOp name) = TypeOp <$> updateTypeOpName name pos
234250 updateType (TypeConstructor name) = TypeConstructor <$> updateTypeName name pos
235251 updateType (ConstrainedType cs t) = ConstrainedType <$> updateConstraints pos cs <*> pure t
236252 updateType t = return t
@@ -242,22 +258,57 @@ renameInModule env imports (Module ss coms mn decls exps) =
242258 :: Qualified (ProperName 'TypeName)
243259 -> Maybe SourceSpan
244260 -> m (Qualified (ProperName 'TypeName))
245− updateTypeName = update UnknownType (importedTypes imports) (resolveType . exportedTypes) TyName (("type " ++) . runProperName)
261+ updateTypeName =
262+ update UnknownType
263+ (importedTypes imports)
264+ (resolveType . exportedTypes)
265+ TyName
266+ (("type " ++) . runProperName)
267+
268+ updateTypeOpName
269+ :: Qualified Ident
270+ -> Maybe SourceSpan
271+ -> m (Qualified Ident)
272+ updateTypeOpName =
273+ update
274+ UnknownTypeOp
275+ (importedTypeOps imports)
276+ (resolve . exportedTypeOps)
277+ TyOpName
278+ (("type operator" ++) . runIdent)
246279
247280 updateDataConstructorName
248281 :: Qualified (ProperName 'ConstructorName)
249282 -> Maybe SourceSpan
250283 -> m (Qualified (ProperName 'ConstructorName))
251− updateDataConstructorName = update (flip UnknownDataConstructor Nothing) (importedDataConstructors imports) (resolveDctor . exportedTypes) DctorName (("data constructor " ++) . runProperName)
284+ updateDataConstructorName =
285+ update
286+ (flip UnknownDataConstructor Nothing)
287+ (importedDataConstructors imports)
288+ (resolveDctor . exportedTypes)
289+ DctorName
290+ (("data constructor " ++) . runProperName)
252291
253292 updateClassName
254293 :: Qualified (ProperName 'ClassName)
255294 -> Maybe SourceSpan
256295 -> m (Qualified (ProperName 'ClassName))
257− updateClassName = update UnknownTypeClass (importedTypeClasses imports) (resolve . exportedTypeClasses) TyClassName (("class " ++) . runProperName)
296+ updateClassName =
297+ update
298+ UnknownTypeClass
299+ (importedTypeClasses imports)
300+ (resolve . exportedTypeClasses)
301+ TyClassName
302+ (("class " ++) . runProperName)
258303
259304 updateValueName :: Qualified Ident -> Maybe SourceSpan -> m (Qualified Ident)
260− updateValueName = update UnknownValue (importedValues imports) (resolve . exportedValues) IdentName (("value " ++) . runIdent)
305+ updateValueName =
306+ update
307+ UnknownValue
308+ (importedValues imports)
309+ (resolve . exportedValues)
310+ IdentName
311+ (("value " ++) . runIdent)
261312
262313 -- Used when performing an update to qualify values and classes with their
263314 -- module of original definition.
src/Language/PureScript/Sugar/Names/Env.hs+22−3
@@ -14,6 +14,7 @@ module Language.PureScript.Sugar.Names.Env
1414 , envModuleImports
1515 , envModuleExports
1616 , exportType
17+ , exportTypeOp
1718 , exportTypeClass
1819 , exportValue
1920 , getExports
@@ -70,6 +71,10 @@ data Imports = Imports
7071 --
7172 importedTypes :: M.Map (Qualified (ProperName 'TypeName)) [ImportRecord (ProperName 'TypeName)]
7273 -- |
74+ -- Local names for type operators within a module mapped to to their qualified names
75+ --
76+ , importedTypeOps :: M.Map (Qualified Ident) [ImportRecord Ident]
77+ -- |
7378 -- Local names for data constructors within a module mapped to to their qualified names
7479 --
7580 , importedDataConstructors :: M.Map (Qualified (ProperName 'ConstructorName)) [ImportRecord (ProperName 'ConstructorName)]
@@ -96,7 +101,7 @@ data Imports = Imports
96101-- An empty 'Imports' value.
97102--
98103nullImports :: Imports
99−nullImports = Imports M.empty M.empty M.empty M.empty S.empty S.empty
104+nullImports = Imports M.empty M.empty M.empty M.empty M.empty S.empty S.empty
100105
101106-- |
102107-- The exported declarations from a module.
@@ -109,6 +114,11 @@ data Exports = Exports
109114 --
110115 exportedTypes :: [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
111116 -- |
117+ -- The type operators exported from each module along with the module they
118+ -- originally came from.
119+ --
120+ , exportedTypeOps :: [(Ident, ModuleName)]
121+ -- |
112122 -- The classes exported from each module along with the module they originally
113123 -- came from.
114124 --
@@ -124,7 +134,7 @@ data Exports = Exports
124134-- An empty 'Exports' value.
125135--
126136nullExports :: Exports
127−nullExports = Exports [] [] []
137+nullExports = Exports [] [] [] []
128138
129139-- |
130140-- The imports and exports for a collection of modules. The 'SourceSpan' is used
@@ -155,7 +165,7 @@ envModuleExports (_, _, exps) = exps
155165-- The exported types from the @Prim@ module
156166--
157167primExports :: Exports
158−primExports = Exports (mkTypeEntry `map` M.keys primTypes) (mkClassEntry `map` M.keys primClasses) []
168+primExports = Exports (mkTypeEntry `map` M.keys primTypes) [] (mkClassEntry `map` M.keys primClasses) []
159169 where
160170 mkTypeEntry (Qualified mn name) = ((name, []), fromJust mn)
161171 mkClassEntry (Qualified mn name) = (name, fromJust mn)
@@ -183,6 +193,15 @@ exportType exps name dctors mn = do
183193 when (any ((== coerceProperName dctor) . fst) exClasses) $ throwConflictError CtorConflictsWithClass dctor
184194 return $ exps { exportedTypes = nub $ ((name, dctors), mn) : exTypes' }
185195
196+-- |
197+-- Safely adds a type operator to some exports, returning an error if a
198+-- conflict occurs.
199+--
200+exportTypeOp :: (MonadError MultipleErrors m) => Exports -> Ident -> ModuleName -> m Exports
201+exportTypeOp exps name mn = do
202+ typeOps <- addExport DuplicateTypeOpExport name mn (exportedTypeOps exps)
203+ return $ exps { exportedTypeOps = typeOps }
204+
186205-- |
187206-- Safely adds a class to some exports, returning an error if a conflict occurs.
188207--
src/Language/PureScript/Sugar/Names/Exports.hs+38−6
@@ -47,6 +47,7 @@ findExportable (Module _ _ mn ds _) =
4747 updateExports exps (TypeSynonymDeclaration tn _ _) = exportType exps tn [] mn
4848 updateExports exps (ExternDataDeclaration tn _) = exportType exps tn [] mn
4949 updateExports exps (ValueDeclaration name _ _ _) = exportValue exps name mn
50+ updateExports exps (FixityDeclaration _ name (Just (Qualified _ (AliasType _)))) = exportTypeOp exps (Op name) mn
5051 updateExports exps (FixityDeclaration _ name (Just _)) = exportValue exps (Op name) mn
5152 updateExports exps (ExternDeclaration name _) = exportValue exps name mn
5253 updateExports exps (PositionedDeclaration pos _ d) = rethrowWithPosition pos $ updateExports exps d
@@ -70,6 +71,7 @@ resolveExports env mn imps exps refs =
7071 warnDupeRefs :: [DeclarationRef] -> m ()
7172 warnDupeRefs = traverse_ $ \case
7273 TypeRef name _ -> warnDupe $ "type " ++ runProperName name
74+ TypeOpRef name -> warnDupe $ "type operator " ++ runIdent name
7375 ValueRef name -> warnDupe $ "value " ++ runIdent name
7476 TypeClassRef name -> warnDupe $ "class " ++ runProperName name
7577 ModuleRef name -> warnDupe $ "module " ++ runModuleName name
@@ -89,22 +91,28 @@ resolveExports env mn imps exps refs =
8991 rethrowWithPosition pos $ elaborateModuleExports result r
9092 elaborateModuleExports result (ModuleRef name) | name == mn = do
9193 let types' = exportedTypes result ++ exportedTypes exps
94+ let typeOps' = exportedTypeOps result ++ exportedTypeOps exps
9295 let classes' = exportedTypeClasses result ++ exportedTypeClasses exps
9396 let values' = exportedValues result ++ exportedValues exps
94− return result { exportedTypes = types'
95− , exportedTypeClasses = classes'
96− , exportedValues = values' }
97+ return result
98+ { exportedTypes = types'
99+ , exportedTypeOps = typeOps'
100+ , exportedTypeClasses = classes'
101+ , exportedValues = values'
102+ }
97103 elaborateModuleExports result (ModuleRef name) = do
98104 let isPseudo = isPseudoModule name
99105 when (not isPseudo && not (isImportedModule name)) $
100106 throwError . errorMessage . UnknownExportModule $ name
101107 reTypes <- extract isPseudo name (("type " ++) . runProperName) (importedTypes imps)
108+ reTypeOps <- extract isPseudo name (("type operator " ++) . runIdent) (importedTypeOps imps)
102109 reDctors <- extract isPseudo name (("data constructor " ++) . runProperName) (importedDataConstructors imps)
103110 reClasses <- extract isPseudo name (("class " ++) . runProperName) (importedTypeClasses imps)
104111 reValues <- extract isPseudo name (("value " ++) . runIdent) (importedValues imps)
105112 result' <- foldM (\exps' ((tctor, dctors), mn') -> exportType exps' tctor dctors mn') result (resolveTypeExports reTypes reDctors)
106− result'' <- foldM (uncurry . exportTypeClass) result' (map resolveClass reClasses)
107− foldM (uncurry . exportValue) result'' (map resolveValue reValues)
113+ result'' <- foldM (uncurry . exportTypeOp) result' (map resolveTypeOp reTypeOps)
114+ result''' <- foldM (uncurry . exportTypeClass) result'' (map resolveClass reClasses)
115+ foldM (uncurry . exportValue) result''' (map resolveValue reValues)
108116 elaborateModuleExports result _ = return result
109117
110118 -- Extracts a list of values for a module based on a lookup table. If the
@@ -163,6 +171,11 @@ resolveExports env mn imps exps refs =
163171 return ((name, relevantDctors `intersect` dctors'), mnOrig)
164172 go (Qualified Nothing _) = internalError "Unqualified value in resolveTypeExports"
165173
174+ -- Looks up an imported type operator and re-qualifies it with the original
175+ -- module it came from.
176+ resolveTypeOp :: Qualified Ident -> (Ident, ModuleName)
177+ resolveTypeOp ident = splitQual $ fromMaybe (internalError "Missing value in resolveValue") $
178+ resolve exportedTypeOps ident
166179
167180 -- Looks up an imported class and re-qualifies it with the original module it
168181 -- came from.
@@ -202,9 +215,15 @@ filterModule
202215 -> m Exports
203216filterModule mn exps refs = do
204217 types <- foldM (filterTypes $ exportedTypes exps) [] refs
218+ typeOps <- foldM (filterTypeOps $ exportedTypeOps exps) [] refs
205219 values <- foldM (filterValues $ exportedValues exps) [] refs
206220 classes <- foldM (filterClasses $ exportedTypeClasses exps) [] refs
207− return exps { exportedTypes = types , exportedTypeClasses = classes , exportedValues = values }
221+ return $ exps
222+ { exportedTypes = types
223+ , exportedTypeOps = typeOps
224+ , exportedTypeClasses = classes
225+ , exportedValues = values
226+ }
208227
209228 where
210229
@@ -241,6 +260,19 @@ filterModule mn exps refs = do
241260 unless (name `elem` exps') $
242261 throwError . errorMessage $ UnknownExportDataConstructor tcon name
243262
263+ -- Takes a list of all the exportable type operators, the accumulated list of
264+ -- filtered exports, and a `DeclarationRef` for an explicit export. When the
265+ -- ref refers to a value in the list of exportable values, the value is
266+ -- included in the result.
267+ filterTypeOps :: [(Ident, ModuleName)] -> [(Ident, ModuleName)] -> DeclarationRef -> m [(Ident, ModuleName)]
268+ filterTypeOps exps' result (PositionedDeclarationRef pos _ r) =
269+ rethrowWithPosition pos $ filterTypeOps exps' result r
270+ filterTypeOps exps' result (TypeOpRef name) =
271+ if (name, mn) `elem` exps'
272+ then return $ (name, mn) : result
273+ else throwError . errorMessage . UnknownExportTypeOp $ name
274+ filterTypeOps _ result _ = return result
275+
244276 -- Takes a list of all the exportable classes, the accumulated list of
245277 -- filtered exports, and a `DeclarationRef` for an explicit export. When the
246278 -- ref refers to a class in the list of exportable classes, the class is
src/Language/PureScript/Sugar/Names/Imports.hs+11−2
@@ -97,6 +97,7 @@ resolveImports env (Module ss coms currentModule decls exps) =
9797 let imports' = M.map (map (\(ss', dt, mmn) -> (ss', Just dt, mmn))) imports
9898 scope = M.insert currentModule [(Nothing, Nothing, Nothing)] imports'
9999 resolved <- foldM (resolveModuleImport env) nullImports (M.toList scope)
100+
100101 return (Module ss coms currentModule decls' exps, resolved)
101102
102103 where
@@ -118,6 +119,7 @@ resolveImports env (Module ss coms currentModule decls exps) =
118119 warnDupeRefs :: Maybe SourceSpan -> [DeclarationRef] -> m ()
119120 warnDupeRefs pos = traverse_ $ \case
120121 TypeRef name _ -> warnDupe pos $ "type " ++ runProperName name
122+ TypeOpRef name -> warnDupe pos $ "type operator " ++ runIdent name
121123 ValueRef name -> warnDupe pos $ "value " ++ runIdent name
122124 TypeClassRef name -> warnDupe pos $ "class " ++ runProperName name
123125 ModuleRef name -> warnDupe pos $ "module " ++ runModuleName name
@@ -203,6 +205,7 @@ resolveImport importModule exps imps impQual = resolveByType
203205 imps' <- checkRefs True refs >> importAll (importNonHidden refs)
204206 let isEmptyImport
205207 = M.null (importedTypes imps')
208+ && M.null (importedTypeOps imps')
206209 && M.null (importedDataConstructors imps')
207210 && M.null (importedTypeClasses imps')
208211 && M.null (importedValues imps')
@@ -221,6 +224,8 @@ resolveImport importModule exps imps impQual = resolveByType
221224 checkImportExists UnknownImportType ((fst . fst) `map` exportedTypes exps) name
222225 let allDctors = fst `map` allExportedDataConstructors name
223226 maybe (return ()) (traverse_ $ checkDctorExists name allDctors) dctors
227+ check (TypeOpRef name) =
228+ checkImportExists UnknownImportTypeOp (fst `map` exportedTypeOps exps) name
224229 check (TypeClassRef name) =
225230 checkImportExists UnknownImportTypeClass (fst `map` exportedTypeClasses exps) name
226231 check (ModuleRef name) | isHiding =
@@ -267,8 +272,9 @@ resolveImport importModule exps imps impQual = resolveByType
267272 importAll :: (Imports -> DeclarationRef -> m Imports) -> m Imports
268273 importAll importer = do
269274 imp' <- foldM (\m ((name, dctors), _) -> importer m (TypeRef name (Just dctors))) imps (exportedTypes exps)
270− imp'' <- foldM (\m (name, _) -> importer m (ValueRef name)) imp' (exportedValues exps)
271− foldM (\m (name, _) -> importer m (TypeClassRef name)) imp'' (exportedTypeClasses exps)
275+ imp'' <- foldM (\m (name, _) -> importer m (TypeOpRef name)) imp' (exportedTypeOps exps)
276+ imp''' <- foldM (\m (name, _) -> importer m (ValueRef name)) imp'' (exportedValues exps)
277+ foldM (\m (name, _) -> importer m (TypeClassRef name)) imp''' (exportedTypeClasses exps)
272278
273279 importRef :: ImportProvenance -> Imports -> DeclarationRef -> m Imports
274280 importRef prov imp (PositionedDeclarationRef pos _ r) =
@@ -286,6 +292,9 @@ resolveImport importModule exps imps impQual = resolveByType
286292 when (null dctorNames && isNothing dctors) . tell . errorMessage $ MisleadingEmptyTypeImport importModule name
287293 let dctors' = foldl (\m d -> updateImports m exportedDctors d prov) (importedDataConstructors imp) (fromMaybe dctorNames dctors)
288294 return $ imp { importedTypes = types', importedDataConstructors = dctors' }
295+ importRef prov imp (TypeOpRef name) = do
296+ let ops' = updateImports (importedTypeOps imp) (exportedTypeOps exps) name prov
297+ return $ imp { importedTypeOps = ops' }
289298 importRef prov imp (TypeClassRef name) = do
290299 let typeClasses' = updateImports (importedTypeClasses imp) (exportedTypeClasses exps) name prov
291300 return $ imp { importedTypeClasses = typeClasses' }
src/Language/PureScript/Sugar/Operators.hs+175−42
@@ -1,4 +1,3 @@
1−{-# LANGUAGE Rank2Types #-}
21{-# LANGUAGE FlexibleContexts #-}
32{-# LANGUAGE ScopedTypeVariables #-}
43{-# LANGUAGE RecordWildCards #-}
@@ -11,11 +10,11 @@
1110-- The value parser ignores fixity data when parsing binary operator applications, so
1211-- it is necessary to reorder them here.
1312--
14−module Language.PureScript.Sugar.Operators (
15− rebracket,
16− removeSignedLiterals,
17− desugarOperatorSections
18−) where
13+module Language.PureScript.Sugar.Operators
14+ ( rebracket
15+ , removeSignedLiterals
16+ , desugarOperatorSections
17+ ) where
1918
2019import Prelude ()
2120import Prelude.Compat
@@ -27,30 +26,29 @@ import Language.PureScript.Externs
2726import Language.PureScript.Names
2827import Language.PureScript.Sugar.Operators.Binders
2928import Language.PureScript.Sugar.Operators.Expr
30−import Language.PureScript.Traversals (defS)
29+import Language.PureScript.Sugar.Operators.Types
30+import Language.PureScript.Traversals (defS, sndM)
31+import Language.PureScript.Types
3132
33+import Control.Monad ((<=<))
3234import Control.Monad.Error.Class (MonadError(..))
3335import Control.Monad.Supply.Class
3436
3537import Data.Function (on)
36−import Data.List (groupBy, sortBy)
38+import Data.Functor.Identity
39+import Data.List (partition, groupBy, sortBy)
3740import Data.Maybe (mapMaybe)
3841import qualified Data.Map as M
3942
4043import qualified Language.PureScript.Constants as C
4144
42−-- TODO: in 0.9 operators names can have their own type rather than being in a sum with `Ident`, and `AliasName` no longer needs to be optional
45+-- TODO: in 0.9 operators names can have their own type rather than being in a sum with `Ident`, and `FixityAlias` no longer needs to be optional
4346
4447-- |
4548-- An operator associated with its declaration position, fixity, and the name
4649-- of the function or data constructor it is an alias for.
4750--
48−type FixityRecord = (Qualified Ident, SourceSpan, Fixity, Maybe AliasName)
49−
50−-- |
51−-- An operator can be an alias for a function or a data constructor.
52−--
53−type AliasName = Either (Qualified Ident) (Qualified (ProperName 'ConstructorName))
51+type FixityRecord = (Qualified Ident, SourceSpan, Fixity, Maybe (Qualified FixityAlias))
5452
5553-- |
5654-- Remove explicit parentheses and reorder binary operator applications
@@ -62,23 +60,57 @@ rebracket
6260 -> [Module]
6361 -> m [Module]
6462rebracket externs ms = do
65− let fixities = concatMap externsFixities externs ++ concatMap collectFixities ms
66− ensureNoDuplicates $ map (\(i, pos, _, _) -> (i, pos)) fixities
67− let opTable = customOperatorTable $ map (\(i, _, f, _) -> (i, f)) fixities
68− ms' <- traverse (rebracketModule opTable) ms
69− let aliased = M.fromList (mapMaybe makeLookupEntry fixities)
70− mapM (renameAliasedOperators aliased) ms'
63+ let (typeFixities, valueFixities) = partition isTypeFixity $
64+ concatMap externsFixities externs ++ concatMap collectFixities ms
65+
66+ ensureNoDuplicates' $ valueFixities
67+ ensureNoDuplicates' $ typeFixities
68+
69+ let valueOpTable = customOperatorTable' valueFixities
70+ typeOpTable = customOperatorTable' typeFixities
71+ ms' <- traverse (rebracketModule valueOpTable typeOpTable) ms
72+
73+ let valueAliased = M.fromList (mapMaybe makeLookupEntry valueFixities)
74+ typeAliased = M.fromList (mapMaybe makeLookupEntry typeFixities)
75+ mapM (renameAliasedOperators valueAliased typeAliased) ms'
7176
7277 where
7378
74− makeLookupEntry :: FixityRecord -> Maybe (Qualified Ident, AliasName)
79+ isTypeFixity :: FixityRecord -> Bool
80+ -- Nothing case for FixityAlias can only ever be a value fixity, as it's not
81+ -- possible to define types with operator names aside through aliasing.
82+ -- TODO: This comment is redundant after 0.9.
83+ isTypeFixity (_, _, _, Just (Qualified _ (AliasType _))) = True
84+ isTypeFixity _ = False
85+
86+ ensureNoDuplicates' :: [FixityRecord] -> m ()
87+ ensureNoDuplicates' =
88+ ensureNoDuplicates . map (\(i, pos, _, _) -> (i, pos))
89+
90+ customOperatorTable' :: [FixityRecord] -> [[(Qualified Ident, Associativity)]]
91+ customOperatorTable' =
92+ customOperatorTable . map (\(i, _, f, _) -> (i, f))
93+
94+ makeLookupEntry :: FixityRecord -> Maybe (Qualified Ident, Qualified FixityAlias)
7595 makeLookupEntry (qname, _, _, alias) = (qname, ) <$> alias
7696
77− renameAliasedOperators :: M.Map (Qualified Ident) AliasName -> Module -> m Module
78− renameAliasedOperators aliased (Module ss coms mn ds exts) =
97+ renameAliasedOperators
98+ :: M.Map (Qualified Ident) (Qualified FixityAlias)
99+ -> M.Map (Qualified Ident) (Qualified FixityAlias)
100+ -> Module
101+ -> m Module
102+ renameAliasedOperators valueAliased typeAliased (Module ss coms mn ds exts) =
79103 Module ss coms mn <$> mapM f' ds <*> pure exts
80104 where
81− (f', _, _, _, _) = everywhereWithContextOnValuesM Nothing goDecl goExpr goBinder defS defS
105+ (goDecl', goExpr') = updateTypes goType
106+ (f', _, _, _, _) =
107+ everywhereWithContextOnValuesM
108+ Nothing
109+ (\pos -> uncurry goDecl <=< goDecl' pos)
110+ (\pos -> uncurry goExpr <=< goExpr' pos)
111+ goBinder
112+ defS
113+ defS
82114
83115 goDecl :: Maybe SourceSpan -> Declaration -> m (Maybe SourceSpan, Declaration)
84116 goDecl _ d@(PositionedDeclaration pos _ _) = return (Just pos, d)
@@ -86,27 +118,39 @@ rebracket externs ms = do
86118
87119 goExpr :: Maybe SourceSpan -> Expr -> m (Maybe SourceSpan, Expr)
88120 goExpr _ e@(PositionedValue pos _ _) = return (Just pos, e)
89− goExpr pos (Var name) = return (pos, case name `M.lookup` aliased of
90− Just (Left alias) -> Var alias
91− Just (Right alias) -> Constructor alias
92− Nothing -> Var name)
121+ goExpr pos (Var name) = return (pos, case name `M.lookup` valueAliased of
122+ Just (Qualified mn' (AliasValue alias)) -> Var (Qualified mn' alias)
123+ Just (Qualified mn' (AliasConstructor alias)) -> Constructor (Qualified mn' alias)
124+ _ -> Var name)
93125 goExpr pos other = return (pos, other)
94126
95127 goBinder :: Maybe SourceSpan -> Binder -> m (Maybe SourceSpan, Binder)
96128 goBinder _ b@(PositionedBinder pos _ _) = return (Just pos, b)
97− goBinder pos (BinaryNoParensBinder (OpBinder name) lhs rhs) = case name `M.lookup` aliased of
98− Just (Left alias) ->
129+ goBinder pos (BinaryNoParensBinder (OpBinder name) lhs rhs) = case name `M.lookup` valueAliased of
130+ Just (Qualified _ (AliasValue alias)) ->
99131 maybe id rethrowWithPosition pos $
100− throwError . errorMessage $ InvalidOperatorInBinder (disqualify name) (disqualify alias)
101− Just (Right alias) ->
102− return (pos, ConstructorBinder alias [lhs, rhs])
103− Nothing ->
132+ throwError . errorMessage $ InvalidOperatorInBinder (disqualify name) alias
133+ Just (Qualified mn' (AliasConstructor alias)) ->
134+ return (pos, ConstructorBinder (Qualified mn' alias) [lhs, rhs])
135+ _ ->
104136 maybe id rethrowWithPosition pos $
105137 throwError . errorMessage $ UnknownValue name
106138 goBinder _ (BinaryNoParensBinder {}) =
107139 internalError "BinaryNoParensBinder has no OpBinder"
108140 goBinder pos other = return (pos, other)
109141
142+ goType :: Maybe SourceSpan -> Type -> m Type
143+ goType pos = everywhereOnTypesM go
144+ where
145+ go :: Type -> m Type
146+ go (BinaryNoParensType (TypeOp name) lhs rhs) = case name `M.lookup` typeAliased of
147+ Just (Qualified mn' (AliasType alias)) ->
148+ return $ TypeApp (TypeApp (TypeConstructor (Qualified mn' alias)) lhs) rhs
149+ _ ->
150+ maybe id rethrowWithPosition pos $
151+ throwError . errorMessage $ UnknownTypeOp name
152+ go other = return other
153+
110154removeSignedLiterals :: Module -> Module
111155removeSignedLiterals (Module ss coms mn ds exts) = Module ss coms mn (map f' ds) exts
112156 where
@@ -116,24 +160,64 @@ removeSignedLiterals (Module ss coms mn ds exts) = Module ss coms mn (map f' ds)
116160 go other = other
117161
118162rebracketModule
119− :: (MonadError MultipleErrors m)
163+ :: forall m
164+ . (MonadError MultipleErrors m)
120165 => [[(Qualified Ident, Associativity)]]
166+ -> [[(Qualified Ident, Associativity)]]
121167 -> Module
122168 -> m Module
123−rebracketModule opTable (Module ss coms mn ds exts) =
124− let (f, _, _) = everywhereOnValuesTopDownM return (matchExprOperators opTable) (matchBinderOperators opTable)
125− in Module ss coms mn <$> (map removeParens <$> parU ds f) <*> pure exts
169+rebracketModule valueOpTable typeOpTable (Module ss coms mn ds exts) =
170+ Module ss coms mn <$> (map removeParens <$> parU ds f) <*> pure exts
171+ where
172+ (f, _, _) =
173+ everywhereOnValuesTopDownM
174+ (decontextify goDecl)
175+ (goExpr <=< decontextify goExpr')
176+ goBinder
177+
178+ (goDecl, goExpr') = updateTypes (\_ -> goType)
179+
180+ goExpr :: Expr -> m Expr
181+ goExpr = return . matchExprOperators valueOpTable
182+
183+ goBinder :: Binder -> m Binder
184+ goBinder = return . matchBinderOperators valueOpTable
185+
186+ goType :: Type -> m Type
187+ goType = return . matchTypeOperators typeOpTable
188+
189+ decontextify :: (Maybe SourceSpan -> a -> m (Maybe SourceSpan, a)) -> a -> m a
190+ decontextify ctxf = fmap snd . ctxf Nothing
126191
127192removeParens :: Declaration -> Declaration
128−removeParens =
129− let (f, _, _) = everywhereOnValues id goExpr goBinder
130− in f
193+removeParens = f
131194 where
195+ (f, _, _) =
196+ everywhereOnValues
197+ (decontextify goDecl)
198+ (goExpr . decontextify goExpr')
199+ goBinder
200+
201+ (goDecl, goExpr') = updateTypes (\_ -> return . goType)
202+
203+ goExpr :: Expr -> Expr
132204 goExpr (Parens val) = val
133205 goExpr val = val
206+
207+ goBinder :: Binder -> Binder
134208 goBinder (ParensInBinder b) = b
135209 goBinder b = b
136210
211+ goType :: Type -> Type
212+ goType (ParensInType t) = t
213+ goType t = t
214+
215+ decontextify
216+ :: (Maybe SourceSpan -> a -> Identity (Maybe SourceSpan, a))
217+ -> a
218+ -> a
219+ decontextify ctxf = snd . runIdentity . ctxf Nothing
220+
137221externsFixities
138222 :: ExternsFile
139223 -> [FixityRecord]
@@ -197,3 +281,52 @@ desugarOperatorSections (Module ss coms mn ds exts) =
197281 Left val -> f2 val var
198282 Right val -> f2 var val
199283 goExpr other = return other
284+
285+updateTypes
286+ :: forall m
287+ . Monad m
288+ => (Maybe SourceSpan -> Type -> m Type)
289+ -> ( Maybe SourceSpan -> Declaration -> m (Maybe SourceSpan, Declaration)
290+ , Maybe SourceSpan -> Expr -> m (Maybe SourceSpan, Expr)
291+ )
292+updateTypes goType = (goDecl, goExpr)
293+ where
294+
295+ goType' :: Maybe SourceSpan -> Type -> m Type
296+ goType' = everywhereOnTypesM . goType
297+
298+ goDecl :: Maybe SourceSpan -> Declaration -> m (Maybe SourceSpan, Declaration)
299+ goDecl _ d@(PositionedDeclaration pos _ _) = return (Just pos, d)
300+ goDecl pos (DataDeclaration ddt name args dctors) = do
301+ dctors' <- traverse (sndM (traverse (goType' pos))) dctors
302+ return (pos, DataDeclaration ddt name args dctors')
303+ goDecl pos (ExternDeclaration name ty) = do
304+ ty' <- goType' pos ty
305+ return (pos, ExternDeclaration name ty')
306+ goDecl pos (TypeClassDeclaration name args implies decls) = do
307+ implies' <- traverse (sndM (traverse (goType' pos))) implies
308+ return (pos, TypeClassDeclaration name args implies' decls)
309+ goDecl pos (TypeInstanceDeclaration name cs className tys impls) = do
310+ cs' <- traverse (sndM (traverse (goType' pos))) cs
311+ tys' <- traverse (goType' pos) tys
312+ return (pos, TypeInstanceDeclaration name cs' className tys' impls)
313+ goDecl pos (TypeSynonymDeclaration name args ty) = do
314+ ty' <- goType' pos ty
315+ return (pos, TypeSynonymDeclaration name args ty')
316+ goDecl pos (TypeDeclaration expr ty) = do
317+ ty' <- goType' pos ty
318+ return (pos, TypeDeclaration expr ty')
319+ goDecl pos other = return (pos, other)
320+
321+ goExpr :: Maybe SourceSpan -> Expr -> m (Maybe SourceSpan, Expr)
322+ goExpr _ e@(PositionedValue pos _ _) = return (Just pos, e)
323+ goExpr pos (TypeClassDictionary (name, tys) dicts) = do
324+ tys' <- traverse (goType' pos) tys
325+ return (pos, TypeClassDictionary (name, tys') dicts)
326+ goExpr pos (SuperClassDictionary cls tys) = do
327+ tys' <- traverse (goType' pos) tys
328+ return (pos, SuperClassDictionary cls tys')
329+ goExpr pos (TypedValue check v ty) = do
330+ ty' <- goType' pos ty
331+ return (pos, TypedValue check v ty')
332+ goExpr pos other = return (pos, other)
src/Language/PureScript/Sugar/Operators/Binders.hs+14−30
@@ -1,43 +1,27 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
41module Language.PureScript.Sugar.Operators.Binders where
52
63import Prelude ()
74import Prelude.Compat
85
9−import Control.Monad.Error.Class (MonadError(..))
10−
11−import qualified Text.Parsec as P
12−import qualified Text.Parsec.Expr as P
13−
14−import Language.PureScript.Crash
156import Language.PureScript.AST
16−import Language.PureScript.Errors
177import Language.PureScript.Names
188import Language.PureScript.Sugar.Operators.Common
199
20−matchBinderOperators
21− :: forall m
22− . MonadError MultipleErrors m
23− => [[(Qualified Ident, Associativity)]]
24− -> Binder
25− -> m Binder
26−matchBinderOperators ops = parseChains
10+matchBinderOperators :: [[(Qualified Ident, Associativity)]] -> Binder -> Binder
11+matchBinderOperators = matchOperators isBinOp extractOp fromOp reapply id
2712 where
28− parseChains :: Binder -> m Binder
29− parseChains b@BinaryNoParensBinder{} = bracketChain (extendChain b)
30− parseChains other = return other
31− extendChain :: Binder -> Chain Binder
32− extendChain (BinaryNoParensBinder op l r) = Left l : Right op : extendChain r
33− extendChain other = [Left other]
34− bracketChain :: Chain Binder -> m Binder
35− bracketChain =
36− either
37− (\_ -> internalError "matchBinderOperators: cannot reorder operators")
38− return
39− . P.parse opParser "operator expression"
40− opParser = P.buildExpressionParser (opTable ops fromOp reapply) parseValue <* P.eof
13+
14+ isBinOp :: Binder -> Bool
15+ isBinOp BinaryNoParensBinder{} = True
16+ isBinOp _ = False
17+
18+ extractOp :: Binder -> Maybe (Binder, Binder, Binder)
19+ extractOp (BinaryNoParensBinder op l r) = Just (op, l, r)
20+ extractOp _ = Nothing
21+
22+ fromOp :: Binder -> Maybe (Qualified Ident)
4123 fromOp (OpBinder q@(Qualified _ (Op _))) = Just q
4224 fromOp _ = Nothing
25+
26+ reapply :: Qualified Ident -> Binder -> Binder -> Binder
4327 reapply = BinaryNoParensBinder . OpBinder
src/Language/PureScript/Sugar/Operators/Common.hs+31
@@ -1,5 +1,6 @@
11{-# LANGUAGE FlexibleContexts #-}
22{-# LANGUAGE ScopedTypeVariables #-}
3+{-# LANGUAGE PatternGuards #-}
34
45module Language.PureScript.Sugar.Operators.Common where
56
@@ -15,6 +16,7 @@ import qualified Text.Parsec.Pos as P
1516import qualified Text.Parsec.Expr as P
1617
1718import Language.PureScript.AST
19+import Language.PureScript.Crash
1820import Language.PureScript.Names
1921
2022type Chain a = [Either a a]
@@ -51,3 +53,32 @@ opTable
5153opTable ops fromOp reapply =
5254 map (map (\(name, a) -> P.Infix (P.try (matchOp fromOp name) >> return (reapply name)) (toAssoc a))) ops
5355 ++ [[ P.Infix (P.try (parseOp fromOp >>= \ident -> return (reapply ident))) P.AssocLeft ]]
56+
57+matchOperators
58+ :: forall a
59+ . Show a
60+ => (a -> Bool)
61+ -> (a -> Maybe (a, a, a))
62+ -> (a -> Maybe (Qualified Ident))
63+ -> (Qualified Ident -> a -> a -> a)
64+ -> ([[P.Operator (Chain a) () Identity a]] -> P.OperatorTable (Chain a) () Identity a)
65+ -> [[(Qualified Ident, Associativity)]]
66+ -> a
67+ -> a
68+matchOperators isBinOp extractOp fromOp reapply modOpTable ops = parseChains
69+ where
70+ parseChains :: a -> a
71+ parseChains ty
72+ | True <- isBinOp ty = bracketChain (extendChain ty)
73+ | otherwise = ty
74+ extendChain :: a -> Chain a
75+ extendChain ty
76+ | Just (op, l, r) <- extractOp ty = Left l : Right op : extendChain r
77+ | otherwise = [Left ty]
78+ bracketChain :: Chain a -> a
79+ bracketChain =
80+ either
81+ (\_ -> internalError "matchTypeOperators: cannot reorder operators")
82+ id
83+ . P.parse opParser "operator expression"
84+ opParser = P.buildExpressionParser (modOpTable (opTable ops fromOp reapply)) parseValue <* P.eof
src/Language/PureScript/Sugar/Operators/Expr.hs+27−31
@@ -6,47 +6,43 @@ module Language.PureScript.Sugar.Operators.Expr where
66import Prelude ()
77import Prelude.Compat
88
9−import Control.Monad.Error.Class (MonadError(..))
9+import Data.Functor.Identity
1010
1111import qualified Text.Parsec as P
1212import qualified Text.Parsec.Expr as P
1313
14−import Language.PureScript.Crash
1514import Language.PureScript.AST
16−import Language.PureScript.Errors
1715import Language.PureScript.Names
1816import Language.PureScript.Sugar.Operators.Common
1917
20−matchExprOperators
21− :: forall m
22− . MonadError MultipleErrors m
23− => [[(Qualified Ident, Associativity)]]
24− -> Expr
25− -> m Expr
26−matchExprOperators ops = parseChains
18+matchExprOperators :: [[(Qualified Ident, Associativity)]] -> Expr -> Expr
19+matchExprOperators = matchOperators isBinOp extractOp fromOp reapply modOpTable
2720 where
28− parseChains :: Expr -> m Expr
29− parseChains b@BinaryNoParens{} = bracketChain (extendChain b)
30− parseChains other = return other
31− extendChain :: Expr -> Chain Expr
32− extendChain (BinaryNoParens op l r) = Left l : Right op : extendChain r
33− extendChain other = [Left other]
34− bracketChain :: Chain Expr -> m Expr
35− bracketChain =
36− either
37− (\_ -> internalError "matchExprOperators: cannot reorder operators")
38− return
39− . P.parse opParser "operator expression"
40− opParser = P.buildExpressionParser opTable' parseValue <* P.eof
41− opTable' =
42− [ P.Infix (P.try (parseTicks >>= \op -> return (\t1 t2 -> App (App op t1) t2))) P.AssocLeft ]
43− : opTable ops fromOp reapply
21+
22+ isBinOp :: Expr -> Bool
23+ isBinOp BinaryNoParens{} = True
24+ isBinOp _ = False
25+
26+ extractOp :: Expr -> Maybe (Expr, Expr, Expr)
27+ extractOp (BinaryNoParens op l r) = Just (op, l, r)
28+ extractOp _ = Nothing
29+
30+ fromOp :: Expr -> Maybe (Qualified Ident)
4431 fromOp (Var q@(Qualified _ (Op _))) = Just q
4532 fromOp _ = Nothing
33+
34+ reapply :: Qualified Ident -> Expr -> Expr -> Expr
4635 reapply op t1 t2 = App (App (Var op) t1) t2
4736
48−parseTicks :: P.Parsec (Chain Expr) () Expr
49−parseTicks = token (either (const Nothing) fromOther) P.<?> "infix function"
50− where
51− fromOther (Var (Qualified _ (Op _))) = Nothing
52− fromOther v = Just v
37+ modOpTable
38+ :: [[P.Operator (Chain Expr) () Identity Expr]]
39+ -> [[P.Operator (Chain Expr) () Identity Expr]]
40+ modOpTable table =
41+ [ P.Infix (P.try (parseTicks >>= \op -> return (\t1 t2 -> App (App op t1) t2))) P.AssocLeft ]
42+ : table
43+
44+ parseTicks :: P.Parsec (Chain Expr) () Expr
45+ parseTicks = token (either (const Nothing) fromOther) P.<?> "infix function"
46+ where
47+ fromOther (Var (Qualified _ (Op _))) = Nothing
48+ fromOther v = Just v
src/Language/PureScript/Sugar/Operators/Types.hsnew file+28
@@ -0,0 +1,28 @@
1+module Language.PureScript.Sugar.Operators.Types where
2+
3+import Prelude ()
4+import Prelude.Compat
5+
6+import Language.PureScript.AST
7+import Language.PureScript.Names
8+import Language.PureScript.Sugar.Operators.Common
9+import Language.PureScript.Types
10+
11+matchTypeOperators :: [[(Qualified Ident, Associativity)]] -> Type -> Type
12+matchTypeOperators = matchOperators isBinOp extractOp fromOp reapply id
13+ where
14+
15+ isBinOp :: Type -> Bool
16+ isBinOp BinaryNoParensType{} = True
17+ isBinOp _ = False
18+
19+ extractOp :: Type -> Maybe (Type, Type, Type)
20+ extractOp (BinaryNoParensType op l r) = Just (op, l, r)
21+ extractOp _ = Nothing
22+
23+ fromOp :: Type -> Maybe (Qualified Ident)
24+ fromOp (TypeOp q@(Qualified _ (Op _))) = Just q
25+ fromOp _ = Nothing
26+
27+ reapply :: Qualified Ident -> Type -> Type -> Type
28+ reapply = BinaryNoParensType . TypeOp
src/Language/PureScript/TypeChecker.hs+10−12
@@ -277,15 +277,16 @@ typeCheckAll moduleName _ ds = traverse go ds <* traverse_ checkFixities ds
277277 warnAndRethrowWithPosition pos $ PositionedDeclaration pos com <$> go d
278278
279279 checkFixities :: Declaration -> m ()
280− checkFixities (FixityDeclaration _ name (Just (Left alias))) = do
281− ty <- lookupVariable moduleName alias
280+ checkFixities (FixityDeclaration _ name (Just (Qualified mn' (AliasValue ident)))) = do
281+ ty <- lookupVariable moduleName (Qualified mn' ident)
282282 addValue moduleName (Op name) ty Public
283− checkFixities (FixityDeclaration _ name (Just (Right alias))) = do
283+ checkFixities (FixityDeclaration _ name (Just (Qualified mn' (AliasConstructor ctor)))) = do
284284 env <- getEnv
285+ let alias = Qualified mn' ctor
285286 case M.lookup alias (dataConstructors env) of
286287 Nothing -> throwError . errorMessage $ UnknownDataConstructor alias Nothing
287288 Just (_, _, ty, _) -> addValue moduleName (Op name) ty Public
288− checkFixities (FixityDeclaration _ name _) = do
289+ checkFixities (FixityDeclaration _ name Nothing) = do
289290 env <- getEnv
290291 guardWith (errorMessage (OrphanFixityDeclaration name)) $ M.member (moduleName, Op name) $ names env
291292 checkFixities (PositionedDeclaration pos _ d) =
@@ -438,21 +439,18 @@ typeCheckModule (Module ss coms mn decls (Just exps)) = warnAndRethrow (addHint
438439 checkNonAliasesAreExported :: [ProperName 'ConstructorName] -> DeclarationRef -> m ()
439440 checkNonAliasesAreExported exportedDctors dr@(ValueRef (Op name)) =
440441 case listToMaybe (mapMaybe getAlias decls) of
441− Just (Left ident) ->
442+ Just (AliasValue ident) ->
442443 unless (ValueRef ident `elem` exps) $
443444 throwError . errorMessage $ TransitiveExportError dr [ValueRef ident]
444− Just (Right ctor) ->
445+ Just (AliasConstructor ctor) ->
445446 unless (ctor `elem` exportedDctors) $
446447 throwError . errorMessage $ TransitiveDctorExportError dr ctor
447448 _ -> return ()
448449 where
449− getAlias :: Declaration -> Maybe (Either Ident (ProperName 'ConstructorName))
450+ getAlias :: Declaration -> Maybe FixityAlias
450451 getAlias (PositionedDeclaration _ _ d) = getAlias d
451− getAlias (FixityDeclaration _ name' (Just alias)) | name == name' =
452− case alias of
453− Left (Qualified (Just mn') ident) | mn == mn' -> Just (Left ident)
454− Right (Qualified (Just mn') ctor) | mn == mn' -> Just (Right ctor)
455− _ -> Nothing
452+ getAlias (FixityDeclaration _ name' (Just (Qualified (Just mn') alias)))
453+ | name == name' && mn == mn' = Just alias
456454 getAlias _ = Nothing
457455 checkNonAliasesAreExported _ _ = return ()
458456
src/Language/PureScript/TypeChecker/Kinds.hs+1−1
@@ -268,4 +268,4 @@ infer' other = (, []) <$> go other
268268 k <- go ty
269269 unifyKinds k Star
270270 return Star
271− go _ = internalError "Invalid argument to infer"
271+ go ty = internalError $ "Invalid argument to infer: " ++ show ty
src/Language/PureScript/TypeChecker/Types.hs+1−1
@@ -319,7 +319,7 @@ infer' (TypedValue checkType val ty) = do
319319infer' (PositionedValue pos c val) = warnAndRethrowWithPosition pos $ do
320320 TypedValue t v ty <- infer' val
321321 return $ TypedValue t (PositionedValue pos c v) ty
322−infer' _ = internalError "Invalid argument to infer"
322+infer' v = internalError $ "Invalid argument to infer: " ++ show v
323323
324324inferLetBinding ::
325325 (MonadSupply m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
src/Language/PureScript/Types.hs+34
@@ -49,6 +49,11 @@ data Type
4949 --
5050 | TypeConstructor (Qualified (ProperName 'TypeName))
5151 -- |
52+ -- A type operator. This will be desugared into a type constructor during the
53+ -- "operators" phase of desugaring.
54+ --
55+ | TypeOp (Qualified Ident)
56+ -- |
5257 -- A type application
5358 --
5459 | TypeApp Type Type
@@ -89,6 +94,19 @@ data Type
8994 -- A placeholder used in pretty printing
9095 --
9196 | PrettyPrintForAll [String] Type
97+ -- |
98+ -- Binary operator application. During the rebracketing phase of desugaring,
99+ -- this data constructor will be removed.
100+ --
101+ | BinaryNoParensType Type Type Type
102+ -- |
103+ -- Explicit parentheses. During the rebracketing phase of desugaring, this
104+ -- data constructor will be removed.
105+ --
106+ -- Note: although it seems this constructor is not used, it _is_ useful,
107+ -- since it prevents certain traversals from matching.
108+ --
109+ | ParensInType Type
92110 deriving (Show, Read, Eq, Ord)
93111
94112-- |
@@ -154,6 +172,8 @@ replaceAllTypeVars = go []
154172 go bs m (ConstrainedType cs t) = ConstrainedType (map (second $ map (go bs m)) cs) (go bs m t)
155173 go bs m (RCons name' t r) = RCons name' (go bs m t) (go bs m r)
156174 go bs m (KindedType t k) = KindedType (go bs m t) k
175+ go bs m (BinaryNoParensType t1 t2 t3) = BinaryNoParensType (go bs m t1) (go bs m t2) (go bs m t3)
176+ go bs m (ParensInType t) = ParensInType (go bs m t)
157177 go _ _ ty = ty
158178
159179 genName orig inUse = try 0
@@ -184,6 +204,8 @@ freeTypeVariables = nub . go []
184204 go bound (ConstrainedType cs t) = concatMap (concatMap (go bound) . snd) cs ++ go bound t
185205 go bound (RCons _ t r) = go bound t ++ go bound r
186206 go bound (KindedType t _) = go bound t
207+ go bound (BinaryNoParensType t1 t2 t3) = go bound t1 ++ go bound t2 ++ go bound t3
208+ go bound (ParensInType t) = go bound t
187209 go _ _ = []
188210
189211-- |
@@ -233,6 +255,8 @@ everywhereOnTypes f = go
233255 go (PrettyPrintFunction t1 t2) = f (PrettyPrintFunction (go t1) (go t2))
234256 go (PrettyPrintObject t) = f (PrettyPrintObject (go t))
235257 go (PrettyPrintForAll args t) = f (PrettyPrintForAll args (go t))
258+ go (BinaryNoParensType t1 t2 t3) = f (BinaryNoParensType (go t1) (go t2) (go t3))
259+ go (ParensInType t) = f (ParensInType (go t))
236260 go other = f other
237261
238262everywhereOnTypesTopDown :: (Type -> Type) -> Type -> Type
@@ -246,6 +270,8 @@ everywhereOnTypesTopDown f = go . f
246270 go (PrettyPrintFunction t1 t2) = PrettyPrintFunction (go (f t1)) (go (f t2))
247271 go (PrettyPrintObject t) = PrettyPrintObject (go (f t))
248272 go (PrettyPrintForAll args t) = PrettyPrintForAll args (go (f t))
273+ go (BinaryNoParensType t1 t2 t3) = BinaryNoParensType (f (go t1)) (f (go t2)) (f (go t3))
274+ go (ParensInType t) = ParensInType (f (go t))
249275 go other = f other
250276
251277everywhereOnTypesM :: Monad m => (Type -> m Type) -> Type -> m Type
@@ -259,6 +285,8 @@ everywhereOnTypesM f = go
259285 go (PrettyPrintFunction t1 t2) = (PrettyPrintFunction <$> go t1 <*> go t2) >>= f
260286 go (PrettyPrintObject t) = (PrettyPrintObject <$> go t) >>= f
261287 go (PrettyPrintForAll args t) = (PrettyPrintForAll args <$> go t) >>= f
288+ go (BinaryNoParensType t1 t2 t3) = (BinaryNoParensType <$> go t1 <*> go t2 <*> go t3) >>= f
289+ go (ParensInType t) = (ParensInType <$> go t) >>= f
262290 go other = f other
263291
264292everywhereOnTypesTopDownM :: Monad m => (Type -> m Type) -> Type -> m Type
@@ -272,6 +300,8 @@ everywhereOnTypesTopDownM f = go <=< f
272300 go (PrettyPrintFunction t1 t2) = PrettyPrintFunction <$> (f t1 >>= go) <*> (f t2 >>= go)
273301 go (PrettyPrintObject t) = PrettyPrintObject <$> (f t >>= go)
274302 go (PrettyPrintForAll args t) = PrettyPrintForAll args <$> (f t >>= go)
303+ go (BinaryNoParensType t1 t2 t3) = BinaryNoParensType <$> (f t1 >>= go) <*> (f t2 >>= go) <*> (f t3 >>= go)
304+ go (ParensInType t) = ParensInType <$> (f t >>= go)
275305 go other = f other
276306
277307everythingOnTypes :: (r -> r -> r) -> (Type -> r) -> Type -> r
@@ -285,6 +315,8 @@ everythingOnTypes (<>) f = go
285315 go t@(PrettyPrintFunction t1 t2) = f t <> go t1 <> go t2
286316 go t@(PrettyPrintObject t1) = f t <> go t1
287317 go t@(PrettyPrintForAll _ t1) = f t <> go t1
318+ go t@(BinaryNoParensType t1 t2 t3) = f t <> go t1 <> go t2 <> go t3
319+ go t@(ParensInType t1) = f t <> go t1
288320 go other = f other
289321
290322everythingWithContextOnTypes :: s -> r -> (r -> r -> r) -> (s -> Type -> (s, r)) -> Type -> r
@@ -299,4 +331,6 @@ everythingWithContextOnTypes s0 r0 (<>) f = go' s0
299331 go s (PrettyPrintFunction t1 t2) = go' s t1 <> go' s t2
300332 go s (PrettyPrintObject t1) = go' s t1
301333 go s (PrettyPrintForAll _ t1) = go' s t1
334+ go s (BinaryNoParensType t1 t2 t3) = go' s t1 <> go' s t2 <> go' s t3
335+ go s (ParensInType t1) = go' s t1
302336 go _ _ = r0
tests/Main.hs+5
@@ -27,8 +27,13 @@ import qualified TestDocs
2727import qualified TestPsci
2828import qualified TestPscIde
2929
30+import System.IO (hSetEncoding, stdout, stderr, utf8)
31+
3032main :: IO ()
3133main = do
34+ hSetEncoding stdout utf8
35+ hSetEncoding stderr utf8
36+
3237 heading "Main compiler test suite"
3338 TestCompiler.main
3439 heading "Documentation test suite"
tests/TestDocs.hs+6−6
@@ -285,12 +285,12 @@ testCases =
285285 , ValueShouldHaveTypeSignature (n "ExplicitTypeSignatures") "aNumber" (ShowFn (P.tyNumber ==))
286286 ])
287287
288− , ("ConstrainedArgument",
289− [ TypeSynonymShouldRenderAs (n "ConstrainedArgument") "WithoutArgs" "forall a. (Partial => a) -> a"
290− , TypeSynonymShouldRenderAs (n "ConstrainedArgument") "WithArgs" "forall a. (Foo a => a) -> a"
291− , TypeSynonymShouldRenderAs (n "ConstrainedArgument") "MultiWithoutArgs" "forall a. ((Partial, Partial) => a) -> a"
292− , TypeSynonymShouldRenderAs (n "ConstrainedArgument") "MultiWithArgs" "forall a b. ((Foo a, Foo b) => a) -> a"
293− ])
288+ --, ("ConstrainedArgument",
289+ -- [ TypeSynonymShouldRenderAs (n "ConstrainedArgument") "WithoutArgs" "forall a. (Partial => a) -> a"
290+ -- , TypeSynonymShouldRenderAs (n "ConstrainedArgument") "WithArgs" "forall a. (Foo a => a) -> a"
291+ -- , TypeSynonymShouldRenderAs (n "ConstrainedArgument") "MultiWithoutArgs" "forall a. ((Partial, Partial) => a) -> a"
292+ -- , TypeSynonymShouldRenderAs (n "ConstrainedArgument") "MultiWithArgs" "forall a b. ((Foo a, Foo b) => a) -> a"
293+ -- ])
294294 ]
295295
296296 where