git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge master to feature branch
commit562144926187abf70dc91d90abf5c256be888a94 authorPhil Freeman <paf31@cantab.net> dateSat 10 Oct 2015, 16:40 (11 years ago) parent5469304c70560a
40 files changed+309−187
.travis.yml+6−6 CONTRIBUTORS.md+1 examples/passing/LargeSumType.purs+33 examples/passing/OptionalQualified.purs+13 examples/passing/QualifiedQualifiedImports.purs+6 examples/passing/UTF8Sourcefile.purs+10 psc/Main.hs+4−2 purescript.cabal+2−1 src/Language/PureScript/AST/Exported.hs+1−1 src/Language/PureScript/Bundle.hs+1−1 src/Language/PureScript/CodeGen/JS.hs+2−1 src/Language/PureScript/CodeGen/JS/Optimizer/Inliner.hs+1−1 src/Language/PureScript/CodeGen/JS/Optimizer/TCO.hs+1−1 src/Language/PureScript/CodeGen/JS/Optimizer/Unused.hs+1−1 src/Language/PureScript/CoreFn/Expr.hs+1−1 src/Language/PureScript/Docs/Convert.hs+2−2 src/Language/PureScript/Docs/Render.hs+3−2 src/Language/PureScript/Docs/Types.hs+1−1 src/Language/PureScript/Errors.hs+43−34 src/Language/PureScript/Linter/Exhaustive.hs+46−28 src/Language/PureScript/Make.hs+48−24 src/Language/PureScript/Parser/Declarations.hs+25−27 src/Language/PureScript/Parser/Kinds.hs+1−1 src/Language/PureScript/Parser/Lexer.hs+1−1 src/Language/PureScript/Pretty/JS.hs+13−13 src/Language/PureScript/Publish.hs+1−1 src/Language/PureScript/Publish/ErrorsWarnings.hs+14−15 src/Language/PureScript/Renamer.hs+3−3 src/Language/PureScript/Sugar/DoNotation.hs+2−2 src/Language/PureScript/Sugar/Names.hs+1−1 src/Language/PureScript/Sugar/Names/Exports.hs+2−3 src/Language/PureScript/Sugar/TypeDeclarations.hs+1−1 src/Language/PureScript/TypeChecker/Entailment.hs−1 src/Language/PureScript/TypeChecker/Types.hs+1−1 src/Language/PureScript/TypeChecker/Unify.hs+1−1 src/Language/PureScript/Types.hs+2−4 src/System/IO/UTF8.hs+9 stack-lts-3.yaml+1−1 stack-nightly.yaml+1−1 tests/Main.hs+4−3
.travis.yml+6−6
@@ -9,8 +9,8 @@ matrix:
99 - env: GHCVER=7.8.4 COVERAGE_SUITE=psci-tests
1010 compiler: ": #GHC 7.8.4 - psci-tests"
1111 addons: {apt: {packages: [cabal-install-1.22,ghc-7.8.4,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
12− - env: GHCVER=7.8.4 STACKAGE=lts-22
13− compiler: ": #GHC 7.8.4 - lts-2.22"
12+ - env: GHCVER=7.8.4 STACKAGE=lts-2.22
13+ compiler: ": #GHC 7.8.4 - lts-2.22-1"
1414 addons: {apt: {packages: [cabal-install-1.22,ghc-7.8.4,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
1515 - env: GHCVER=7.6.3
1616 compiler: ": #GHC 7.6.3"
@@ -18,11 +18,11 @@ matrix:
1818 - env: GHCVER=7.10.1
1919 compiler: ": #GHC 7.10.1"
2020 addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.1,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
21− - env: GHCVER=7.10.2 STACKAGE=lts=3.4 RUNSDISTTESTS=YES
22− compiler: ": #GHC 7.10.2 lts-3.4"
21+ - env: GHCVER=7.10.2 STACKAGE=lts=3.6 RUNSDISTTESTS=YES
22+ compiler: ": #GHC 7.10.2 lts-3.6"
2323 addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
24− - env: GHCVER=7.10.2 STACKAGE=nightly-2015-08-24
25− compiler: ": #GHC 7.10.2 nightly-2015-09-09"
24+ - env: GHCVER=7.10.2 STACKAGE=nightly-2015-09-29
25+ compiler: ": #GHC 7.10.2 nightly-2015-09-29"
2626 addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
2727before_install:
2828 - unset CC
CONTRIBUTORS.md+1
@@ -53,6 +53,7 @@ This file lists the contributors to the PureScript compiler project, and the ter
5353- [@utkarshkukreti](https://github.com/utkarshkukreti) (Utkarsh Kukreti) My existing contributions and all future contributions until further notice are Copyright Utkarsh Kukreti, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
5454- [@vkorablin](https://github.com/vkorablin) (Vladimir Korablin) - My existing contributions and all future contributions until further notice are Copyright Vladimir Korablin, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
5555- [@zudov](https://github.com/zudov) (Konstantin Zudov) My existing contributions and all future contributions until further notice are Copyright Konstantin Zudov, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
56+- [@senju](https://github.com/senju) - My existing contributions and all future contributions until further notice are Copyright senju, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
5657<http://opensource.org/licenses/MIT>.
5758
5859### Companies
examples/passing/LargeSumType.pursnew file+33
@@ -0,0 +1,33 @@
1+module Main where
2+
3+data Large = A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
4+
5+explode A A = "A"
6+explode B B = "B"
7+explode C C = "C"
8+explode D D = "D"
9+explode E E = "E"
10+explode F F = "F"
11+explode G G = "G"
12+explode H H = "H"
13+explode I I = "I"
14+explode J J = "J"
15+explode K K = "K"
16+explode L L = "L"
17+explode M M = "M"
18+explode N N = "N"
19+explode O O = "O"
20+explode P P = "P"
21+explode Q Q = "Q"
22+explode R R = "R"
23+explode S S = "S"
24+explode T T = "T"
25+explode U U = "U"
26+explode V V = "V"
27+explode W W = "W"
28+explode X X = "X"
29+explode Y Y = "Y"
30+explode Z Z = "Z"
31+explode _ _ = ""
32+
33+main = Control.Monad.Eff.Console.log "Done"
examples/passing/OptionalQualified.pursnew file+13
@@ -0,0 +1,13 @@
1+module Main where
2+
3+-- qualified import with the "qualified" keyword
4+import qualified Prelude as P
5+
6+-- qualified import without the "qualified" keyword
7+import Control.Monad.Eff.Console as Console
8+
9+bind = P.bind
10+
11+main = do
12+ message <- P.return "success!"
13+ Console.log message
examples/passing/QualifiedQualifiedImports.pursnew file+6
@@ -0,0 +1,6 @@
1+module Main where
2+
3+-- qualified import with qualified imported names
4+import qualified Control.Monad.Eff.Console (log) as Console
5+
6+main = Console.log "Success!"
examples/passing/UTF8Sourcefile.pursnew file+10
@@ -0,0 +1,10 @@
1+module Main where
2+
3+import Control.Monad.Eff.Console
4+
5+-- '→' is multibyte sequence \u2192.
6+utf8multibyte = "Hello λ→ world!!"
7+
8+main = do
9+ log "done"
10+
psc/Main.hs+4−2
@@ -32,6 +32,7 @@ import Options.Applicative as Opts
3232
3333import System.Exit (exitSuccess, exitFailure)
3434import System.IO (hPutStrLn, stderr)
35+import System.IO.UTF8
3536import System.FilePath.Glob (glob)
3637
3738import qualified Language.PureScript as P
@@ -60,7 +61,7 @@ compile (PSCMakeOptions inputGlob inputForeignGlob outputDir opts usePrefix) = d
6061 let (jsFiles, pursFiles) = partition (isSuffixOf ".js") input
6162 moduleFiles <- readInput (InputOptions pursFiles)
6263 inputForeign <- globWarningOnMisses warnFileTypeNotFound inputForeignGlob
63− foreignFiles <- forM (inputForeign ++ jsFiles) (\inFile -> (inFile,) <$> readFile inFile)
64+ foreignFiles <- forM (inputForeign ++ jsFiles) (\inFile -> (inFile,) <$> readUTF8File inFile)
6465 case runWriterT (parseInputs moduleFiles foreignFiles) of
6566 Left errs -> do
6667 hPutStrLn stderr (P.prettyPrintMultipleErrors (P.optionsVerboseErrors opts) errs)
@@ -93,7 +94,7 @@ globWarningOnMisses warn = concatMapM globWithWarning
9394 concatMapM f = liftM concat . mapM f
9495
9596readInput :: InputOptions -> IO [(Either P.RebuildPolicy FilePath, String)]
96−readInput InputOptions{..} = forM ioInputFiles $ \inFile -> (Right inFile, ) <$> readFile inFile
97+readInput InputOptions{..} = forM ioInputFiles $ \inFile -> (Right inFile, ) <$> readUTF8File inFile
9798
9899parseInputs :: (Functor m, Applicative m, MonadError P.MultipleErrors m, MonadWriter P.MultipleErrors m)
99100 => [(Either P.RebuildPolicy FilePath, String)]
@@ -178,6 +179,7 @@ pscMakeOptions = PSCMakeOptions <$> many inputFile
178179 <*> options
179180 <*> (not <$> noPrefix)
180181
182+
181183main :: IO ()
182184main = execParser opts >>= compile
183185 where
purescript.cabal+2−1
@@ -58,7 +58,7 @@ library
5858 language-javascript == 0.5.*,
5959 syb -any,
6060 Glob >= 0.7 && < 0.8,
61− process >= 1.2.0 && < 1.3,
61+ process >= 1.2.0 && < 1.4,
6262 safe >= 0.3.9 && < 0.4,
6363 semigroups >= 0.16.2 && < 0.18
6464
@@ -165,6 +165,7 @@ library
165165 Control.Monad.Supply
166166 Control.Monad.Supply.Class
167167
168+ System.IO.UTF8
168169 exposed: True
169170 buildable: True
170171 hs-source-dirs: src
src/Language/PureScript/AST/Exported.hs+1−1
@@ -66,7 +66,7 @@ filterInstances (Just exps) =
6666 -- * the name is defined in a different module (and must be exported from
6767 -- that module; the code would fail to compile otherwise).
6868 visibleOutside _ (Qualified (Just _) _) = True
69− visibleOutside refs (Qualified Nothing n) = any (== n) refs
69+ visibleOutside refs (Qualified Nothing n) = n `elem` refs
7070
7171 typeName (TypeRef n _) = Just n
7272 typeName (PositionedDeclarationRef _ _ r) = typeName r
src/Language/PureScript/Bundle.hs+1−1
@@ -385,7 +385,7 @@ isModuleEmpty (Module _ els) = all isElementEmpty els
385385 where
386386 isElementEmpty :: ModuleElement -> Bool
387387 isElementEmpty (ExportsList exps) = null exps
388− isElementEmpty (Require _ _ _) = True
388+ isElementEmpty Require{} = True
389389 isElementEmpty (Other _) = True
390390 isElementEmpty _ = False
391391
src/Language/PureScript/CodeGen/JS.hs+2−1
@@ -27,6 +27,7 @@ module Language.PureScript.CodeGen.JS
2727 ) where
2828
2929import Data.List ((\\), delete, intersect)
30+import Data.Maybe (isNothing)
3031import qualified Data.Traversable as T (traverse)
3132
3233#if __GLASGOW_HASKELL__ < 710
@@ -62,7 +63,7 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign_ = do
6263 comments <- not <$> asks optionsNoComments
6364 let strict = JSStringLiteral "use strict"
6465 let header = if comments && not (null coms) then JSComment coms strict else strict
65− let foreign' = [JSVariableIntroduction "$foreign" foreign_ | not $ null foreigns || foreign_ == Nothing]
66+ let foreign' = [JSVariableIntroduction "$foreign" foreign_ | not $ null foreigns || isNothing foreign_]
6667 let moduleBody = header : foreign' ++ jsImports ++ concat optimized
6768 let foreignExps = exps `intersect` (fst `map` foreigns)
6869 let standardExps = exps \\ foreignExps
src/Language/PureScript/CodeGen/JS/Optimizer/Inliner.hs+1−1
@@ -255,7 +255,7 @@ inlineFnComposition = everywhereOnJSTopDownM convert
255255 return $ JSFunction Nothing [arg] (JSBlock [JSReturn $ JSApp x [JSApp y [JSVar arg]]])
256256 convert other = return other
257257 isFnCompose :: JS -> JS -> Bool
258− isFnCompose dict' fn = isDict semigroupoidFn dict' && (isPreludeFn (C.<<<) fn || isPreludeFn (C.compose) fn)
258+ isFnCompose dict' fn = isDict semigroupoidFn dict' && (isPreludeFn (C.<<<) fn || isPreludeFn C.compose fn)
259259
260260isDict :: (String, String) -> JS -> Bool
261261isDict (moduleName, dictName) (JSAccessor x (JSVar y)) = x == dictName && y == moduleName
src/Language/PureScript/CodeGen/JS/Optimizer/TCO.hs+1−1
@@ -124,5 +124,5 @@ tco' = everywhereOnJS convert
124124 hasFunction :: JS -> Bool
125125 hasFunction = getAny . everythingOnJS mappend (Any . isFunction)
126126 where
127− isFunction (JSFunction _ _ _) = True
127+ isFunction JSFunction{} = True
128128 isFunction _ = False
src/Language/PureScript/CodeGen/JS/Optimizer/Unused.hs+1−1
@@ -29,7 +29,7 @@ removeCodeAfterReturnStatements = everywhereOnJS (removeFromBlock go)
2929 where
3030 go :: [JS] -> [JS]
3131 go jss | not (any isJSReturn jss) = jss
32− | otherwise = let (body, ret : _) = span (not . isJSReturn) jss in body ++ [ret]
32+ | otherwise = let (body, ret : _) = break isJSReturn jss in body ++ [ret]
3333 isJSReturn (JSReturn _) = True
3434 isJSReturn _ = False
3535
src/Language/PureScript/CoreFn/Expr.hs+1−1
@@ -101,7 +101,7 @@ data CaseAlternative a = CaseAlternative
101101instance Functor CaseAlternative where
102102
103103 fmap f (CaseAlternative cabs car) = CaseAlternative
104− (fmap (fmap f) $ cabs)
104+ (fmap (fmap f) cabs)
105105 (either (Left . fmap (fmap f *** fmap f)) (Right . fmap f) car)
106106
107107-- |
src/Language/PureScript/Docs/Convert.hs+2−2
@@ -147,7 +147,7 @@ convertDeclaration (P.ExternDataDeclaration _ kind') title =
147147 basicDeclaration title (ExternDataDeclaration kind')
148148convertDeclaration (P.TypeSynonymDeclaration _ args ty) title =
149149 basicDeclaration title (TypeSynonymDeclaration args ty)
150−convertDeclaration (P.TypeClassDeclaration _ args implies ds) title = do
150+convertDeclaration (P.TypeClassDeclaration _ args implies ds) title =
151151 Just (Right (mkDeclaration title info) { declChildren = children })
152152 where
153153 info = TypeClassDeclaration args implies
@@ -158,7 +158,7 @@ convertDeclaration (P.TypeClassDeclaration _ args implies ds) title = do
158158 ChildDeclaration (P.showIdent ident') Nothing Nothing (ChildTypeClassMember ty)
159159 convertClassMember _ =
160160 error "Invalid argument to convertClassMember."
161−convertDeclaration (P.TypeInstanceDeclaration _ constraints className tys _) title = do
161+convertDeclaration (P.TypeInstanceDeclaration _ constraints className tys _) title =
162162 Just (Left (classNameString : typeNameStrings, AugmentChild childDecl))
163163 where
164164 classNameString = unQual className
src/Language/PureScript/Docs/Render.hs+3−2
@@ -10,6 +10,7 @@
1010
1111module Language.PureScript.Docs.Render where
1212
13+import Data.Maybe (maybeToList)
1314import Data.Monoid ((<>))
1415import qualified Language.PureScript as P
1516
@@ -46,7 +47,7 @@ renderDeclarationWithOptions opts Declaration{..} =
4647 ]
4748 TypeClassDeclaration args implies ->
4849 [ keywordClass ]
49− ++ maybe [] (:[]) superclasses
50+ ++ maybeToList superclasses
5051 ++ [renderType' (typeApp declTitle args)]
5152 ++ if any (isTypeClassMember . cdeclInfo) declChildren
5253 then [keywordWhere]
@@ -75,7 +76,7 @@ renderChildDeclarationWithOptions opts ChildDeclaration{..} =
7576 [ keywordInstance
7677 , ident cdeclTitle
7778 , syntax "::"
78− ] ++ maybe [] (:[]) (renderConstraints constraints)
79+ ] ++ maybeToList (renderConstraints constraints)
7980 ++ [ renderType' ty ]
8081 ChildDataConstructor args ->
8182 [ renderType' typeApp' ]
src/Language/PureScript/Docs/Types.hs+1−1
@@ -425,7 +425,7 @@ asSourceSpan = P.SourceSpan <$> key "name" asString
425425
426426instance A.ToJSON a => A.ToJSON (Package a) where
427427 toJSON Package{..} =
428− A.object $
428+ A.object
429429 [ "packageMeta" .= pkgMeta
430430 , "version" .= showVersion pkgVersion
431431 , "versionTag" .= pkgVersionTag
src/Language/PureScript/Errors.hs+43−34
@@ -20,7 +20,7 @@
2020module Language.PureScript.Errors where
2121
2222import Data.Either (lefts, rights)
23−import Data.List (intercalate, transpose)
23+import Data.List (intercalate, transpose, nub)
2424import Data.Function (on)
2525#if __GLASGOW_HASKELL__ < 710
2626import Data.Foldable (fold, foldMap)
@@ -52,7 +52,6 @@ import qualified Text.PrettyPrint.Boxes as Box
5252import qualified Text.Parsec as P
5353import qualified Text.Parsec.Error as PE
5454import Text.Parsec.Error (Message(..))
55−import Data.List (nub)
5655
5756-- |
5857-- A type of error messages
@@ -100,6 +99,7 @@ data SimpleErrorMessage
10099 | CtorConflictsWithClass ProperName
101100 | ClassConflictsWithType ProperName
102101 | ClassConflictsWithCtor ProperName
102+ | DuplicateModuleName ModuleName
103103 | DuplicateClassExport ProperName
104104 | DuplicateValueExport Ident
105105 | DuplicateTypeArgument String
@@ -145,6 +145,7 @@ data SimpleErrorMessage
145145 | WildcardInferredType Type
146146 | NotExhaustivePattern [[Binder]] Bool
147147 | OverlappingPattern [[Binder]] Bool
148+ | IncompleteExhaustivityCheck
148149 | ClassOperator ProperName Ident
149150 | MisleadingEmptyTypeImport ModuleName ProperName
150151 | ImportHidingModule ModuleName
@@ -229,6 +230,7 @@ errorCode em = case unwrapErrorMessage em of
229230 CtorConflictsWithClass{} -> "CtorConflictsWithClass"
230231 ClassConflictsWithType{} -> "ClassConflictsWithType"
231232 ClassConflictsWithCtor{} -> "ClassConflictsWithCtor"
233+ DuplicateModuleName{} -> "DuplicateModuleName"
232234 DuplicateClassExport{} -> "DuplicateClassExport"
233235 DuplicateValueExport{} -> "DuplicateValueExport"
234236 DuplicateTypeArgument{} -> "DuplicateTypeArgument"
@@ -274,6 +276,7 @@ errorCode em = case unwrapErrorMessage em of
274276 WildcardInferredType{} -> "WildcardInferredType"
275277 NotExhaustivePattern{} -> "NotExhaustivePattern"
276278 OverlappingPattern{} -> "OverlappingPattern"
279+ IncompleteExhaustivityCheck{} -> "IncompleteExhaustivityCheck"
277280 ClassOperator{} -> "ClassOperator"
278281 MisleadingEmptyTypeImport{} -> "MisleadingEmptyTypeImport"
279282 ImportHidingModule{} -> "ImportHidingModule"
@@ -364,33 +367,33 @@ replaceUnknowns = everywhereOnTypesM replaceTypes
364367onTypesInErrorMessageM :: (Applicative m) => (Type -> m Type) -> ErrorMessage -> m ErrorMessage
365368onTypesInErrorMessageM f = g
366369 where
367− gSimple (InfiniteType t) = InfiniteType <$> (f t)
368− gSimple (TypesDoNotUnify t1 t2) = TypesDoNotUnify <$> (f t1) <*> (f t2)
369− gSimple (ConstrainedTypeUnified t1 t2) = ConstrainedTypeUnified <$> (f t1) <*> (f t2)
370− gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> (f t)
371− gSimple (PropertyIsMissing s t) = PropertyIsMissing s <$> (f t)
372− gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> (pure e)
370+ gSimple (InfiniteType t) = InfiniteType <$> f t
371+ gSimple (TypesDoNotUnify t1 t2) = TypesDoNotUnify <$> f t1 <*> f t2
372+ gSimple (ConstrainedTypeUnified t1 t2) = ConstrainedTypeUnified <$> f t1 <*> f t2
373+ gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> f t
374+ gSimple (PropertyIsMissing s t) = PropertyIsMissing s <$> f t
375+ gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> pure e
373376 gSimple (InvalidInstanceHead t) = InvalidInstanceHead <$> f t
374377 gSimple other = pure other
375− g (ErrorInSubsumption t1 t2 em) = ErrorInSubsumption <$> (f t1) <*> (f t2) <*> (g em)
376− g (ErrorUnifyingTypes t1 t2 e) = ErrorUnifyingTypes <$> (f t1) <*> (f t2) <*> (g e)
377− g (ErrorCheckingType e t em) = ErrorCheckingType e <$> (f t) <*> (g em)
378− g (ErrorCheckingKind t em) = ErrorCheckingKind <$> (f t) <*> g em
379− g (ErrorInApplication e1 t1 e2 em) = ErrorInApplication e1 <$> (f t1) <*> (pure e2) <*> (g em)
380− g (NotYetDefined x e) = NotYetDefined x <$> (g e)
381− g (ErrorInExpression x e) = ErrorInExpression x <$> (g e)
382− g (ErrorInModule x e) = ErrorInModule x <$> (g e)
383− g (ErrorInInstance x y e) = ErrorInInstance x y <$> (g e)
384− g (ErrorInferringType x e) = ErrorInferringType x <$> (g e)
385− g (ErrorInDataConstructor x e) = ErrorInDataConstructor x <$> (g e)
386− g (ErrorInTypeConstructor x e) = ErrorInTypeConstructor x <$> (g e)
387− g (ErrorInBindingGroup x e) = ErrorInBindingGroup x <$> (g e)
388− g (ErrorInDataBindingGroup e) = ErrorInDataBindingGroup <$> (g e)
389− g (ErrorInTypeSynonym x e) = ErrorInTypeSynonym x <$> (g e)
390− g (ErrorInValueDeclaration x e) = ErrorInValueDeclaration x <$> (g e)
391− g (ErrorInTypeDeclaration x e) = ErrorInTypeDeclaration x <$> (g e)
392− g (ErrorInForeignImport x e) = ErrorInForeignImport x <$> (g e)
393− g (PositionedError x e) = PositionedError x <$> (g e)
378+ g (ErrorInSubsumption t1 t2 em) = ErrorInSubsumption <$> f t1 <*> f t2 <*> g em
379+ g (ErrorUnifyingTypes t1 t2 e) = ErrorUnifyingTypes <$> f t1 <*> f t2 <*> g e
380+ g (ErrorCheckingType e t em) = ErrorCheckingType e <$> f t <*> g em
381+ g (ErrorCheckingKind t em) = ErrorCheckingKind <$> f t <*> g em
382+ g (ErrorInApplication e1 t1 e2 em) = ErrorInApplication e1 <$> f t1 <*> pure e2 <*> g em
383+ g (NotYetDefined x e) = NotYetDefined x <$> g e
384+ g (ErrorInExpression x e) = ErrorInExpression x <$> g e
385+ g (ErrorInModule x e) = ErrorInModule x <$> g e
386+ g (ErrorInInstance x y e) = ErrorInInstance x y <$> g e
387+ g (ErrorInferringType x e) = ErrorInferringType x <$> g e
388+ g (ErrorInDataConstructor x e) = ErrorInDataConstructor x <$> g e
389+ g (ErrorInTypeConstructor x e) = ErrorInTypeConstructor x <$> g e
390+ g (ErrorInBindingGroup x e) = ErrorInBindingGroup x <$> g e
391+ g (ErrorInDataBindingGroup e) = ErrorInDataBindingGroup <$> g e
392+ g (ErrorInTypeSynonym x e) = ErrorInTypeSynonym x <$> g e
393+ g (ErrorInValueDeclaration x e) = ErrorInValueDeclaration x <$> g e
394+ g (ErrorInTypeDeclaration x e) = ErrorInTypeDeclaration x <$> g e
395+ g (ErrorInForeignImport x e) = ErrorInForeignImport x <$> g e
396+ g (PositionedError x e) = PositionedError x <$> g e
394397 g (SimpleErrorWrapper sem) = SimpleErrorWrapper <$> gSimple sem
395398
396399-- |
@@ -524,6 +527,8 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
524527 line $ "Type class " ++ runProperName nm ++ " conflicts with type declaration of the same name"
525528 goSimple (ClassConflictsWithCtor nm) =
526529 line $ "Type class " ++ runProperName nm ++ " conflicts with data constructor declaration of the same name"
530+ goSimple (DuplicateModuleName mn) =
531+ line $ "Module " ++ runModuleName mn ++ " has been defined multiple times."
527532 goSimple (DuplicateClassExport nm) =
528533 line $ "Duplicate export declaration for type class " ++ runProperName nm
529534 goSimple (DuplicateValueExport nm) =
@@ -662,6 +667,10 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
662667 , Box.hsep 1 Box.left (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs))
663668 ] ++
664669 [ line "..." | not b ]
670+ goSimple IncompleteExhaustivityCheck =
671+ paras [ line "An exhaustivity check was abandoned due to too many possible cases."
672+ , line "You may want to decomposing your data types into smaller types."
673+ ]
665674 go (NotYetDefined names err) =
666675 paras [ line $ "The following are not yet defined here: " ++ intercalate ", " (map showIdent names) ++ ":"
667676 , indent $ go err
@@ -732,7 +741,7 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
732741 , go err
733742 ]
734743 go (ErrorInDataBindingGroup err) =
735− paras [ lineWithLevel $ "in data binding group:"
744+ paras [ lineWithLevel "in data binding group:"
736745 , go err
737746 ]
738747 go (ErrorInTypeSynonym name err) =
@@ -851,7 +860,7 @@ prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
851860 , result
852861 ]
853862prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) = do
854− result <- forM es $ (liftM $ Box.moveRight 2) . prettyPrintSingleError full level
863+ result <- forM es $ liftM (Box.moveRight 2) . prettyPrintSingleError full level
855864 return $
856865 Box.vcat Box.left [ Box.text intro
857866 , Box.vsep 1 Box.left result
@@ -859,7 +868,7 @@ prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) = do
859868
860869-- | Pretty print a Parsec ParseError as a Box
861870prettyPrintParseError :: P.ParseError -> Box.Box
862−prettyPrintParseError = (prettyPrintParseErrorMessages "or" "unknown parse error" "expecting" "unexpected" "end of input") . PE.errorMessages
871+prettyPrintParseError = prettyPrintParseErrorMessages "or" "unknown parse error" "expecting" "unexpected" "end of input" . PE.errorMessages
863872
864873-- |
865874-- Pretty print ParseError detail messages.
@@ -872,9 +881,9 @@ prettyPrintParseErrorMessages msgOr msgUnknown msgExpecting msgUnExpected msgEnd
872881 | otherwise = Box.vcat Box.left $ map Box.text $ clean [showSysUnExpect,showUnExpect,showExpect,showMessages]
873882
874883 where
875− (sysUnExpect,msgs1) = span ((SysUnExpect "") ==) msgs
876− (unExpect,msgs2) = span ((UnExpect "") ==) msgs1
877− (expect,messages) = span ((Expect "") ==) msgs2
884+ (sysUnExpect,msgs1) = span (SysUnExpect "" ==) msgs
885+ (unExpect,msgs2) = span (UnExpect "" ==) msgs1
886+ (expect,messages) = span (Expect "" ==) msgs2
878887
879888 showExpect = showMany msgExpecting expect
880889 showUnExpect = showMany msgUnExpected unExpect
@@ -922,7 +931,7 @@ renderBox = unlines . map trimEnd . lines . Box.render
922931interpretMultipleErrorsAndWarnings :: (MonadError MultipleErrors m, MonadWriter MultipleErrors m) => (Either MultipleErrors a, MultipleErrors) -> m a
923932interpretMultipleErrorsAndWarnings (err, ws) = do
924933 tell ws
925− either throwError return $ err
934+ either throwError return err
926935
927936-- |
928937-- Rethrow an error with a more detailed error message in the case of failure
src/Language/PureScript/Linter/Exhaustive.hs+46−28
@@ -29,6 +29,9 @@ import qualified Data.Map as M
2929import Data.Maybe (fromMaybe)
3030import Data.List (foldl', sortBy, nub)
3131import Data.Function (on)
32+#if __GLASGOW_HASKELL__ < 710
33+import Data.Traversable (sequenceA)
34+#endif
3235
3336import Control.Monad (unless)
3437import Control.Applicative
@@ -45,6 +48,14 @@ import Language.PureScript.Errors
4548
4649import Language.PureScript.AST.Traversals (everywhereOnValuesTopDownM)
4750
51+-- | There are two modes of failure for the redudancy check:
52+--
53+-- 1. Exhaustivity was incomeplete due to too many cases, so we couldn't determine redundancy.
54+-- 2. We didn't attempt to determine redundancy for a binder, e.g. an integer binder.
55+--
56+-- We want to warn the user in the first case.
57+data RedudancyError = Incomplete | Unknown
58+
4859-- |
4960-- Qualifies a propername from a given qualified propername and a default module name
5061--
@@ -59,20 +70,20 @@ qualifyName n defmn qn = Qualified (Just mn) n
5970-- where: - ProperName is the name of the constructor (for example, "Nothing" in Maybe)
6071-- - [Type] is the list of arguments, if it has (for example, "Just" has [TypeVar "a"])
6172--
62−getConstructors :: Environment -> ModuleName -> (Qualified ProperName) -> [(ProperName, [Type])]
73+getConstructors :: Environment -> ModuleName -> Qualified ProperName -> [(ProperName, [Type])]
6374getConstructors env defmn n = extractConstructors lnte
6475 where
6576 qpn :: Qualified ProperName
6677 qpn = getConsDataName n
6778
68− getConsDataName :: (Qualified ProperName) -> (Qualified ProperName)
79+ getConsDataName :: Qualified ProperName -> Qualified ProperName
6980 getConsDataName con = qualifyName nm defmn con
7081 where
7182 nm = case getConsInfo con of
7283 Nothing -> error $ "Constructor " ++ showQualified runProperName con ++ " not in the scope of the current environment in getConsDataName."
7384 Just (_, pm, _, _) -> pm
7485
75− getConsInfo :: (Qualified ProperName) -> Maybe (DataDeclType, ProperName, Type, [Ident])
86+ getConsInfo :: Qualified ProperName -> Maybe (DataDeclType, ProperName, Type, [Ident])
7687 getConsInfo con = M.lookup con dce
7788 where
7889 dce :: M.Map (Qualified ProperName) (DataDeclType, ProperName, Type, [Ident])
@@ -103,27 +114,27 @@ genericMerge _ [] [] = []
103114genericMerge f bs [] = map (\(s, b) -> f s (Just b) Nothing) bs
104115genericMerge f [] bs = map (\(s, b) -> f s Nothing (Just b)) bs
105116genericMerge f bsl@((s, b):bs) bsr@((s', b'):bs')
106− | s < s' = (f s (Just b) Nothing) : genericMerge f bs bsr
107− | s > s' = (f s' Nothing (Just b')) : genericMerge f bsl bs'
108− | otherwise = (f s (Just b) (Just b')) : genericMerge f bs bs'
117+ | s < s' = f s (Just b) Nothing : genericMerge f bs bsr
118+ | s > s' = f s' Nothing (Just b') : genericMerge f bsl bs'
119+ | otherwise = f s (Just b) (Just b') : genericMerge f bs bs'
109120
110121-- |
111122-- Find the uncovered set between two binders:
112123-- the first binder is the case we are trying to cover, the second one is the matching binder
113124--
114−missingCasesSingle :: Environment -> ModuleName -> Binder -> Binder -> ([Binder], Maybe Bool)
115−missingCasesSingle _ _ _ NullBinder = ([], Just True)
116−missingCasesSingle _ _ _ (VarBinder _) = ([], Just True)
125+missingCasesSingle :: Environment -> ModuleName -> Binder -> Binder -> ([Binder], Either RedudancyError Bool)
126+missingCasesSingle _ _ _ NullBinder = ([], return True)
127+missingCasesSingle _ _ _ (VarBinder _) = ([], return True)
117128missingCasesSingle env mn (VarBinder _) b = missingCasesSingle env mn NullBinder b
118129missingCasesSingle env mn br (NamedBinder _ bl) = missingCasesSingle env mn br bl
119130missingCasesSingle env mn NullBinder cb@(ConstructorBinder con _) =
120− (concatMap (\cp -> fst $ missingCasesSingle env mn cp cb) allPatterns, Just True)
131+ (concatMap (\cp -> fst $ missingCasesSingle env mn cp cb) allPatterns, return True)
121132 where
122133 allPatterns = map (\(p, t) -> ConstructorBinder (qualifyName p mn con) (initialize $ length t))
123134 $ getConstructors env mn con
124135missingCasesSingle env mn cb@(ConstructorBinder con bs) (ConstructorBinder con' bs')
125136 | con == con' = let (bs'', pr) = missingCasesMultiple env mn bs bs' in (map (ConstructorBinder con) bs'', pr)
126− | otherwise = ([cb], Just False)
137+ | otherwise = ([cb], return False)
127138missingCasesSingle env mn NullBinder (ObjectBinder bs) =
128139 (map (ObjectBinder . zip (map fst bs)) allMisses, pr)
129140 where
@@ -146,12 +157,12 @@ missingCasesSingle env mn (ObjectBinder bs) (ObjectBinder bs') =
146157 compBS e s b b' = (s, compB e b b')
147158
148159 (sortedNames, binders) = unzip $ genericMerge (compBS NullBinder) sbs sbs'
149−missingCasesSingle _ _ NullBinder (BooleanBinder b) = ([BooleanBinder $ not b], Just True)
160+missingCasesSingle _ _ NullBinder (BooleanBinder b) = ([BooleanBinder $ not b], return True)
150161missingCasesSingle _ _ (BooleanBinder bl) (BooleanBinder br)
151− | bl == br = ([], Just True)
152− | otherwise = ([BooleanBinder bl], Just False)
162+ | bl == br = ([], return True)
163+ | otherwise = ([BooleanBinder bl], return False)
153164missingCasesSingle env mn b (PositionedBinder _ _ cb) = missingCasesSingle env mn b cb
154−missingCasesSingle _ _ b _ = ([b], Nothing)
165+missingCasesSingle _ _ b _ = ([b], Left Unknown)
155166
156167-- |
157168-- Returns the uncovered set of binders
@@ -179,7 +190,7 @@ missingCasesSingle _ _ b _ = ([b], Nothing)
179190-- redundant or not, but uncovered at least. If we use `y` instead, we'll need to have a redundancy checker
180191-- (which ought to be available soon), or increase the complexity of the algorithm.
181192--
182−missingCasesMultiple :: Environment -> ModuleName -> [Binder] -> [Binder] -> ([[Binder]], Maybe Bool)
193+missingCasesMultiple :: Environment -> ModuleName -> [Binder] -> [Binder] -> ([[Binder]], Either RedudancyError Bool)
183194missingCasesMultiple env mn = go
184195 where
185196 go [] [] = ([], pure True)
@@ -213,10 +224,10 @@ isExhaustiveGuard (Right _) = True
213224-- |
214225-- Returns the uncovered set of case alternatives
215226--
216−missingCases :: Environment -> ModuleName -> [Binder] -> CaseAlternative -> ([[Binder]], Maybe Bool)
227+missingCases :: Environment -> ModuleName -> [Binder] -> CaseAlternative -> ([[Binder]], Either RedudancyError Bool)
217228missingCases env mn uncovered ca = missingCasesMultiple env mn uncovered (caseAlternativeBinders ca)
218229
219−missingAlternative :: Environment -> ModuleName -> CaseAlternative -> [Binder] -> ([[Binder]], Maybe Bool)
230+missingAlternative :: Environment -> ModuleName -> CaseAlternative -> [Binder] -> ([[Binder]], Either RedudancyError Bool)
220231missingAlternative env mn ca uncovered
221232 | isExhaustiveGuard (caseAlternativeResult ca) = mcases
222233 | otherwise = ([uncovered], snd mcases)
@@ -232,24 +243,31 @@ missingAlternative env mn ca uncovered
232243checkExhaustive :: forall m. (MonadWriter MultipleErrors m) => Environment -> ModuleName -> Int -> [CaseAlternative] -> m ()
233244checkExhaustive env mn numArgs cas = makeResult . first nub $ foldl' step ([initialize numArgs], (pure True, [])) cas
234245 where
235− step :: ([[Binder]], (Maybe Bool, [[Binder]])) -> CaseAlternative -> ([[Binder]], (Maybe Bool, [[Binder]]))
246+ step :: ([[Binder]], (Either RedudancyError Bool, [[Binder]])) -> CaseAlternative -> ([[Binder]], (Either RedudancyError Bool, [[Binder]]))
236247 step (uncovered, (nec, redundant)) ca =
237248 let (missed, pr) = unzip (map (missingAlternative env mn ca) uncovered)
238− cond = or <$> sequenceA pr
239− in (concat missed, (liftA2 (&&) cond nec,
240− if fromMaybe True cond then redundant else caseAlternativeBinders ca : redundant))
241−#if __GLASGOW_HASKELL__ < 710
242− where
243− sequenceA = foldr (liftA2 (:)) (pure [])
244−#endif
249+ (missed', approx) = splitAt 10000 (concat missed)
250+ cond = liftA2 (&&) (or <$> sequenceA pr) nec
251+ in (missed', ( if null approx
252+ then cond
253+ else Left Incomplete
254+ , if either (const True) id cond
255+ then redundant
256+ else caseAlternativeBinders ca : redundant
257+ )
258+ )
245259
246− makeResult :: ([[Binder]], (Maybe Bool, [[Binder]])) -> m ()
247− makeResult (bss, (_, bss')) =
260+ makeResult :: ([[Binder]], (Either RedudancyError Bool, [[Binder]])) -> m ()
261+ makeResult (bss, (rr, bss')) =
248262 do unless (null bss) tellExhaustive
249263 unless (null bss') tellRedundant
264+ case rr of
265+ Left Incomplete -> tellIncomplete
266+ _ -> return ()
250267 where
251268 tellExhaustive = tell . errorMessage . uncurry NotExhaustivePattern . second null . splitAt 5 $ bss
252269 tellRedundant = tell . errorMessage . uncurry OverlappingPattern . second null . splitAt 5 $ bss'
270+ tellIncomplete = tell . errorMessage $ IncompleteExhaustivityCheck
253271
254272-- |
255273-- Exhaustivity checking over a list of declarations
src/Language/PureScript/Make.hs+48−24
@@ -52,7 +52,7 @@ import Control.Monad.Trans.Control (MonadBaseControl(..))
5252
5353import Control.Concurrent.Lifted as C
5454
55−import Data.List (foldl')
55+import Data.List (foldl', sort)
5656import Data.Maybe (fromMaybe, catMaybes)
5757import Data.Time.Clock
5858import Data.String (fromString)
@@ -159,6 +159,8 @@ make :: forall m. (Functor m, Applicative m, Monad m, MonadBaseControl IO m, Mon
159159 -> [Module]
160160 -> m Environment
161161make MakeActions{..} ms = do
162+ checkModuleNamesAreUnique
163+
162164 (sorted, graph) <- sortModules ms
163165
164166 barriers <- zip (map getModuleName sorted) <$> replicateM (length ms) ((,) <$> C.newEmptyMVar <*> C.newEmptyMVar)
@@ -178,12 +180,32 @@ make MakeActions{..} ms = do
178180 return $ foldl' (flip applyExternsFileToEnvironment) initEnvironment (fromMaybe (error "make: externs were missing but no errors reported.") externs)
179181
180182 where
183+ checkModuleNamesAreUnique :: m ()
184+ checkModuleNamesAreUnique =
185+ case findDuplicate (map getModuleName ms) of
186+ Nothing -> return ()
187+ Just mn -> throwError . errorMessage $ DuplicateModuleName mn
188+
189+ -- Verify that a list of values has unique keys
190+ findDuplicate :: (Ord a) => [a] -> Maybe a
191+ findDuplicate = go . sort
192+ where
193+ go (x : y : xs)
194+ | x == y = Just x
195+ | otherwise = go (y : xs)
196+ go _ = Nothing
197+
181198 -- Sort a list so its elements appear in the same order as in another list.
182199 inOrderOf :: (Ord a) => [a] -> [a] -> [a]
183200 inOrderOf xs ys = let s = S.fromList xs in filter (`S.member` s) ys
184201
185202 buildModule :: [(ModuleName, (C.MVar (Maybe ExternsFile), C.MVar (Maybe MultipleErrors)))] -> Module -> [ModuleName] -> m ()
186203 buildModule barriers m@(Module _ _ moduleName _ _) deps = flip catchError (markComplete Nothing . Just) $ do
204+ -- We need to wait for dependencies to be built, before checking if the current
205+ -- module should be rebuilt, so the first thing to do is to wait on the
206+ -- MVars for the module's dependencies.
207+ mexterns <- sequence <$> mapM (readMVar . fst . fromMaybe (error "make: no barrier") . flip lookup barriers) deps
208+
187209 outputTimestamp <- getOutputTimestamp moduleName
188210 dependencyTimestamp <- maximumMaybe <$> mapM (fmap shouldExist . getOutputTimestamp) deps
189211 inputTimestamp <- getInputTimestamp moduleName
@@ -194,29 +216,31 @@ make MakeActions{..} ms = do
194216 (Left RebuildNever, _, Just _) -> False
195217 _ -> True
196218
197− exts <- if shouldRebuild
198− then do
199− mexterns <- sequence <$> mapM (readMVar . fst . fromMaybe (error "make: no barrier") . flip lookup barriers) deps
200−
201− for mexterns $ \externs -> do
202− progress $ CompilingModule moduleName
203− let env = foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
204− lint m
205− ([desugared], nextVar) <- runSupplyT 0 $ desugar externs [m]
206− (checked@(Module ss coms _ elaborated exps), env') <- runCheck' env $ typeCheckModule desugared
207− checkExhaustiveModule env' checked
208− regrouped <- createBindingGroups moduleName . collapseBindingGroups $ elaborated
209− let mod' = Module ss coms moduleName regrouped exps
210− corefn = CF.moduleToCoreFn env' mod'
211− [renamed] = renameInModules [corefn]
212− exts = moduleToExternsFile mod' env'
213− evalSupplyT nextVar $ codegen renamed env' $ encode exts
214− return exts
215− else do
216− mexts <- decodeExterns . snd <$> readExterns moduleName
217− return $ Just $ fromMaybe (error "make: externs files are out of date. Try 'rm output/*/externs.json'.") mexts
218−
219− markComplete exts Nothing
219+ let rebuild =
220+ case mexterns of
221+ Just externs -> do
222+ progress $ CompilingModule moduleName
223+ let env = foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
224+ lint m
225+ ([desugared], nextVar) <- runSupplyT 0 $ desugar externs [m]
226+ (checked@(Module ss coms _ elaborated exps), env') <- runCheck' env $ typeCheckModule desugared
227+ checkExhaustiveModule env' checked
228+ regrouped <- createBindingGroups moduleName . collapseBindingGroups $ elaborated
229+ let mod' = Module ss coms moduleName regrouped exps
230+ corefn = CF.moduleToCoreFn env' mod'
231+ [renamed] = renameInModules [corefn]
232+ exts = moduleToExternsFile mod' env'
233+ evalSupplyT nextVar $ codegen renamed env' $ encode exts
234+ markComplete (Just exts) Nothing
235+ Nothing -> markComplete Nothing Nothing
236+
237+ if shouldRebuild
238+ then rebuild
239+ else do
240+ mexts <- decodeExterns . snd <$> readExterns moduleName
241+ case mexts of
242+ Just exts -> markComplete (Just exts) Nothing
243+ Nothing -> rebuild
220244 where
221245 markComplete :: Maybe ExternsFile -> Maybe MultipleErrors -> m ()
222246 markComplete externs errors = do
src/Language/PureScript/Parser/Declarations.hs+25−27
@@ -151,33 +151,34 @@ parseImportDeclaration' = do
151151 where
152152 stdImport = do
153153 moduleName' <- moduleName
154− stdImportHiding moduleName' <|> stdImportQualifying moduleName'
154+ suffixHiding moduleName' <|> suffixQualifyingList moduleName'
155155 where
156− stdImportHiding mn = do
156+ suffixHiding mn = do
157157 reserved "hiding"
158− declType <- importDeclarationType Hiding
159− return (mn, declType, Nothing)
160− stdImportQualifying mn = do
161− declType <- importDeclarationType Explicit
158+ declType <- qualifyingList Hiding
162159 return (mn, declType, Nothing)
160+ suffixQualifyingList mn = do
161+ declType <- qualifyingList Explicit
162+ qName <- P.optionMaybe qualifiedName
163+ return (mn, declType, qName)
164+ qualifiedName = reserved "as" *> moduleName
163165 qualImport = do
164166 reserved "qualified"
165167 indented
166168 moduleName' <- moduleName
167− declType <- importDeclarationType Explicit
168− reserved "as"
169− asQ <- moduleName
170− return (moduleName', declType, Just asQ)
171− importDeclarationType expectedType = do
169+ declType <- qualifyingList Explicit
170+ qName <- qualifiedName
171+ return (moduleName', declType, Just qName)
172+ qualifyingList expectedType = do
172173 idents <- P.optionMaybe $ indented *> parens (commaSep parseDeclarationRef)
173174 return $ fromMaybe Implicit (expectedType <$> idents)
174175
175176
176177parseDeclarationRef :: TokenParser DeclarationRef
177178parseDeclarationRef =
178− parseModuleRef <|> (
179− withSourceSpan PositionedDeclarationRef $
180− ValueRef <$> parseIdent
179+ parseModuleRef <|>
180+ withSourceSpan PositionedDeclarationRef
181+ (ValueRef <$> parseIdent
181182 <|> do name <- properName
182183 dctors <- P.optionMaybe $ parens (symbol' ".." *> pure Nothing <|> Just <$> commaSep properName)
183184 return $ maybe (TypeClassRef name) (TypeRef name) dctors
@@ -203,8 +204,8 @@ parseTypeClassDeclaration = do
203204 mark (P.many (same *> positioned parseTypeDeclaration))
204205 return $ TypeClassDeclaration className idents implies members
205206
206−parseTypeInstanceDeclaration :: TokenParser Declaration
207−parseTypeInstanceDeclaration = do
207+parseInstanceDeclaration :: TokenParser (TypeInstanceBody -> Declaration)
208+parseInstanceDeclaration = do
208209 reserved "instance"
209210 name <- parseIdent <* indented <* doubleColon
210211 deps <- P.optionMaybe $ do
@@ -214,24 +215,21 @@ parseTypeInstanceDeclaration = do
214215 return deps
215216 className <- indented *> parseQualified properName
216217 ty <- P.many (indented *> noWildcards parseTypeAtom)
218+ return $ TypeInstanceDeclaration name (fromMaybe [] deps) className ty
219+
220+parseTypeInstanceDeclaration :: TokenParser Declaration
221+parseTypeInstanceDeclaration = do
222+ instanceDecl <- parseInstanceDeclaration
217223 members <- P.option [] . P.try $ do
218224 indented *> reserved "where"
219225 mark (P.many (same *> positioned parseValueDeclaration))
220− return $ TypeInstanceDeclaration name (fromMaybe [] deps) className ty (ExplicitInstance members)
226+ return $ instanceDecl (ExplicitInstance members)
221227
222228parseDerivingInstanceDeclaration :: TokenParser Declaration
223229parseDerivingInstanceDeclaration = do
224230 reserved "derive"
225− reserved "instance"
226− name <- parseIdent <* indented <* doubleColon
227− deps <- P.optionMaybe $ do
228− deps <- parens (commaSep1 ((,) <$> parseQualified properName <*> P.many (noWildcards parseTypeAtom)))
229− indented
230− rfatArrow
231− return deps
232− className <- indented *> parseQualified properName
233− ty <- P.many (indented *> noWildcards parseTypeAtom)
234− return $ TypeInstanceDeclaration name (fromMaybe [] deps) className ty DerivedInstance
231+ instanceDecl <- parseInstanceDeclaration
232+ return $ instanceDecl DerivedInstance
235233
236234positioned :: TokenParser Declaration -> TokenParser Declaration
237235positioned = withSourceSpan PositionedDeclaration
src/Language/PureScript/Parser/Kinds.hs+1−1
@@ -46,4 +46,4 @@ parseKind :: TokenParser Kind
4646parseKind = P.buildExpressionParser operators parseTypeAtom P.<?> "kind"
4747 where
4848 operators = [ [ P.Prefix (symbol' "#" >> return Row) ]
49− , [ P.Infix ((P.try rarrow) >> return FunKind) P.AssocRight ] ]
49+ , [ P.Infix (P.try rarrow >> return FunKind) P.AssocRight ] ]
src/Language/PureScript/Parser/Lexer.hs+1−1
@@ -479,7 +479,7 @@ identifier = token go P.<?> "identifier"
479479 go _ = Nothing
480480
481481validModuleName :: String -> Bool
482−validModuleName s = not ('_' `elem` s)
482+validModuleName s = '_' `notElem` s
483483
484484-- |
485485-- A list of purescript reserved identifiers
src/Language/PureScript/Pretty/JS.hs+13−13
@@ -45,13 +45,13 @@ literals = mkPattern' match
4545 match (JSStringLiteral s) = return $ string s
4646 match (JSBooleanLiteral True) = return "true"
4747 match (JSBooleanLiteral False) = return "false"
48− match (JSArrayLiteral xs) = fmap concat $ sequence
48+ match (JSArrayLiteral xs) = concat <$> sequence
4949 [ return "[ "
50− , fmap (intercalate ", ") $ forM xs prettyPrintJS'
50+ , intercalate ", " <$> forM xs prettyPrintJS'
5151 , return " ]"
5252 ]
5353 match (JSObjectLiteral []) = return "{}"
54− match (JSObjectLiteral ps) = fmap concat $ sequence
54+ match (JSObjectLiteral ps) = concat <$> sequence
5555 [ return "{\n"
5656 , withIndent $ do
5757 jss <- forM ps $ \(key, value) -> fmap ((objectPropertyToString key ++ ": ") ++) . prettyPrintJS' $ value
@@ -65,7 +65,7 @@ literals = mkPattern' match
6565 objectPropertyToString :: String -> String
6666 objectPropertyToString s | identNeedsEscaping s = show s
6767 | otherwise = s
68− match (JSBlock sts) = fmap concat $ sequence
68+ match (JSBlock sts) = concat <$> sequence
6969 [ return "{\n"
7070 , withIndent $ prettyStatements sts
7171 , return "\n"
@@ -73,23 +73,23 @@ literals = mkPattern' match
7373 , return "}"
7474 ]
7575 match (JSVar ident) = return ident
76− match (JSVariableIntroduction ident value) = fmap concat $ sequence
76+ match (JSVariableIntroduction ident value) = concat <$> sequence
7777 [ return "var "
7878 , return ident
7979 , maybe (return "") (fmap (" = " ++) . prettyPrintJS') value
8080 ]
81− match (JSAssignment target value) = fmap concat $ sequence
81+ match (JSAssignment target value) = concat <$> sequence
8282 [ prettyPrintJS' target
8383 , return " = "
8484 , prettyPrintJS' value
8585 ]
86− match (JSWhile cond sts) = fmap concat $ sequence
86+ match (JSWhile cond sts) = concat <$> sequence
8787 [ return "while ("
8888 , prettyPrintJS' cond
8989 , return ") "
9090 , prettyPrintJS' sts
9191 ]
92− match (JSFor ident start end sts) = fmap concat $ sequence
92+ match (JSFor ident start end sts) = concat <$> sequence
9393 [ return $ "for (var " ++ ident ++ " = "
9494 , prettyPrintJS' start
9595 , return $ "; " ++ ident ++ " < "
@@ -97,30 +97,30 @@ literals = mkPattern' match
9797 , return $ "; " ++ ident ++ "++) "
9898 , prettyPrintJS' sts
9999 ]
100− match (JSForIn ident obj sts) = fmap concat $ sequence
100+ match (JSForIn ident obj sts) = concat <$> sequence
101101 [ return $ "for (var " ++ ident ++ " in "
102102 , prettyPrintJS' obj
103103 , return ") "
104104 , prettyPrintJS' sts
105105 ]
106− match (JSIfElse cond thens elses) = fmap concat $ sequence
106+ match (JSIfElse cond thens elses) = concat <$> sequence
107107 [ return "if ("
108108 , prettyPrintJS' cond
109109 , return ") "
110110 , prettyPrintJS' thens
111111 , maybe (return "") (fmap (" else " ++) . prettyPrintJS') elses
112112 ]
113− match (JSReturn value) = fmap concat $ sequence
113+ match (JSReturn value) = concat <$> sequence
114114 [ return "return "
115115 , prettyPrintJS' value
116116 ]
117− match (JSThrow value) = fmap concat $ sequence
117+ match (JSThrow value) = concat <$> sequence
118118 [ return "throw "
119119 , prettyPrintJS' value
120120 ]
121121 match (JSBreak lbl) = return $ "break " ++ lbl
122122 match (JSContinue lbl) = return $ "continue " ++ lbl
123− match (JSLabel lbl js) = fmap concat $ sequence
123+ match (JSLabel lbl js) = concat <$> sequence
124124 [ return $ lbl ++ ": "
125125 , prettyPrintJS' js
126126 ]
src/Language/PureScript/Publish.hs+1−1
@@ -153,7 +153,7 @@ getGitWorkingTreeStatus :: PrepareM TreeStatus
153153getGitWorkingTreeStatus = do
154154 out <- readProcess' "git" ["status", "--porcelain"] ""
155155 return $
156− if null . filter (not . null) . lines $ out
156+ if all null . lines $ out
157157 then Clean
158158 else Dirty
159159
src/Language/PureScript/Publish/ErrorsWarnings.hs+14−15
@@ -98,10 +98,10 @@ renderError err =
9898 case err of
9999 UserError e ->
100100 vcat
101− [ para (concat
102− [ "There is a problem with your package, which meant that "
103− , "it could not be published."
104− ])
101+ [ para (
102+ "There is a problem with your package, which meant that " ++
103+ "it could not be published."
104+ )
105105 , para "Details:"
106106 , indented (displayUserError e)
107107 ]
@@ -123,10 +123,10 @@ renderError err =
123123displayUserError :: UserError -> Box
124124displayUserError e = case e of
125125 BowerJSONNotFound ->
126− para (concat
127− [ "The bower.json file was not found. Please create one, or run "
128− , "`pulp init`."
129− ])
126+ para (
127+ "The bower.json file was not found. Please create one, or run " ++
128+ "`pulp init`."
129+ )
130130 BowerExecutableNotFound names ->
131131 para (concat
132132 [ "The Bower executable was not found (tried: ", format names, "). Please"
@@ -217,10 +217,10 @@ displayUserError e = case e of
217217 , indented (P.prettyPrintMultipleErrorsBox False err)
218218 ]
219219 DirtyWorkingTree ->
220− para (concat
221− [ "Your git working tree is dirty. Please commit, discard, or stash "
222− , "your changes first."
223− ])
220+ para (
221+ "Your git working tree is dirty. Please commit, discard, or stash " ++
222+ "your changes first."
223+ )
224224
225225displayRepositoryError :: RepositoryFieldError -> Box
226226displayRepositoryError err = case err of
@@ -356,12 +356,11 @@ warnUndeclaredDependencies pkgNames =
356356 are = pl "are" "is"
357357 dependencies = pl "dependencies" "a dependency"
358358 in vcat $
359− [ para (concat
359+ para (concat
360360 [ "The following Bower ", packages, " ", are, " installed, but not "
361361 , "declared as ", dependencies, " in your bower.json file:"
362362 ])
363− ] ++
364− bulletedList runPackageName (NonEmpty.toList pkgNames)
363+ : bulletedList runPackageName (NonEmpty.toList pkgNames)
365364
366365warnUnacceptableVersions :: NonEmpty (PackageName, String) -> Box
367366warnUnacceptableVersions pkgs =
src/Language/PureScript/Renamer.hs+3−3
@@ -80,12 +80,12 @@ updateScope :: Ident -> Rename Ident
8080updateScope i@(Ident name) | name == C.__unused = return i
8181updateScope name = do
8282 scope <- get
83− name' <- case name `S.member` rsUsedNames scope of
84− True -> do
83+ name' <- if name `S.member` rsUsedNames scope
84+ then do
8585 let newNames = [ Ident (runIdent name ++ "_" ++ show (i :: Int)) | i <- [1..] ]
8686 Just newName = find (`S.notMember` rsUsedNames scope) newNames
8787 return newName
88− False -> return name
88+ else return name
8989 modify $ \s -> s { rsBoundNames = M.insert name name' (rsBoundNames s)
9090 , rsUsedNames = S.insert name' (rsUsedNames s)
9191 }
src/Language/PureScript/Sugar/DoNotation.hs+2−2
@@ -42,13 +42,13 @@ desugarDoModule :: forall m. (Applicative m, MonadSupply m, MonadError MultipleE
4242desugarDoModule (Module ss coms mn ds exts) = Module ss coms mn <$> parU ds desugarDo <*> pure exts
4343
4444desugarDo :: forall m. (Applicative m, MonadSupply m, MonadError MultipleErrors m) => Declaration -> m Declaration
45−desugarDo (PositionedDeclaration pos com d) = PositionedDeclaration pos com <$> (rethrowWithPosition pos $ desugarDo d)
45+desugarDo (PositionedDeclaration pos com d) = PositionedDeclaration pos com <$> rethrowWithPosition pos (desugarDo d)
4646desugarDo d =
4747 let (f, _, _) = everywhereOnValuesM return replace return
4848 in f d
4949 where
5050 bind :: Expr
51− bind = Var (Qualified Nothing (Ident (C.bind)))
51+ bind = Var (Qualified Nothing (Ident C.bind))
5252
5353 replace :: Expr -> m Expr
5454 replace (Do els) = go els
src/Language/PureScript/Sugar/Names.hs+1−1
@@ -132,7 +132,7 @@ elaborateImports imps (Module ss coms mn decls exps) = Module ss coms mn decls'
132132 let (f, _, _, _, _) = everythingOnValues (++) (const []) fqValues (const []) (const []) (const [])
133133 in mkImport `map` nub (f `concatMap` decls) ++ decls
134134 fqValues :: Expr -> [ModuleName]
135− fqValues (Var (Qualified (Just mn') _)) | notElem mn' (importedModules imps) = [mn']
135+ fqValues (Var (Qualified (Just mn') _)) | mn' `notElem` importedModules imps = [mn']
136136 fqValues _ = []
137137 mkImport :: ModuleName -> Declaration
138138 mkImport mn' = ImportDeclaration mn' (Explicit []) Nothing
src/Language/PureScript/Sugar/Names/Exports.hs+2−3
@@ -205,9 +205,8 @@ filterModule mn exps refs = do
205205 -- the data constructor to check.
206206 checkDcon :: ProperName -> [ProperName] -> ProperName -> m ()
207207 checkDcon tcon exps' name =
208− if name `elem` exps'
209− then return ()
210− else throwError . errorMessage $ UnknownExportDataConstructor tcon name
208+ unless (name `elem` exps') $
209+ throwError . errorMessage $ UnknownExportDataConstructor tcon name
211210
212211 -- Takes a list of all the exportable classes, the accumulated list of
213212 -- filtered exports, and a `DeclarationRef` for an explicit export. When the
src/Language/PureScript/Sugar/TypeDeclarations.hs+1−1
@@ -59,7 +59,7 @@ desugarTypeDeclarations (TypeDeclaration name ty : d : rest) = do
5959 (ident, nameKind, val) <- rethrowWithPosition pos $ fromValueDeclaration d'
6060 return (ident, nameKind, PositionedValue pos com val)
6161 fromValueDeclaration _ = throwError . errorMessage $ OrphanTypeDeclaration name
62−desugarTypeDeclarations (TypeDeclaration name _ : []) = throwError . errorMessage $ OrphanTypeDeclaration name
62+desugarTypeDeclarations [TypeDeclaration name _] = throwError . errorMessage $ OrphanTypeDeclaration name
6363desugarTypeDeclarations (ValueDeclaration name nameKind bs val : rest) = do
6464 let (_, f, _) = everywhereOnValuesTopDownM return go return
6565 f' (Left gs) = Left <$> mapM (pairM return f) gs
src/Language/PureScript/TypeChecker/Entailment.hs−1
@@ -13,7 +13,6 @@
1313--
1414-----------------------------------------------------------------------------
1515
16−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1716{-# LANGUAGE CPP #-}
1817
1918module Language.PureScript.TypeChecker.Entailment (
src/Language/PureScript/TypeChecker/Types.hs+1−1
@@ -399,7 +399,7 @@ binderRequiresMonotype _ = True
399399
400400-- | Instantiate polytypes only when necessitated by a binder.
401401instantiateForBinders :: [Expr] -> [CaseAlternative] -> UnifyT Type Check ([Expr], [Type])
402−instantiateForBinders vals cas = fmap unzip $ zipWithM (\val inst -> do
402+instantiateForBinders vals cas = unzip <$> zipWithM (\val inst -> do
403403 TypedValue _ val' ty <- infer val
404404 if inst
405405 then instantiatePolyTypeWithUnknowns val' ty
src/Language/PureScript/TypeChecker/Unify.hs+1−1
@@ -141,7 +141,7 @@ unifiesWith (TypeVar v1) (TypeVar v2) | v1 == v2 = True
141141unifiesWith (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = True
142142unifiesWith (TypeApp h1 t1) (TypeApp h2 t2) = h1 `unifiesWith` h2 && t1 `unifiesWith` t2
143143unifiesWith REmpty REmpty = True
144−unifiesWith r1@(RCons _ _ _) r2@(RCons _ _ _) =
144+unifiesWith r1@RCons{} r2@RCons{} =
145145 let (s1, r1') = rowToList r1
146146 (s2, r2') = rowToList r2
147147
src/Language/PureScript/Types.hs+2−4
@@ -22,6 +22,7 @@ module Language.PureScript.Types where
2222
2323import Data.Data
2424import Data.List (nub)
25+import Data.Maybe (fromMaybe)
2526import qualified Data.Aeson as A
2627import qualified Data.Aeson.TH as A
2728
@@ -152,10 +153,7 @@ replaceAllTypeVars = go []
152153 where
153154
154155 go :: [String] -> [(String, Type)] -> Type -> Type
155− go _ m (TypeVar v) =
156− case v `lookup` m of
157− Just r -> r
158− Nothing -> TypeVar v
156+ go _ m (TypeVar v) = fromMaybe (TypeVar v) (v `lookup` m)
159157 go bs m (TypeApp t1 t2) = TypeApp (go bs m t1) (go bs m t2)
160158 go bs m f@(ForAll v t sco) | v `elem` keys = go bs (filter ((/= v) . fst) m) f
161159 | v `elem` usedVars =
src/System/IO/UTF8.hsnew file+9
@@ -0,0 +1,9 @@
1+module System.IO.UTF8
2+where
3+import System.IO (hGetContents, hSetEncoding, openFile, utf8, IOMode (..))
4+
5+readUTF8File :: FilePath -> IO String
6+readUTF8File inFile = do
7+ h <- openFile inFile ReadMode
8+ hSetEncoding h utf8
9+ hGetContents h
stack-lts-3.yaml+1−1
@@ -2,4 +2,4 @@ flags: {}
22packages:
33- '.'
44extra-deps:
5−resolver: lts-3.4
5+resolver: lts-3.6
stack-nightly.yaml+1−1
@@ -2,4 +2,4 @@ flags: {}
22packages:
33- '.'
44extra-deps:
5−resolver: nightly-2015-09-09
5+resolver: nightly-2015-09-29
tests/Main.hs+4−3
@@ -66,6 +66,7 @@ import System.Exit
6666import System.Process
6767import System.FilePath
6868import System.Directory
69+import System.IO.UTF8
6970import qualified System.Info
7071import qualified System.FilePath.Glob as Glob
7172
@@ -97,7 +98,7 @@ makeActions foreigns = (P.buildMakeActions modulesDir (error "makeActions: input
9798
9899readInput :: [FilePath] -> IO [(FilePath, String)]
99100readInput inputFiles = forM inputFiles $ \inputFile -> do
100− text <- readFile inputFile
101+ text <- readUTF8File inputFile
101102 return (inputFile, text)
102103
103104type TestM = WriterT [(FilePath, String)] IO
@@ -157,7 +158,7 @@ assertDoesNotCompile inputFiles foreigns = do
157158
158159 where
159160 getShouldFailWith =
160− readFile
161+ readUTF8File
161162 >>> liftIO
162163 >>> fmap ( lines
163164 >>> mapMaybe (stripPrefix "-- @shouldFailWith ")
@@ -184,7 +185,7 @@ main = do
184185 supportPurs <- supportFiles "purs"
185186 supportJS <- supportFiles "js"
186187
187− foreignFiles <- forM supportJS (\f -> (f,) <$> readFile f)
188+ foreignFiles <- forM supportJS (\f -> (f,) <$> readUTF8File f)
188189 Right (foreigns, _) <- runExceptT $ runWriterT $ P.parseForeignModulesFromFiles foreignFiles
189190
190191 let passing = cwd </> "examples" </> "passing"