git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge branch 'master' into pure11
commitcd8e57f651aaaaf1048acddf8a6f8a69200ce6ee authorAndy Arvanitis <andyarvanitis@gmail.com> dateTue 20 Oct 2015, 15:29 (11 years ago) parent43aeba78178604
67 files changed+1315−1092
.gitignore+1 .travis.yml+2−1 INSTALL.md+12−2 LICENSE+167−68 README.md+5−1 core-tests/tests/generic-deriving/Main.purs+3 examples/failing/1071.purs+8 examples/failing/881.purs+13 examples/failing/TransitiveDctorExport.purs+5 examples/failing/TransitiveSynonymExport.purs+5 examples/failing/TypedBinders.purs+10 examples/failing/TypedBinders2.purs+9 examples/failing/TypedBinders3.purs+12 examples/passing/TypedBinders.purs+62 license-generator/generate+3 pcc/Make.hs+10−15 psci/PSCi.hs+6−6 purescript.cabal+13−2 src/Language/PureScript/AST/Binders.hs+7−1 src/Language/PureScript/AST/Exported.hs+1−1 src/Language/PureScript/AST/Traversals.hs+9−3 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/Desugar.hs+2 src/Language/PureScript/CoreFn/Expr.hs+1−1 src/Language/PureScript/Docs/Convert.hs+2−3 src/Language/PureScript/Docs/Render.hs+3−2 src/Language/PureScript/Docs/Types.hs+1−1 src/Language/PureScript/Errors.hs+338−341 src/Language/PureScript/Linter.hs+5−4 src/Language/PureScript/Linter/Exhaustive.hs+30−20 src/Language/PureScript/Make.hs+125−62 src/Language/PureScript/ModuleDependencies.hs+9−7 src/Language/PureScript/Names.hs+4 src/Language/PureScript/Parser/Declarations.hs+18−18 src/Language/PureScript/Parser/Kinds.hs+1−1 src/Language/PureScript/Parser/Lexer.hs+1−1 src/Language/PureScript/Pretty/Common.hs+11 src/Language/PureScript/Pretty/JS.hs+13−13 src/Language/PureScript/Pretty/Kinds.hs+2−3 src/Language/PureScript/Pretty/Types.hs+58−35 src/Language/PureScript/Pretty/Values.hs+98−152 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/BindingGroups.hs+1−1 src/Language/PureScript/Sugar/CaseDeclarations.hs+3−1 src/Language/PureScript/Sugar/DoNotation.hs+2−2 src/Language/PureScript/Sugar/Names.hs+6−3 src/Language/PureScript/Sugar/Names/Exports.hs+4−5 src/Language/PureScript/Sugar/Names/Imports.hs+1−1 src/Language/PureScript/Sugar/Operators.hs+1−1 src/Language/PureScript/Sugar/TypeClasses.hs+1−1 src/Language/PureScript/Sugar/TypeDeclarations.hs+37−33 src/Language/PureScript/TypeChecker.hs+78−50 src/Language/PureScript/TypeChecker/Entailment.hs+15−25 src/Language/PureScript/TypeChecker/Kinds.hs+4−4 src/Language/PureScript/TypeChecker/Rows.hs−1 src/Language/PureScript/TypeChecker/Skolems.hs+1−1 src/Language/PureScript/TypeChecker/Subsumption.hs+1−9 src/Language/PureScript/TypeChecker/Synonyms.hs+20−66 src/Language/PureScript/TypeChecker/Types.hs+18−58 src/Language/PureScript/TypeChecker/Unify.hs+11−26 src/Language/PureScript/Types.hs+2−16
.gitignore+1
@@ -15,3 +15,4 @@ node_modules
1515tmp/
1616.stack-work/
1717tests/support/flattened/
18+output
.travis.yml+2−1
@@ -15,7 +15,7 @@ matrix:
1515 - env: GHCVER=7.6.3
1616 compiler: ": #GHC 7.6.3"
1717 addons: {apt: {packages: [cabal-install-1.22,ghc-7.6.3,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
18− - env: GHCVER=7.10.1
18+ - env: GHCVER=7.10.1 DEPLOY=yes
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]}}
2121 - env: GHCVER=7.10.2 STACKAGE=lts=3.6 RUNSDISTTESTS=YES
@@ -74,6 +74,7 @@ deploy:
7474 on:
7575 all_branches: true
7676 tags: true
77+ condition: "$DEPLOY = yes"
7778cache:
7879 directories:
7980 - ~/cabal-sandboxes
INSTALL.md+12−2
@@ -24,15 +24,25 @@ requirements.
2424## Compiling from source
2525
2626GHC 7.6.1 or newer is required to compile from source. The easiest way is to
27−use `cabal-install`:
27+use stack:
2828
2929```
30−$ cabal update && cabal install purescript
30+$ stack install purescript
3131```
3232
33+This will then copy the compiler and utilities into `~/.local/bin`.
34+
35+
36+If you don't have stack installed yet there are install instructions
37+[here](https://github.com/commercialhaskell/stack/blob/master/doc/install_and_upgrade.md).
38+
39+If you don't have ghc installed yet, stack will prompt you to run `stack setup`
40+which will install ghc for you.
41+
3342The PureScript compiler has been known to run on OS X 10.6 when built with GHC
34437.6.
3544
45+
3646## The "curses" library
3747
3848`psci` depends on the `curses` library (via the Haskell package `terminfo`). If
LICENSE+167−68
@@ -31,6 +31,7 @@ PureScript uses the following Haskell library packages. Their license files foll
3131 array
3232 attoparsec
3333 base
34+ binary
3435 blaze-builder
3536 bower-json
3637 boxes
@@ -45,9 +46,10 @@ PureScript uses the following Haskell library packages. Their license files foll
4546 haskeline
4647 integer-gmp
4748 language-javascript
49+ lifted-base
50+ monad-control
4851 mtl
4952 nats
50− old-locale
5153 optparse-applicative
5254 parsec
5355 pattern-arrows
@@ -59,12 +61,14 @@ PureScript uses the following Haskell library packages. Their license files foll
5961 scientific
6062 semigroups
6163 split
64+ stm
6265 syb
6366 template-haskell
6467 terminfo
6568 text
6669 time
6770 transformers
71+ transformers-base
6872 transformers-compat
6973 unix
7074 unordered-containers
@@ -449,6 +453,39 @@ base LICENSE file:
449453
450454 -----------------------------------------------------------------------------
451455
456+binary LICENSE file:
457+
458+ Copyright (c) Lennart Kolmodin
459+
460+ All rights reserved.
461+
462+ Redistribution and use in source and binary forms, with or without
463+ modification, are permitted provided that the following conditions
464+ are met:
465+
466+ 1. Redistributions of source code must retain the above copyright
467+ notice, this list of conditions and the following disclaimer.
468+
469+ 2. Redistributions in binary form must reproduce the above copyright
470+ notice, this list of conditions and the following disclaimer in the
471+ documentation and/or other materials provided with the distribution.
472+
473+ 3. Neither the name of the author nor the names of his contributors
474+ may be used to endorse or promote products derived from this software
475+ without specific prior written permission.
476+
477+ THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
478+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
479+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
480+ DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
481+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
482+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
483+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
484+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
485+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
486+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
487+ POSSIBILITY OF SUCH DAMAGE.
488+
452489blaze-builder LICENSE file:
453490
454491 Copyright Jasper Van der Jeugt 2010, Simon Meier 2010 & 2011
@@ -967,6 +1004,70 @@ language-javascript LICENSE file:
9671004 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
9681005 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9691006
1007+lifted-base LICENSE file:
1008+
1009+ Copyright © 2010-2012, Bas van Dijk, Anders Kaseorg
1010+ All rights reserved.
1011+
1012+ Redistribution and use in source and binary forms, with or without
1013+ modification, are permitted provided that the following conditions are
1014+ met:
1015+
1016+ • Redistributions of source code must retain the above copyright
1017+ notice, this list of conditions and the following disclaimer.
1018+
1019+ • Redistributions in binary form must reproduce the above copyright
1020+ notice, this list of conditions and the following disclaimer in the
1021+ documentation and/or other materials provided with the distribution.
1022+
1023+ • Neither the name of the author nor the names of other contributors
1024+ may be used to endorse or promote products derived from this
1025+ software without specific prior written permission.
1026+
1027+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1028+ “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1029+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1030+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1031+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1032+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1033+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1034+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1035+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1036+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1037+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1038+
1039+monad-control LICENSE file:
1040+
1041+ Copyright © 2010, Bas van Dijk, Anders Kaseorg
1042+ All rights reserved.
1043+
1044+ Redistribution and use in source and binary forms, with or without
1045+ modification, are permitted provided that the following conditions are
1046+ met:
1047+
1048+ • Redistributions of source code must retain the above copyright
1049+ notice, this list of conditions and the following disclaimer.
1050+
1051+ • Redistributions in binary form must reproduce the above copyright
1052+ notice, this list of conditions and the following disclaimer in the
1053+ documentation and/or other materials provided with the distribution.
1054+
1055+ • Neither the name of the author nor the names of other contributors
1056+ may be used to endorse or promote products derived from this
1057+ software without specific prior written permission.
1058+
1059+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1060+ “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1061+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1062+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1063+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1064+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1065+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1066+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1067+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1068+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1069+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1070+
9701071mtl LICENSE file:
9711072
9721073 The Glasgow Haskell Compiler License
@@ -1034,72 +1135,6 @@ nats LICENSE file:
10341135 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
10351136 POSSIBILITY OF SUCH DAMAGE.
10361137
1037−old-locale LICENSE file:
1038−
1039− This library (libraries/base) is derived from code from two
1040− sources:
1041−
1042− * Code from the GHC project which is largely (c) The University of
1043− Glasgow, and distributable under a BSD-style license (see below),
1044−
1045− * Code from the Haskell 98 Report which is (c) Simon Peyton Jones
1046− and freely redistributable (but see the full license for
1047− restrictions).
1048−
1049− The full text of these licenses is reproduced below. Both of the
1050− licenses are BSD-style or compatible.
1051−
1052− -----------------------------------------------------------------------------
1053−
1054− The Glasgow Haskell Compiler License
1055−
1056− Copyright 2004, The University Court of the University of Glasgow.
1057− All rights reserved.
1058−
1059− Redistribution and use in source and binary forms, with or without
1060− modification, are permitted provided that the following conditions are met:
1061−
1062− - Redistributions of source code must retain the above copyright notice,
1063− this list of conditions and the following disclaimer.
1064−
1065− - Redistributions in binary form must reproduce the above copyright notice,
1066− this list of conditions and the following disclaimer in the documentation
1067− and/or other materials provided with the distribution.
1068−
1069− - Neither name of the University nor the names of its contributors may be
1070− used to endorse or promote products derived from this software without
1071− specific prior written permission.
1072−
1073− THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
1074− GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
1075− INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
1076− FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1077− UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
1078− FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1079− DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1080− SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1081− CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1082− LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1083− OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1084− DAMAGE.
1085−
1086− -----------------------------------------------------------------------------
1087−
1088− Code derived from the document "Report on the Programming Language
1089− Haskell 98", is distributed under the following license:
1090−
1091− Copyright (c) 2002 Simon Peyton Jones
1092−
1093− The authors intend this Report to belong to the entire Haskell
1094− community, and so we grant permission to copy and distribute it for
1095− any purpose, provided that it is reproduced in its entirety,
1096− including this Notice. Modified versions of this Report may also be
1097− copied and distributed for any purpose, provided that the modified
1098− version is clearly presented as such, and that it does not claim to
1099− be a definition of the Haskell 98 Language.
1100−
1101− -----------------------------------------------------------------------------
1102−
11031138optparse-applicative LICENSE file:
11041139
11051140 Copyright (c) 2012, Paolo Capriotti
@@ -1450,6 +1485,40 @@ split LICENSE file:
14501485 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
14511486 SUCH DAMAGE.
14521487
1488+stm LICENSE file:
1489+
1490+ The Glasgow Haskell Compiler License
1491+
1492+ Copyright 2004, The University Court of the University of Glasgow.
1493+ All rights reserved.
1494+
1495+ Redistribution and use in source and binary forms, with or without
1496+ modification, are permitted provided that the following conditions are met:
1497+
1498+ - Redistributions of source code must retain the above copyright notice,
1499+ this list of conditions and the following disclaimer.
1500+
1501+ - Redistributions in binary form must reproduce the above copyright notice,
1502+ this list of conditions and the following disclaimer in the documentation
1503+ and/or other materials provided with the distribution.
1504+
1505+ - Neither name of the University nor the names of its contributors may be
1506+ used to endorse or promote products derived from this software without
1507+ specific prior written permission.
1508+
1509+ THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
1510+ GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
1511+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
1512+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1513+ UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
1514+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1515+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1516+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1517+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1518+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1519+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1520+ DAMAGE.
1521+
14531522syb LICENSE file:
14541523
14551524 This library (libraries/syb) is derived from code from several
@@ -1674,6 +1743,36 @@ transformers LICENSE file:
16741743 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
16751744 DAMAGE.
16761745
1746+transformers-base LICENSE file:
1747+
1748+ Copyright (c) 2011, Mikhail Vorozhtsov, Bas van Dijk
1749+ All rights reserved.
1750+
1751+ Redistribution and use in source and binary forms, with or without
1752+ modification, are permitted provided that the following conditions are met:
1753+
1754+ - Redistributions of source code must retain the above copyright notice,
1755+ this list of conditions and the following disclaimer.
1756+ - Redistributions in binary form must reproduce the above copyright
1757+ notice, this list of conditions and the following disclaimer in the
1758+ documentation and/or other materials provided with the distribution.
1759+ - Neither the names of the copyright owners nor the names of the
1760+ contributors may be used to endorse or promote products derived
1761+ from this software without specific prior written permission.
1762+
1763+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1764+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1765+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1766+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1767+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1768+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1769+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1770+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1771+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1772+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1773+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1774+
1775+
16771776transformers-compat LICENSE file:
16781777
16791778 Copyright 2012 Edward Kmett
@@ -1836,7 +1935,7 @@ vector LICENSE file:
18361935
18371936void LICENSE file:
18381937
1839− Copyright 2013 Edward Kmett
1938+ Copyright 2015 Edward Kmett
18401939
18411940 All rights reserved.
18421941
README.md+5−1
@@ -2,7 +2,11 @@
22
33A small strongly typed programming language with expressive types that compiles to Javascript, written in and inspired by Haskell.
44
5−[![Hackage](https://img.shields.io/hackage/v/purescript.svg)](http://hackage.haskell.org/package/purescript) [![Build Status](https://api.travis-ci.org/purescript/purescript.svg?branch=master)](http://travis-ci.org/purescript/purescript) [![Coverage Status](https://coveralls.io/repos/purescript/purescript/badge.svg?branch=master)](https://coveralls.io/r/purescript/purescript?branch=master)
5+[![Hackage](https://img.shields.io/hackage/v/purescript.svg)](http://hackage.haskell.org/package/purescript) [![Build Status](https://api.travis-ci.org/purescript/purescript.svg?branch=master)](http://travis-ci.org/purescript/purescript)
6+
7+[![Stackage LTS 2](http://stackage.org/package/purescript/badge/lts-2)](http://stackage.org/lts-2/package/purescript)
8+[![Stackage LTS 3](http://stackage.org/package/purescript/badge/lts-3)](http://stackage.org/lts-3/package/purescript)
9+[![Stackage Nightly](http://stackage.org/package/purescript/badge/nightly)](http://stackage.org/nightly/package/purescript)
610
711## Language info
812
core-tests/tests/generic-deriving/Main.purs+3
@@ -2,6 +2,8 @@ module GenericDeriving where
22
33import Prelude
44
5+import Control.Monad.Eff (Eff())
6+import Control.Monad.Eff.Console (CONSOLE())
57import Data.Generic
68
79data Void
@@ -17,4 +19,5 @@ data A a
1719
1820derive instance genericA :: (Generic a) => Generic (A a)
1921
22+main :: forall eff. Eff (console :: CONSOLE | eff) Unit
2023main = Control.Monad.Eff.Console.log (gShow (D { a: C [ A 1.0 "test", B 42, D { a: true } ] }))
examples/failing/1071.pursnew file+8
@@ -0,0 +1,8 @@
1+-- @shouldFailWith KindsDoNotUnify
2+module Main where
3+
4+class Foo a b where
5+ foo :: a -> b
6+
7+bar :: forall a. (Foo a) => a -> a
8+bar a = a
examples/failing/881.pursnew file+13
@@ -0,0 +1,13 @@
1+-- @shouldFailWith DuplicateValueDeclaration
2+module Main where
3+
4+data X = X | Y
5+
6+class Foo a where
7+ foo :: a -> a
8+ bar :: a
9+
10+instance fooX :: Foo X where
11+ foo X = X
12+ bar = X
13+ foo Y = Y
examples/failing/TransitiveDctorExport.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith TransitiveExportError
2+module Main (Y(..)) where
3+
4+type X = Int
5+data Y = Y X
examples/failing/TransitiveSynonymExport.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith TransitiveExportError
2+module Main (Y()) where
3+
4+type X = Int
5+type Y = X
examples/failing/TypedBinders.pursnew file+10
@@ -0,0 +1,10 @@
1+-- @shouldFailWith ErrorParsingModule
2+module Main where
3+
4+import Prelude
5+
6+test = (\f :: Int -> Int -> f 10) id
7+
8+main = do
9+ let t1 = test
10+ Control.Monad.Eff.Console.log "Done"
examples/failing/TypedBinders2.pursnew file+9
@@ -0,0 +1,9 @@
1+-- @shouldFailWith TypesDoNotUnify
2+module Main where
3+
4+import Prelude
5+
6+main = do
7+ s :: String <- Control.Monad.Eff.Console.log "Foo"
8+ Control.Monad.Eff.Console.log "Done"
9+
examples/failing/TypedBinders3.pursnew file+12
@@ -0,0 +1,12 @@
1+-- @shouldFailWith TypesDoNotUnify
2+module Main where
3+
4+import Prelude
5+
6+test = case 1 of
7+ (0 :: String) -> true
8+ _ -> false
9+
10+main = do
11+ let t = test
12+ Control.Monad.Eff.Console.log "Done"
examples/passing/TypedBinders.pursnew file+62
@@ -0,0 +1,62 @@
1+module Main where
2+
3+import Prelude
4+
5+data Tuple a b = Tuple a b
6+
7+class MonadState s m where
8+ get :: m s
9+ put :: s -> m {}
10+
11+data State s a = State (s -> Tuple s a)
12+
13+runState s (State f) = f s
14+
15+instance functorState :: Functor (State s) where
16+ map = liftM1
17+
18+instance applyState :: Apply (State s) where
19+ apply = ap
20+
21+instance applicativeState :: Applicative (State s) where
22+ pure a = State $ \s -> Tuple s a
23+
24+instance bindState :: Bind (State s) where
25+ bind f g = State $ \s -> case runState s f of
26+ Tuple s1 a -> runState s1 (g a)
27+
28+instance monadState :: Monad (State s)
29+
30+instance monadStateState :: MonadState s (State s) where
31+ get = State (\s -> Tuple s s)
32+ put s = State (\_ -> Tuple s {})
33+
34+modify :: forall m s. (Prelude.Monad m, MonadState s m) => (s -> s) -> m {}
35+modify f = do
36+ s <- get
37+ put (f s)
38+
39+test :: Tuple String String
40+test = runState "" $ do
41+ modify $ (++) "World!"
42+ modify $ (++) "Hello, "
43+ str :: String <- get
44+ return str
45+
46+test2 :: (Int -> Int) -> Int
47+test2 = (\(f :: Int -> Int) -> f 10)
48+
49+test3 :: Int -> Boolean
50+test3 n = case n of
51+ (0 :: Int) -> true
52+ _ -> false
53+
54+test4 :: Tuple Int Int -> Tuple Int Int
55+test4 = (\(Tuple a b :: Tuple Int Int) -> Tuple b a)
56+
57+main = do
58+ let t1 = test
59+ t2 = test2 id
60+ t3 = test3 1
61+ t4 = test4 (Tuple 1 0)
62+ Control.Monad.Eff.Console.log "Done"
license-generator/generate+3
@@ -9,6 +9,9 @@ set -e # exit on error
99set -u # exit on undefined variable
1010set -o pipefail # propagate nonzero exit codes through pipelines
1111
12+export LC_CTYPE=C
13+export LANG=C
14+
1215if ! which cabal-dependency-licenses >/dev/null; then
1316 echo "$0: the program 'cabal-dependency-licenses' is required." >&2
1417 echo "$0: see Hackage: https://hackage.haskell.org/package/cabal-dependency-licenses" >&2
pcc/Make.hs+10−15
@@ -26,9 +26,7 @@ module Make
2626
2727import Control.Monad
2828import Control.Monad.Error.Class (MonadError(..))
29−import Control.Monad.Trans.Except
3029import Control.Monad.Reader
31−import Control.Monad.Writer.Strict
3230
3331import Data.FileEmbed (embedFile)
3432import Data.List (intercalate)
@@ -45,17 +43,14 @@ import System.FilePath ((</>), takeDirectory, addExtension, dropExtension)
4543import System.IO.Error (tryIOError)
4644import System.IO.UTF8
4745
46+import Language.PureScript.Errors
47+import Language.PureScript (Make, runMake)
48+
4849import qualified Language.PureScript as P
4950import qualified Language.PureScript.CodeGen.Cpp as CPP
5051import qualified Language.PureScript.CoreFn as CF
5152import qualified Paths_purescript as Paths
5253
53−newtype Make a = Make { unMake :: ReaderT P.Options (WriterT P.MultipleErrors (ExceptT P.MultipleErrors IO)) a }
54− deriving (Functor, Applicative, Monad, MonadIO, MonadError P.MultipleErrors, MonadWriter P.MultipleErrors, MonadReader P.Options)
55−
56−runMake :: P.Options -> Make a -> IO (Either P.MultipleErrors (a, P.MultipleErrors))
57−runMake opts = runExceptT . runWriterT . flip runReaderT opts . unMake
58−
5954makeIO :: (IOError -> P.ErrorMessage) -> IO a -> Make a
6055makeIO f io = do
6156 e <- liftIO $ tryIOError io
@@ -67,7 +62,7 @@ traverseEither _ (Left x) = pure (Left x)
6762traverseEither f (Right y) = Right <$> f y
6863
6964buildMakeActions :: FilePath
70− -> M.Map P.ModuleName (Either P.RebuildPolicy String)
65+ -> M.Map P.ModuleName (Either P.RebuildPolicy FilePath)
7166 -> Bool
7267 -> P.MakeActions Make
7368buildMakeActions outputDir filePathMap usePrefix =
@@ -149,26 +144,26 @@ buildMakeActions outputDir filePathMap usePrefix =
149144 requiresForeign = not . null . CF.moduleForeign
150145
151146 dirExists :: FilePath -> Make Bool
152− dirExists path = makeIO (const (P.SimpleErrorWrapper $ P.CannotReadFile path)) $ do
147+ dirExists path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ do
153148 doesDirectoryExist path
154149
155150 textFileExists :: FilePath -> Make Bool
156− textFileExists path = makeIO (const (P.SimpleErrorWrapper $ P.CannotReadFile path)) $ do
151+ textFileExists path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ do
157152 doesFileExist path
158153
159154 getTimestamp :: FilePath -> Make (Maybe UTCTime)
160− getTimestamp path = makeIO (const (P.SimpleErrorWrapper $ P.CannotGetFileInfo path)) $ do
155+ getTimestamp path = makeIO (const (ErrorMessage [] $ CannotGetFileInfo path)) $ do
161156 exists <- doesFileExist path
162157 traverse (const $ getModificationTime path) $ guard exists
163158
164159 readTextFile :: FilePath -> Make String
165− readTextFile path = makeIO (const (P.SimpleErrorWrapper $ P.CannotReadFile path)) $ readUTF8File path
160+ readTextFile path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ readUTF8File path
166161
167162 readTextFile' :: FilePath -> Make BL.ByteString
168− readTextFile' path = makeIO (const (P.SimpleErrorWrapper $ P.CannotReadFile path)) $ BL.readFile path
163+ readTextFile' path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ BL.readFile path
169164
170165 writeTextFile :: FilePath -> String -> Make ()
171− writeTextFile path text = makeIO (const (P.SimpleErrorWrapper $ P.CannotWriteFile path)) $ do
166+ writeTextFile path text = makeIO (const (ErrorMessage [] $ CannotWriteFile path)) $ do
172167 mkdirp path
173168 writeFile path text
174169 where
psci/PSCi.hs+6−6
@@ -263,10 +263,10 @@ makeIO f io = do
263263
264264make :: PSCiState -> [(Either P.RebuildPolicy FilePath, P.Module)] -> P.Make P.Environment
265265make PSCiState{..} ms = P.make actions' (map snd (psciLoadedModules ++ ms))
266− where
267− filePathMap = M.fromList $ (first P.getModuleName . swap) `map` (psciLoadedModules ++ ms)
268− actions = P.buildMakeActions modulesDir filePathMap psciForeignFiles False
269− actions' = actions { P.progress = const (return ()) }
266+ where
267+ filePathMap = M.fromList $ (first P.getModuleName . swap) `map` (psciLoadedModules ++ ms)
268+ actions = P.buildMakeActions modulesDir filePathMap psciForeignFiles False
269+ actions' = actions { P.progress = const (return ()) }
270270
271271-- |
272272-- Takes a value declaration and evaluates it with the current state.
@@ -464,7 +464,7 @@ handleCommand (LoadFile filePath) = whenFileExists filePath $ \absPath -> do
464464 Right mods -> PSCI . lift $ modify (updateModules (map ((,) (Right absPath)) mods))
465465handleCommand (LoadForeign filePath) = whenFileExists filePath $ \absPath -> do
466466 foreignsOrError <- psciIO . runMake $ do
467− foreignFile <- makeIO (const (P.SimpleErrorWrapper $ P.CannotReadFile absPath)) (readFile absPath)
467+ foreignFile <- makeIO (const (P.ErrorMessage [] $ P.CannotReadFile absPath)) (readFile absPath)
468468 P.parseForeignModulesFromFiles [(absPath, foreignFile)]
469469 case foreignsOrError of
470470 Left err -> PSCI $ outputStrLn $ P.prettyPrintMultipleErrors False err
@@ -533,7 +533,7 @@ loop PSCiOptions{..} = do
533533 historyFilename <- getHistoryFilename
534534 let settings = defaultSettings { historyFile = Just historyFilename }
535535 foreignsOrError <- runMake $ do
536− foreignFilesContent <- forM foreignFiles (\inFile -> (inFile,) <$> makeIO (const (P.SimpleErrorWrapper $ P.CannotReadFile inFile)) (readFile inFile))
536+ foreignFilesContent <- forM foreignFiles (\inFile -> (inFile,) <$> makeIO (const (P.ErrorMessage [] $ P.CannotReadFile inFile)) (readFile inFile))
537537 P.parseForeignModulesFromFiles foreignFilesContent
538538 case foreignsOrError of
539539 Left errs -> putStrLn (P.prettyPrintMultipleErrors False errs) >> exitFailure
purescript.cabal+13−2
@@ -1,5 +1,5 @@
11name: purescript
2−version: 0.7.4.1
2+version: 0.7.5
33cabal-version: >=1.8
44build-type: Simple
55license: MIT
@@ -25,6 +25,14 @@ extra-source-files: examples/passing/*.purs
2525 , tests/support/bower.json
2626 , tests/support/setup-win.cmd
2727 , psci/tests/data/Sample.purs
28+ , stack.yaml
29+ , stack-lts-2.yaml
30+ , stack-lts-3.yaml
31+ , stack-nightly.yaml
32+ , README.md
33+ , INSTALL.md
34+ , CONTRIBUTORS.md
35+ , CONTRIBUTING.md
2836 , pcc/include/*.hh
2937
3038source-repository head
@@ -33,6 +41,9 @@ source-repository head
3341
3442library
3543 build-depends: base >=4.6 && <5,
44+ lifted-base >= 0.2.3 && < 0.2.4,
45+ monad-control >= 1.0.0.0 && < 1.1,
46+ transformers-base >= 0.4.0 && < 0.5,
3647 containers -any,
3748 unordered-containers -any,
3849 dlist -any,
@@ -192,7 +203,7 @@ executable psc
192203 main-is: Main.hs
193204 buildable: True
194205 hs-source-dirs: psc
195− ghc-options: -Wall -O2 -fno-warn-unused-do-bind
206+ ghc-options: -Wall -O2 -fno-warn-unused-do-bind -threaded -rtsopts "-with-rtsopts=-N"
196207
197208executable psci
198209 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
src/Language/PureScript/AST/Binders.hs+7−1
@@ -21,6 +21,7 @@ import qualified Data.Data as D
2121import Language.PureScript.AST.SourcePos
2222import Language.PureScript.Names
2323import Language.PureScript.Comments
24+import Language.PureScript.Types
2425
2526-- |
2627-- Data type for binders
@@ -69,7 +70,11 @@ data Binder
6970 -- |
7071 -- A binder with source position information
7172 --
72− | PositionedBinder SourceSpan [Comment] Binder deriving (Show, Read, Eq, D.Data, D.Typeable)
73+ | PositionedBinder SourceSpan [Comment] Binder
74+ -- |
75+ -- A binder with a type annotation
76+ --
77+ | TypedBinder Type Binder deriving (Show, Read, Eq, D.Data, D.Typeable)
7378
7479-- |
7580-- Collect all names introduced in binders in an expression
@@ -83,4 +88,5 @@ binderNames = go []
8388 go ns (ArrayBinder bs) = foldl go ns bs
8489 go ns (NamedBinder name b) = go (name : ns) b
8590 go ns (PositionedBinder _ _ b) = go ns b
91+ go ns (TypedBinder _ b) = go ns b
8692 go ns _ = ns
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/AST/Traversals.hs+9−3
@@ -79,6 +79,7 @@ everywhereOnValues f g h = (f', g', h')
7979 h' (ArrayBinder bs) = h (ArrayBinder (map h' bs))
8080 h' (NamedBinder name b) = h (NamedBinder name (h' b))
8181 h' (PositionedBinder pos com b) = h (PositionedBinder pos com (h' b))
82+ h' (TypedBinder t b) = h (TypedBinder t (h' b))
8283 h' other = h other
8384
8485 handleCaseAlternative :: CaseAlternative -> CaseAlternative
@@ -135,6 +136,7 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
135136 h' (ArrayBinder bs) = ArrayBinder <$> mapM (h' <=< h) bs
136137 h' (NamedBinder name b) = NamedBinder name <$> (h b >>= h')
137138 h' (PositionedBinder pos com b) = PositionedBinder pos com <$> (h b >>= h')
139+ h' (TypedBinder t b) = TypedBinder t <$> (h b >>= h')
138140 h' other = h other
139141
140142 handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM (h' <=< h) bs
@@ -187,6 +189,7 @@ everywhereOnValuesM f g h = (f', g', h')
187189 h' (ArrayBinder bs) = (ArrayBinder <$> mapM h' bs) >>= h
188190 h' (NamedBinder name b) = (NamedBinder name <$> h' b) >>= h
189191 h' (PositionedBinder pos com b) = (PositionedBinder pos com <$> h' b) >>= h
192+ h' (TypedBinder t b) = (TypedBinder t <$> h' b) >>= h
190193 h' other = h other
191194
192195 handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM h' bs
@@ -216,10 +219,10 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
216219 f' d = f d
217220
218221 g' v@(UnaryMinus v1) = g v <> g' v1
219− g' v@(BinaryNoParens op v1 v2) = g v <> g op <> g' v1 <> g' v2
222+ g' v@(BinaryNoParens op v1 v2) = g v <> g' op <> g' v1 <> g' v2
220223 g' v@(Parens v1) = g v <> g' v1
221− g' v@(OperatorSection op (Left v1)) = g v <> g op <> g' v1
222− g' v@(OperatorSection op (Right v1)) = g v <> g op <> g' v1
224+ g' v@(OperatorSection op (Left v1)) = g v <> g' op <> g' v1
225+ g' v@(OperatorSection op (Right v1)) = g v <> g' op <> g' v1
223226 g' v@(ArrayLiteral vs) = foldl (<>) (g v) (map g' vs)
224227 g' v@(ObjectLiteral vs) = foldl (<>) (g v) (map (g' . snd) vs)
225228 g' v@(ObjectConstructor vs) = foldl (<>) (g v) (map g' (mapMaybe snd vs))
@@ -242,6 +245,7 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
242245 h' b@(ArrayBinder bs) = foldl (<>) (h b) (map h' bs)
243246 h' b@(NamedBinder _ b1) = h b <> h' b1
244247 h' b@(PositionedBinder _ _ b1) = h b <> h' b1
248+ h' b@(TypedBinder _ b1) = h b <> h' b1
245249 h' b = h b
246250
247251 i' ca@(CaseAlternative bs (Right val)) = foldl (<>) (i ca) (map h' bs) <> g' val
@@ -310,6 +314,7 @@ everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'
310314 h' s (ArrayBinder bs) = foldl (<>) r0 (map (h'' s) bs)
311315 h' s (NamedBinder _ b1) = h'' s b1
312316 h' s (PositionedBinder _ _ b1) = h'' s b1
317+ h' s (TypedBinder _ b1) = h'' s b1
313318 h' _ _ = r0
314319
315320 i'' s ca = let (s', r) = i s ca in r <> i' s' ca
@@ -379,6 +384,7 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
379384 h' s (ArrayBinder bs) = ArrayBinder <$> mapM (h'' s) bs
380385 h' s (NamedBinder name b) = NamedBinder name <$> h'' s b
381386 h' s (PositionedBinder pos com b) = PositionedBinder pos com <$> h'' s b
387+ h' s (TypedBinder t b) = TypedBinder t <$> h'' s b
382388 h' _ other = return other
383389
384390 i'' s = uncurry i' <=< i s
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/Desugar.hs+2
@@ -166,6 +166,8 @@ moduleToCoreFn env (A.Module _ coms mn decls (Just exps)) =
166166 NamedBinder (ss, com, Nothing, Nothing) name (binderToCoreFn ss [] b)
167167 binderToCoreFn _ com (A.PositionedBinder ss com1 b) =
168168 binderToCoreFn (Just ss) (com ++ com1) b
169+ binderToCoreFn ss com (A.TypedBinder _ b) =
170+ binderToCoreFn ss com b
169171
170172 -- |
171173 -- Gets metadata for values.
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−3
@@ -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
@@ -166,7 +166,6 @@ convertDeclaration (P.TypeInstanceDeclaration _ constraints className tys _) tit
166166 unQual x = let (P.Qualified _ y) = x in P.runProperName y
167167
168168 extractProperNames (P.TypeConstructor n) = [unQual n]
169− extractProperNames (P.SaturatedTypeSynonym n _) = [unQual n]
170169 extractProperNames _ = []
171170
172171 childDecl = ChildDeclaration title Nothing Nothing (ChildInstance constraints classApp)
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+338−341
@@ -20,10 +20,11 @@
2020module Language.PureScript.Errors where
2121
2222import Data.Either (lefts, rights)
23−import Data.List (intercalate, transpose)
23+import Data.List (intercalate, transpose, nub, nubBy, partition)
2424import Data.Function (on)
2525#if __GLASGOW_HASKELL__ < 710
2626import Data.Foldable (fold, foldMap)
27+import Data.Traversable (traverse)
2728#else
2829import Data.Foldable (fold)
2930#endif
@@ -52,11 +53,8 @@ import qualified Text.PrettyPrint.Boxes as Box
5253import qualified Text.Parsec as P
5354import qualified Text.Parsec.Error as PE
5455import Text.Parsec.Error (Message(..))
55−import Data.List (nub)
5656
57−-- |
58−-- A type of error messages
59−--
57+-- | A type of error messages
6058data SimpleErrorMessage
6159 = ErrorParsingExterns P.ParseError
6260 | ErrorParsingFFIModule FilePath
@@ -100,6 +98,7 @@ data SimpleErrorMessage
10098 | CtorConflictsWithClass ProperName
10199 | ClassConflictsWithType ProperName
102100 | ClassConflictsWithCtor ProperName
101+ | DuplicateModuleName ModuleName
103102 | DuplicateClassExport ProperName
104103 | DuplicateValueExport Ident
105104 | DuplicateTypeArgument String
@@ -143,45 +142,54 @@ data SimpleErrorMessage
143142 | ShadowedTypeVar String
144143 | UnusedTypeVar String
145144 | WildcardInferredType Type
145+ | MissingTypeDeclaration Ident
146146 | NotExhaustivePattern [[Binder]] Bool
147147 | OverlappingPattern [[Binder]] Bool
148148 | IncompleteExhaustivityCheck
149149 | ClassOperator ProperName Ident
150150 | MisleadingEmptyTypeImport ModuleName ProperName
151151 | ImportHidingModule ModuleName
152− deriving (Show)
153−
154−-- |
155−-- Wrapper of simpler errors
156−--
157−data ErrorMessage
158− = NotYetDefined [Ident] ErrorMessage
159− | ErrorUnifyingTypes Type Type ErrorMessage
160− | ErrorInExpression Expr ErrorMessage
161− | ErrorInModule ModuleName ErrorMessage
162− | ErrorInInstance (Qualified ProperName) [Type] ErrorMessage
163− | ErrorInSubsumption Type Type ErrorMessage
164− | ErrorCheckingType Expr Type ErrorMessage
165− | ErrorCheckingKind Type ErrorMessage
166− | ErrorInferringType Expr ErrorMessage
167− | ErrorInApplication Expr Type Expr ErrorMessage
168− | ErrorInDataConstructor ProperName ErrorMessage
169− | ErrorInTypeConstructor ProperName ErrorMessage
170− | ErrorInBindingGroup [Ident] ErrorMessage
171− | ErrorInDataBindingGroup ErrorMessage
172− | ErrorInTypeSynonym ProperName ErrorMessage
173− | ErrorInValueDeclaration Ident ErrorMessage
174− | ErrorInTypeDeclaration Ident ErrorMessage
175− | ErrorInForeignImport Ident ErrorMessage
176− | PositionedError SourceSpan ErrorMessage
177− | SimpleErrorWrapper SimpleErrorMessage
178− deriving (Show)
152+ deriving Show
153+
154+-- | Error message hints, providing more detailed information about failure.
155+data ErrorMessageHint
156+ = NotYetDefined [Ident]
157+ | ErrorUnifyingTypes Type Type
158+ | ErrorInExpression Expr
159+ | ErrorInModule ModuleName
160+ | ErrorInInstance (Qualified ProperName) [Type]
161+ | ErrorInSubsumption Type Type
162+ | ErrorCheckingType Expr Type
163+ | ErrorCheckingKind Type
164+ | ErrorInferringType Expr
165+ | ErrorInApplication Expr Type Expr
166+ | ErrorInDataConstructor ProperName
167+ | ErrorInTypeConstructor ProperName
168+ | ErrorInBindingGroup [Ident]
169+ | ErrorInDataBindingGroup
170+ | ErrorInTypeSynonym ProperName
171+ | ErrorInValueDeclaration Ident
172+ | ErrorInTypeDeclaration Ident
173+ | ErrorInForeignImport Ident
174+ | PositionedError SourceSpan
175+ deriving Show
176+
177+-- | Categories of hints
178+data HintCategory
179+ = ExprHint
180+ | KindHint
181+ | CheckHint
182+ | PositionHint
183+ | OtherHint
184+ deriving (Show, Eq)
185+
186+data ErrorMessage = ErrorMessage [ErrorMessageHint] SimpleErrorMessage deriving (Show)
179187
180188instance UnificationError Type ErrorMessage where
181− occursCheckFailed t = SimpleErrorWrapper $ InfiniteType t
189+ occursCheckFailed t = ErrorMessage [] $ InfiniteType t
182190
183191instance UnificationError Kind ErrorMessage where
184− occursCheckFailed k = SimpleErrorWrapper $ InfiniteKind k
192+ occursCheckFailed k = ErrorMessage [] $ InfiniteKind k
185193
186194-- |
187195-- Get the error code for a particular error type
@@ -230,6 +238,7 @@ errorCode em = case unwrapErrorMessage em of
230238 CtorConflictsWithClass{} -> "CtorConflictsWithClass"
231239 ClassConflictsWithType{} -> "ClassConflictsWithType"
232240 ClassConflictsWithCtor{} -> "ClassConflictsWithCtor"
241+ DuplicateModuleName{} -> "DuplicateModuleName"
233242 DuplicateClassExport{} -> "DuplicateClassExport"
234243 DuplicateValueExport{} -> "DuplicateValueExport"
235244 DuplicateTypeArgument{} -> "DuplicateTypeArgument"
@@ -273,6 +282,7 @@ errorCode em = case unwrapErrorMessage em of
273282 ShadowedTypeVar{} -> "ShadowedTypeVar"
274283 UnusedTypeVar{} -> "UnusedTypeVar"
275284 WildcardInferredType{} -> "WildcardInferredType"
285+ MissingTypeDeclaration{} -> "MissingTypeDeclaration"
276286 NotExhaustivePattern{} -> "NotExhaustivePattern"
277287 OverlappingPattern{} -> "OverlappingPattern"
278288 IncompleteExhaustivityCheck{} -> "IncompleteExhaustivityCheck"
@@ -300,7 +310,7 @@ nonEmpty = not . null . runMultipleErrors
300310-- Create an error set from a single simple error message
301311--
302312errorMessage :: SimpleErrorMessage -> MultipleErrors
303−errorMessage err = MultipleErrors [SimpleErrorWrapper err]
313+errorMessage err = MultipleErrors [ErrorMessage [] err]
304314
305315
306316-- |
@@ -309,12 +319,14 @@ errorMessage err = MultipleErrors [SimpleErrorWrapper err]
309319singleError :: ErrorMessage -> MultipleErrors
310320singleError = MultipleErrors . pure
311321
312−-- |
313−-- Lift a function on ErrorMessage to a function on MultipleErrors
314−--
322+-- | Lift a function on ErrorMessage to a function on MultipleErrors
315323onErrorMessages :: (ErrorMessage -> ErrorMessage) -> MultipleErrors -> MultipleErrors
316324onErrorMessages f = MultipleErrors . map f . runMultipleErrors
317325
326+-- | Add a hint to an error message
327+addHint :: ErrorMessageHint -> MultipleErrors -> MultipleErrors
328+addHint hint = onErrorMessages $ \(ErrorMessage hints se) -> ErrorMessage (hint : hints) se
329+
318330-- | The various types of things which might need to be relabelled in errors messages.
319331data LabelType = TypeLabel | SkolemLabel String deriving (Show, Read, Eq, Ord)
320332
@@ -328,27 +340,7 @@ data Level = Error | Warning deriving Show
328340-- Extract nested error messages from wrapper errors
329341--
330342unwrapErrorMessage :: ErrorMessage -> SimpleErrorMessage
331−unwrapErrorMessage em = case em of
332− (ErrorCheckingKind _ err) -> unwrapErrorMessage err
333− (ErrorCheckingType _ _ err) -> unwrapErrorMessage err
334− (ErrorInApplication _ _ _ err) -> unwrapErrorMessage err
335− (ErrorInBindingGroup _ err) -> unwrapErrorMessage err
336− (ErrorInDataBindingGroup err) -> unwrapErrorMessage err
337− (ErrorInDataConstructor _ err) -> unwrapErrorMessage err
338− (ErrorInExpression _ err) -> unwrapErrorMessage err
339− (ErrorInForeignImport _ err) -> unwrapErrorMessage err
340− (ErrorInInstance _ _ err) -> unwrapErrorMessage err
341− (ErrorInModule _ err) -> unwrapErrorMessage err
342− (ErrorInSubsumption _ _ err) -> unwrapErrorMessage err
343− (ErrorInTypeConstructor _ err) -> unwrapErrorMessage err
344− (ErrorInTypeSynonym _ err) -> unwrapErrorMessage err
345− (ErrorInValueDeclaration _ err) -> unwrapErrorMessage err
346− (ErrorInTypeDeclaration _ err) -> unwrapErrorMessage err
347− (ErrorInferringType _ err) -> unwrapErrorMessage err
348− (ErrorUnifyingTypes _ _ err) -> unwrapErrorMessage err
349− (NotYetDefined _ err) -> unwrapErrorMessage err
350− (PositionedError _ err) -> unwrapErrorMessage err
351− (SimpleErrorWrapper sem) -> sem
343+unwrapErrorMessage (ErrorMessage _ se) = se
352344
353345replaceUnknowns :: Type -> State UnknownMap Type
354346replaceUnknowns = everywhereOnTypesM replaceTypes
@@ -364,404 +356,406 @@ replaceUnknowns = everywhereOnTypesM replaceTypes
364356 replaceTypes other = return other
365357
366358onTypesInErrorMessageM :: (Applicative m) => (Type -> m Type) -> ErrorMessage -> m ErrorMessage
367−onTypesInErrorMessageM f = g
359+onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse gHint hints <*> gSimple simple
368360 where
369− gSimple (InfiniteType t) = InfiniteType <$> (f t)
370− gSimple (TypesDoNotUnify t1 t2) = TypesDoNotUnify <$> (f t1) <*> (f t2)
371− gSimple (ConstrainedTypeUnified t1 t2) = ConstrainedTypeUnified <$> (f t1) <*> (f t2)
372− gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> (f t)
373− gSimple (PropertyIsMissing s t) = PropertyIsMissing s <$> (f t)
374− gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> (pure e)
361+ gSimple (InfiniteType t) = InfiniteType <$> f t
362+ gSimple (TypesDoNotUnify t1 t2) = TypesDoNotUnify <$> f t1 <*> f t2
363+ gSimple (ConstrainedTypeUnified t1 t2) = ConstrainedTypeUnified <$> f t1 <*> f t2
364+ gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> f t
365+ gSimple (PropertyIsMissing s t) = PropertyIsMissing s <$> f t
366+ gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> pure e
375367 gSimple (InvalidInstanceHead t) = InvalidInstanceHead <$> f t
376368 gSimple other = pure other
377− g (ErrorInSubsumption t1 t2 em) = ErrorInSubsumption <$> (f t1) <*> (f t2) <*> (g em)
378− g (ErrorUnifyingTypes t1 t2 e) = ErrorUnifyingTypes <$> (f t1) <*> (f t2) <*> (g e)
379− g (ErrorCheckingType e t em) = ErrorCheckingType e <$> (f t) <*> (g em)
380− g (ErrorCheckingKind t em) = ErrorCheckingKind <$> (f t) <*> g em
381− g (ErrorInApplication e1 t1 e2 em) = ErrorInApplication e1 <$> (f t1) <*> (pure e2) <*> (g em)
382− g (NotYetDefined x e) = NotYetDefined x <$> (g e)
383− g (ErrorInExpression x e) = ErrorInExpression x <$> (g e)
384− g (ErrorInModule x e) = ErrorInModule x <$> (g e)
385− g (ErrorInInstance x y e) = ErrorInInstance x y <$> (g e)
386− g (ErrorInferringType x e) = ErrorInferringType x <$> (g e)
387− g (ErrorInDataConstructor x e) = ErrorInDataConstructor x <$> (g e)
388− g (ErrorInTypeConstructor x e) = ErrorInTypeConstructor x <$> (g e)
389− g (ErrorInBindingGroup x e) = ErrorInBindingGroup x <$> (g e)
390− g (ErrorInDataBindingGroup e) = ErrorInDataBindingGroup <$> (g e)
391− g (ErrorInTypeSynonym x e) = ErrorInTypeSynonym x <$> (g e)
392− g (ErrorInValueDeclaration x e) = ErrorInValueDeclaration x <$> (g e)
393− g (ErrorInTypeDeclaration x e) = ErrorInTypeDeclaration x <$> (g e)
394− g (ErrorInForeignImport x e) = ErrorInForeignImport x <$> (g e)
395− g (PositionedError x e) = PositionedError x <$> (g e)
396− g (SimpleErrorWrapper sem) = SimpleErrorWrapper <$> gSimple sem
369+ gHint (ErrorInSubsumption t1 t2) = ErrorInSubsumption <$> f t1 <*> f t2
370+ gHint (ErrorUnifyingTypes t1 t2) = ErrorUnifyingTypes <$> f t1 <*> f t2
371+ gHint (ErrorCheckingType e t) = ErrorCheckingType e <$> f t
372+ gHint (ErrorCheckingKind t) = ErrorCheckingKind <$> f t
373+ gHint (ErrorInApplication e1 t1 e2) = ErrorInApplication e1 <$> f t1 <*> pure e2
374+ gHint other = pure other
397375
398376-- |
399377-- Pretty print a single error, simplifying if necessary
400378--
401379prettyPrintSingleError :: Bool -> Level -> ErrorMessage -> State UnknownMap Box.Box
402−prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)
380+prettyPrintSingleError full level e = prettyPrintErrorMessage . positionHintsFirst . reverseHints <$> onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)
403381 where
404− -- |
382+
405383 -- Pretty print an ErrorMessage
406− --
407384 prettyPrintErrorMessage :: ErrorMessage -> Box.Box
408− prettyPrintErrorMessage em =
385+ prettyPrintErrorMessage (ErrorMessage hints simple) =
409386 paras $
410− go em:suggestions em ++
387+ map renderHint hints ++
388+ renderSimpleErrorMessage simple :
389+ suggestions simple ++
411390 [line $ "See " ++ wikiUri ++ " for more information, or to contribute content related to this " ++ levelText ++ "."]
412391 where
413392 wikiUri :: String
414393 wikiUri = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
415394
416− go :: ErrorMessage -> Box.Box
417− goSimple (CannotGetFileInfo path) =
395+ renderSimpleErrorMessage :: SimpleErrorMessage -> Box.Box
396+ renderSimpleErrorMessage (CannotGetFileInfo path) =
418397 paras [ line "Unable to read file info: "
419398 , indent . line $ path
420399 ]
421− goSimple (CannotReadFile path) =
400+ renderSimpleErrorMessage (CannotReadFile path) =
422401 paras [ line "Unable to read file: "
423402 , indent . line $ path
424403 ]
425− goSimple (CannotWriteFile path) =
404+ renderSimpleErrorMessage (CannotWriteFile path) =
426405 paras [ line "Unable to write file: "
427406 , indent . line $ path
428407 ]
429− goSimple (ErrorParsingExterns err) =
408+ renderSimpleErrorMessage (ErrorParsingExterns err) =
430409 paras [ lineWithLevel "parsing externs files: "
431− , indent . prettyPrintParseError $ err
410+ , prettyPrintParseError err
432411 ]
433− goSimple (ErrorParsingFFIModule path) =
412+ renderSimpleErrorMessage (ErrorParsingFFIModule path) =
434413 paras [ line "Unable to parse module from FFI file: "
435414 , indent . line $ path
436415 ]
437− goSimple (ErrorParsingModule err) =
416+ renderSimpleErrorMessage (ErrorParsingModule err) =
438417 paras [ line "Unable to parse module: "
439− , indent . prettyPrintParseError $ err
418+ , prettyPrintParseError err
440419 ]
441− goSimple (MissingFFIModule mn) =
420+ renderSimpleErrorMessage (MissingFFIModule mn) =
442421 line $ "Missing FFI implementations for module " ++ runModuleName mn
443− goSimple (UnnecessaryFFIModule mn path) =
422+ renderSimpleErrorMessage (UnnecessaryFFIModule mn path) =
444423 paras [ line $ "Unnecessary FFI implementations have been provided for module " ++ runModuleName mn ++ ": "
445424 , indent . line $ path
446425 ]
447− goSimple (MultipleFFIModules mn paths) =
448− paras $ [ line $ "Multiple FFI implementations have been provided for module " ++ runModuleName mn ++ ": " ]
449− ++ map (indent . line) paths
450− goSimple (InvalidExternsFile path) =
426+ renderSimpleErrorMessage (MultipleFFIModules mn paths) =
427+ paras [ line $ "Multiple FFI implementations have been provided for module " ++ runModuleName mn ++ ": "
428+ , indent . paras $ map line paths
429+ ]
430+ renderSimpleErrorMessage (InvalidExternsFile path) =
451431 paras [ line "Externs file is invalid: "
452432 , indent . line $ path
453433 ]
454− goSimple InvalidDoBind =
434+ renderSimpleErrorMessage InvalidDoBind =
455435 line "Bind statement cannot be the last statement in a do block. The last statement must be an expression."
456− goSimple InvalidDoLet =
436+ renderSimpleErrorMessage InvalidDoLet =
457437 line "Let statement cannot be the last statement in a do block. The last statement must be an expression."
458− goSimple CannotReorderOperators =
438+ renderSimpleErrorMessage CannotReorderOperators =
459439 line "Unable to reorder operators"
460− goSimple UnspecifiedSkolemScope =
440+ renderSimpleErrorMessage UnspecifiedSkolemScope =
461441 line "Skolem variable scope is unspecified"
462− goSimple OverlappingNamesInLet =
442+ renderSimpleErrorMessage OverlappingNamesInLet =
463443 line "Overlapping names in let binding."
464− goSimple (InfiniteType ty) =
444+ renderSimpleErrorMessage (InfiniteType ty) =
465445 paras [ line "An infinite type was inferred for an expression: "
466− , indent $ line $ prettyPrintType ty
446+ , indent $ typeAsBox ty
467447 ]
468− goSimple (InfiniteKind ki) =
448+ renderSimpleErrorMessage (InfiniteKind ki) =
469449 paras [ line "An infinite kind was inferred for a type: "
470450 , indent $ line $ prettyPrintKind ki
471451 ]
472− goSimple (MultipleFixities name) =
452+ renderSimpleErrorMessage (MultipleFixities name) =
473453 line $ "Multiple fixity declarations for " ++ showIdent name
474− goSimple (OrphanTypeDeclaration nm) =
454+ renderSimpleErrorMessage (OrphanTypeDeclaration nm) =
475455 line $ "Orphan type declaration for " ++ showIdent nm
476− goSimple (OrphanFixityDeclaration op) =
456+ renderSimpleErrorMessage (OrphanFixityDeclaration op) =
477457 line $ "Orphan fixity declaration for " ++ show op
478− goSimple (RedefinedModule name filenames) =
479− paras $ line ("Module " ++ runModuleName name ++ " has been defined multiple times:")
480− : map (indent . line . displaySourceSpan) filenames
481− goSimple (RedefinedIdent name) =
458+ renderSimpleErrorMessage (RedefinedModule name filenames) =
459+ paras [ line ("Module " ++ runModuleName name ++ " has been defined multiple times:")
460+ , indent . paras $ map (line . displaySourceSpan) filenames
461+ ]
462+ renderSimpleErrorMessage (RedefinedIdent name) =
482463 line $ "Name " ++ showIdent name ++ " has been defined multiple times"
483− goSimple (UnknownModule mn) =
464+ renderSimpleErrorMessage (UnknownModule mn) =
484465 line $ "Unknown module " ++ runModuleName mn
485− goSimple (UnknownType name) =
466+ renderSimpleErrorMessage (UnknownType name) =
486467 line $ "Unknown type " ++ showQualified runProperName name
487− goSimple (UnknownTypeClass name) =
468+ renderSimpleErrorMessage (UnknownTypeClass name) =
488469 line $ "Unknown type class " ++ showQualified runProperName name
489− goSimple (UnknownValue name) =
470+ renderSimpleErrorMessage (UnknownValue name) =
490471 line $ "Unknown value " ++ showQualified showIdent name
491− goSimple (UnknownTypeConstructor name) =
472+ renderSimpleErrorMessage (UnknownTypeConstructor name) =
492473 line $ "Unknown type constructor " ++ showQualified runProperName name
493− goSimple (UnknownDataConstructor dc tc) =
474+ renderSimpleErrorMessage (UnknownDataConstructor dc tc) =
494475 line $ "Unknown data constructor " ++ showQualified runProperName dc ++ foldMap ((" for type constructor " ++) . showQualified runProperName) tc
495− goSimple (UnknownImportType mn name) =
476+ renderSimpleErrorMessage (UnknownImportType mn name) =
496477 line $ "Module " ++ runModuleName mn ++ " does not export type " ++ runProperName name
497− goSimple (UnknownExportType name) =
478+ renderSimpleErrorMessage (UnknownExportType name) =
498479 line $ "Cannot export unknown type " ++ runProperName name
499− goSimple (UnknownImportTypeClass mn name) =
480+ renderSimpleErrorMessage (UnknownImportTypeClass mn name) =
500481 line $ "Module " ++ runModuleName mn ++ " does not export type class " ++ runProperName name
501− goSimple (UnknownExportTypeClass name) =
482+ renderSimpleErrorMessage (UnknownExportTypeClass name) =
502483 line $ "Cannot export unknown type class " ++ runProperName name
503− goSimple (UnknownImportValue mn name) =
484+ renderSimpleErrorMessage (UnknownImportValue mn name) =
504485 line $ "Module " ++ runModuleName mn ++ " does not export value " ++ showIdent name
505− goSimple (UnknownExportValue name) =
486+ renderSimpleErrorMessage (UnknownExportValue name) =
506487 line $ "Cannot export unknown value " ++ showIdent name
507− goSimple (UnknownExportModule name) =
488+ renderSimpleErrorMessage (UnknownExportModule name) =
508489 line $ "Cannot export unknown module " ++ runModuleName name ++ ", it either does not exist or has not been imported by the current module"
509− goSimple (UnknownImportDataConstructor mn tcon dcon) =
490+ renderSimpleErrorMessage (UnknownImportDataConstructor mn tcon dcon) =
510491 line $ "Module " ++ runModuleName mn ++ " does not export data constructor " ++ runProperName dcon ++ " for type " ++ runProperName tcon
511− goSimple (UnknownExportDataConstructor tcon dcon) =
492+ renderSimpleErrorMessage (UnknownExportDataConstructor tcon dcon) =
512493 line $ "Cannot export data constructor " ++ runProperName dcon ++ " for type " ++ runProperName tcon ++ " as it has not been declared"
513− goSimple (ConflictingImport nm mn) =
494+ renderSimpleErrorMessage (ConflictingImport nm mn) =
514495 line $ "Cannot declare " ++ show nm ++ " since another declaration of that name was imported from " ++ runModuleName mn
515− goSimple (ConflictingImports nm m1 m2) =
496+ renderSimpleErrorMessage (ConflictingImports nm m1 m2) =
516497 line $ "Conflicting imports for " ++ nm ++ " from modules " ++ runModuleName m1 ++ " and " ++ runModuleName m2
517− goSimple (ConflictingTypeDecls nm) =
498+ renderSimpleErrorMessage (ConflictingTypeDecls nm) =
518499 line $ "Conflicting type declarations for " ++ runProperName nm
519− goSimple (ConflictingCtorDecls nm) =
500+ renderSimpleErrorMessage (ConflictingCtorDecls nm) =
520501 line $ "Conflicting data constructor declarations for " ++ runProperName nm
521− goSimple (TypeConflictsWithClass nm) =
502+ renderSimpleErrorMessage (TypeConflictsWithClass nm) =
522503 line $ "Type " ++ runProperName nm ++ " conflicts with type class declaration of the same name"
523− goSimple (CtorConflictsWithClass nm) =
504+ renderSimpleErrorMessage (CtorConflictsWithClass nm) =
524505 line $ "Data constructor " ++ runProperName nm ++ " conflicts with type class declaration of the same name"
525− goSimple (ClassConflictsWithType nm) =
506+ renderSimpleErrorMessage (ClassConflictsWithType nm) =
526507 line $ "Type class " ++ runProperName nm ++ " conflicts with type declaration of the same name"
527− goSimple (ClassConflictsWithCtor nm) =
508+ renderSimpleErrorMessage (ClassConflictsWithCtor nm) =
528509 line $ "Type class " ++ runProperName nm ++ " conflicts with data constructor declaration of the same name"
529− goSimple (DuplicateClassExport nm) =
510+ renderSimpleErrorMessage (DuplicateModuleName mn) =
511+ line $ "Module " ++ runModuleName mn ++ " has been defined multiple times."
512+ renderSimpleErrorMessage (DuplicateClassExport nm) =
530513 line $ "Duplicate export declaration for type class " ++ runProperName nm
531− goSimple (DuplicateValueExport nm) =
514+ renderSimpleErrorMessage (DuplicateValueExport nm) =
532515 line $ "Duplicate export declaration for value " ++ showIdent nm
533− goSimple (CycleInDeclaration nm) =
516+ renderSimpleErrorMessage (CycleInDeclaration nm) =
534517 line $ "Cycle in declaration of " ++ showIdent nm
535− goSimple (CycleInModules mns) =
518+ renderSimpleErrorMessage (CycleInModules mns) =
536519 line $ "Cycle in module dependencies: " ++ intercalate ", " (map runModuleName mns)
537− goSimple (CycleInTypeSynonym pn) =
520+ renderSimpleErrorMessage (CycleInTypeSynonym pn) =
538521 line $ "Cycle in type synonym" ++ foldMap ((" " ++) . runProperName) pn
539− goSimple (NameIsUndefined ident) =
522+ renderSimpleErrorMessage (NameIsUndefined ident) =
540523 line $ showIdent ident ++ " is undefined"
541− goSimple (NameNotInScope ident) =
524+ renderSimpleErrorMessage (NameNotInScope ident) =
542525 line $ showIdent ident ++ " may not be defined in the current scope"
543− goSimple (UndefinedTypeVariable name) =
526+ renderSimpleErrorMessage (UndefinedTypeVariable name) =
544527 line $ "Type variable " ++ runProperName name ++ " is undefined"
545− goSimple (PartiallyAppliedSynonym name) =
528+ renderSimpleErrorMessage (PartiallyAppliedSynonym name) =
546529 paras [ line $ "Partially applied type synonym " ++ showQualified runProperName name
547530 , line "Type synonyms must be applied to all of their type arguments."
548531 ]
549− goSimple (EscapedSkolem binding) =
532+ renderSimpleErrorMessage (EscapedSkolem binding) =
550533 paras $ [ line "A type variable has escaped its scope." ]
551534 <> foldMap (\expr -> [ line "Relevant expression: "
552− , indent $ line $ prettyPrintValue expr
535+ , indent $ prettyPrintValue expr
553536 ]) binding
554− goSimple (TypesDoNotUnify t1 t2)
537+ renderSimpleErrorMessage (TypesDoNotUnify t1 t2)
555538 = paras [ line "Cannot unify type"
556− , indent $ line $ prettyPrintType t1
539+ , indent $ typeAsBox t1
557540 , line "with type"
558− , indent $ line $ prettyPrintType t2
541+ , indent $ typeAsBox t2
559542 ]
560− goSimple (KindsDoNotUnify k1 k2) =
543+ renderSimpleErrorMessage (KindsDoNotUnify k1 k2) =
561544 paras [ line "Cannot unify kind"
562545 , indent $ line $ prettyPrintKind k1
563546 , line "with kind"
564547 , indent $ line $ prettyPrintKind k2
565548 ]
566− goSimple (ConstrainedTypeUnified t1 t2) =
549+ renderSimpleErrorMessage (ConstrainedTypeUnified t1 t2) =
567550 paras [ line "Cannot unify constrained type"
568− , indent $ line $ prettyPrintType t1
551+ , indent $ typeAsBox t1
569552 , line "with type"
570− , indent $ line $ prettyPrintType t2
571− ]
572− goSimple (OverlappingInstances nm ts (d : ds)) =
573− paras [ line $ "Overlapping instances found for " ++ showQualified runProperName nm ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ ":"
553+ , indent $ typeAsBox t2
554+ ]
555+ renderSimpleErrorMessage (OverlappingInstances nm ts (d : ds)) =
556+ paras [ line "Overlapping instances found for"
557+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
558+ , Box.vcat Box.left (map typeAtomAsBox ts)
559+ ]
560+ , line "The following instances were found:"
574561 , indent $ paras (line (showQualified showIdent d ++ " (chosen)") : map (line . showQualified showIdent) ds)
575562 ]
576− goSimple OverlappingInstances{} = error "OverlappingInstances: empty instance list"
577− goSimple (NoInstanceFound nm ts) =
578− line $ "No instance found for " ++ showQualified runProperName nm ++ " " ++ unwords (map prettyPrintTypeAtom ts)
579− goSimple (PossiblyInfiniteInstance nm ts) =
580− line $ "Instance for " ++ showQualified runProperName nm ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ " is possibly infinite."
581− goSimple (CannotDerive nm ts) =
582− line $ "Cannot derive " ++ showQualified runProperName nm ++ " instance for " ++ unwords (map prettyPrintTypeAtom ts)
583− goSimple (CannotFindDerivingType nm) =
563+ renderSimpleErrorMessage OverlappingInstances{} = error "OverlappingInstances: empty instance list"
564+ renderSimpleErrorMessage (NoInstanceFound nm ts) =
565+ paras [ line "No instance found for"
566+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
567+ , Box.vcat Box.left (map typeAtomAsBox ts)
568+ ]
569+ ]
570+ renderSimpleErrorMessage (PossiblyInfiniteInstance nm ts) =
571+ paras [ line "Instance for"
572+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
573+ , Box.vcat Box.left (map typeAtomAsBox ts)
574+ ]
575+ , line "is possibly infinite."
576+ ]
577+ renderSimpleErrorMessage (CannotDerive nm ts) =
578+ paras [ line "Cannot derive an instance for"
579+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
580+ , Box.vcat Box.left (map typeAtomAsBox ts)
581+ ]
582+ ]
583+ renderSimpleErrorMessage (CannotFindDerivingType nm) =
584584 line $ "Cannot derive instance, because the type declaration for " ++ runProperName nm ++ " could not be found."
585− goSimple (DuplicateLabel l expr) =
585+ renderSimpleErrorMessage (DuplicateLabel l expr) =
586586 paras $ [ line $ "Duplicate label " ++ show l ++ " in row." ]
587587 <> foldMap (\expr' -> [ line "Relevant expression: "
588− , indent $ line $ prettyPrintValue expr'
588+ , indent $ prettyPrintValue expr'
589589 ]) expr
590− goSimple (DuplicateTypeArgument name) =
590+ renderSimpleErrorMessage (DuplicateTypeArgument name) =
591591 line $ "Duplicate type argument " ++ show name
592− goSimple (DuplicateValueDeclaration nm) =
592+ renderSimpleErrorMessage (DuplicateValueDeclaration nm) =
593593 line $ "Duplicate value declaration for " ++ showIdent nm
594− goSimple (ArgListLengthsDiffer ident) =
594+ renderSimpleErrorMessage (ArgListLengthsDiffer ident) =
595595 line $ "Argument list lengths differ in declaration " ++ showIdent ident
596− goSimple (OverlappingArgNames ident) =
596+ renderSimpleErrorMessage (OverlappingArgNames ident) =
597597 line $ "Overlapping names in function/binder" ++ foldMap ((" in declaration" ++) . showIdent) ident
598− goSimple (MissingClassMember ident) =
598+ renderSimpleErrorMessage (MissingClassMember ident) =
599599 line $ "Member " ++ showIdent ident ++ " has not been implemented"
600− goSimple (ExtraneousClassMember ident) =
600+ renderSimpleErrorMessage (ExtraneousClassMember ident) =
601601 line $ "Member " ++ showIdent ident ++ " is not a member of the class being instantiated"
602− goSimple (ExpectedType ty kind) =
602+ renderSimpleErrorMessage (ExpectedType ty kind) =
603603 paras [ line "In a type-annotated expression x :: t, the type t must have kind *."
604− , line $ "The error arises from the type " ++ prettyPrintType ty ++ " having the kind " ++ prettyPrintKind kind ++ " instead."
604+ , line "The error arises from the type"
605+ , indent $ typeAsBox ty
606+ , line "having the kind"
607+ , indent $ line $ prettyPrintKind kind
608+ , line "instead."
605609 ]
606− goSimple (IncorrectConstructorArity nm) =
610+ renderSimpleErrorMessage (IncorrectConstructorArity nm) =
607611 line $ "Wrong number of arguments to constructor " ++ showQualified runProperName nm
608− goSimple SubsumptionCheckFailed = line "Unable to check type subsumption"
609− goSimple (ExprDoesNotHaveType expr ty) =
612+ renderSimpleErrorMessage SubsumptionCheckFailed = line "Unable to check type subsumption"
613+ renderSimpleErrorMessage (ExprDoesNotHaveType expr ty) =
610614 paras [ line "Expression"
611− , indent $ line $ prettyPrintValue expr
615+ , indent $ prettyPrintValue expr
612616 , line "does not have type"
613− , indent $ line $ prettyPrintType ty
617+ , indent $ typeAsBox ty
614618 ]
615− goSimple (PropertyIsMissing prop row) =
616− line $ "Row " ++ prettyPrintRow row ++ " lacks required property " ++ show prop
617− goSimple (CannotApplyFunction fn arg) =
619+ renderSimpleErrorMessage (PropertyIsMissing prop row) =
620+ paras [ line "Row"
621+ , indent $ prettyPrintRowWith '(' ')' row
622+ , line $ "lacks required property " ++ show prop
623+ ]
624+ renderSimpleErrorMessage (CannotApplyFunction fn arg) =
618625 paras [ line "Cannot apply function of type"
619− , indent $ line $ prettyPrintType fn
626+ , indent $ typeAsBox fn
620627 , line "to argument"
621− , indent $ line $ prettyPrintValue arg
628+ , indent $ prettyPrintValue arg
622629 ]
623− goSimple TypeSynonymInstance =
630+ renderSimpleErrorMessage TypeSynonymInstance =
624631 line "Type synonym instances are disallowed"
625− goSimple (OrphanInstance nm cnm ts) =
626− paras [ line $ "Instance " ++ showIdent nm ++ " for " ++ showQualified runProperName cnm ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ " is an orphan instance."
632+ renderSimpleErrorMessage (OrphanInstance nm cnm ts) =
633+ paras [ line $ "Instance " ++ showIdent nm ++ " for "
634+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName cnm)
635+ , Box.vcat Box.left (map typeAtomAsBox ts)
636+ ]
637+ , line "is an orphan instance."
627638 , line "An orphan instance is an instance which is defined in neither the class module nor the data type module."
628639 , line "Consider moving the instance, if possible, or using a newtype wrapper."
629640 ]
630− goSimple InvalidNewtype =
641+ renderSimpleErrorMessage InvalidNewtype =
631642 line "Newtypes must define a single constructor with a single argument"
632− goSimple (InvalidInstanceHead ty) =
643+ renderSimpleErrorMessage (InvalidInstanceHead ty) =
633644 paras [ line "Invalid type in class instance head:"
634− , indent $ line $ prettyPrintType ty
645+ , indent $ typeAsBox ty
635646 ]
636− goSimple (TransitiveExportError x ys) =
647+ renderSimpleErrorMessage (TransitiveExportError x ys) =
637648 paras $ line ("An export for " ++ prettyPrintExport x ++ " requires the following to also be exported: ")
638649 : map (line . prettyPrintExport) ys
639− goSimple (ShadowedName nm) =
650+ renderSimpleErrorMessage (ShadowedName nm) =
640651 line $ "Name '" ++ showIdent nm ++ "' was shadowed"
641− goSimple (ShadowedTypeVar tv) =
652+ renderSimpleErrorMessage (ShadowedTypeVar tv) =
642653 line $ "Type variable '" ++ tv ++ "' was shadowed"
643− goSimple (UnusedTypeVar tv) =
654+ renderSimpleErrorMessage (UnusedTypeVar tv) =
644655 line $ "Type variable '" ++ tv ++ "' was declared but not used"
645− goSimple (ClassOperator className opName) =
656+ renderSimpleErrorMessage (ClassOperator className opName) =
646657 paras [ line $ "Class '" ++ runProperName className ++ "' declares operator " ++ showIdent opName ++ "."
647− , indent $ line "This may be disallowed in the future - consider declaring a named member in the class and making the operator an alias:"
648− , indent $ line $ showIdent opName ++ " = someMember"
658+ , line "This may be disallowed in the future - consider declaring a named member in the class and making the operator an alias:"
659+ , indent . line $ showIdent opName ++ " = someMember"
649660 ]
650− goSimple (MisleadingEmptyTypeImport mn name) =
661+ renderSimpleErrorMessage (MisleadingEmptyTypeImport mn name) =
651662 line $ "Importing type " ++ runProperName name ++ "(..) from " ++ runModuleName mn ++ " is misleading as it has no exported data constructors"
652− goSimple (ImportHidingModule name) =
663+ renderSimpleErrorMessage (ImportHidingModule name) =
653664 line $ "Attempted to hide module " ++ runModuleName name ++ " in import expression, this is not permitted"
654− goSimple (WildcardInferredType ty) =
655− line $ "The wildcard type definition has the inferred type " ++ prettyPrintType ty
656− goSimple (NotExhaustivePattern bs b) =
665+ renderSimpleErrorMessage (WildcardInferredType ty) =
666+ paras [ line "The wildcard type definition has the inferred type "
667+ , indent $ typeAsBox ty
668+ ]
669+ renderSimpleErrorMessage (MissingTypeDeclaration ident) =
670+ paras [ line $ "No type declaration was provided for the top-level declaration of " ++ showIdent ident ++ "."
671+ , line "It is good practice to provide type declarations as a form of documentation."
672+ , line "Consider using a type wildcard to display the inferred type:"
673+ , indent $ line $ showIdent ident ++ " :: _"
674+ ]
675+ renderSimpleErrorMessage (NotExhaustivePattern bs b) =
657676 paras $ [ line "A case expression could not be determined to cover all inputs."
658677 , line "The following additional cases are required to cover all inputs:\n"
659678 , Box.hsep 1 Box.left (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs))
660679 ] ++
661680 [ line "..." | not b ]
662− goSimple (OverlappingPattern bs b) =
681+ renderSimpleErrorMessage (OverlappingPattern bs b) =
663682 paras $ [ line "A case expression contains unreachable cases:\n"
664683 , Box.hsep 1 Box.left (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs))
665684 ] ++
666685 [ line "..." | not b ]
667− goSimple IncompleteExhaustivityCheck =
686+ renderSimpleErrorMessage IncompleteExhaustivityCheck =
668687 paras [ line "An exhaustivity check was abandoned due to too many possible cases."
669688 , line "You may want to decomposing your data types into smaller types."
670689 ]
671− go (NotYetDefined names err) =
672− paras [ line $ "The following are not yet defined here: " ++ intercalate ", " (map showIdent names) ++ ":"
673− , indent $ go err
674− ]
675− go (ErrorUnifyingTypes t1 t2 err) =
690+
691+ renderHint :: ErrorMessageHint -> Box.Box
692+ renderHint (NotYetDefined names) =
693+ line $ "The following are not yet defined here: " ++ intercalate ", " (map showIdent names) ++ ":"
694+ renderHint (ErrorUnifyingTypes t1 t2) =
676695 paras [ lineWithLevel "unifying type "
677− , indent $ line $ prettyPrintType t1
696+ , indent $ typeAsBox t1
678697 , line "with type"
679− , indent $ line $ prettyPrintType t2
680− , go err
698+ , indent $ typeAsBox t2
681699 ]
682− go (ErrorInExpression expr err) =
700+ renderHint (ErrorInExpression expr) =
683701 paras [ lineWithLevel "in expression:"
684− , indent $ line $ prettyPrintValue expr
685− , go err
702+ , indent $ prettyPrintValue expr
686703 ]
687− go (ErrorInModule mn err) =
704+ renderHint (ErrorInModule mn) =
688705 paras [ lineWithLevel $ "in module " ++ runModuleName mn ++ ":"
689− , go err
690706 ]
691− go (ErrorInSubsumption t1 t2 err) =
707+ renderHint (ErrorInSubsumption t1 t2) =
692708 paras [ lineWithLevel "checking that type "
693− , indent $ line $ prettyPrintType t1
709+ , indent $ typeAsBox t1
694710 , line "subsumes type"
695− , indent $ line $ prettyPrintType t2
696− , go err
711+ , indent $ typeAsBox t2
697712 ]
698− go (ErrorInInstance name ts err) =
699− paras [ lineWithLevel $ "in type class instance " ++ showQualified runProperName name ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ ":"
700− , go err
713+ renderHint (ErrorInInstance nm ts) =
714+ paras [ lineWithLevel "in type class instance"
715+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
716+ , Box.vcat Box.left (map typeAtomAsBox ts)
717+ ]
701718 ]
702− go (ErrorCheckingKind ty err) =
719+ renderHint (ErrorCheckingKind ty) =
703720 paras [ lineWithLevel "checking kind of type "
704− , indent $ line $ prettyPrintType ty
705− , go err
721+ , indent $ typeAsBox ty
706722 ]
707− go (ErrorInferringType expr err) =
723+ renderHint (ErrorInferringType expr) =
708724 paras [ lineWithLevel "inferring type of value "
709− , indent $ line $ prettyPrintValue expr
710− , go err
725+ , indent $ prettyPrintValue expr
711726 ]
712− go (ErrorCheckingType expr ty err) =
727+ renderHint (ErrorCheckingType expr ty) =
713728 paras [ lineWithLevel "checking that value "
714− , indent $ line $ prettyPrintValue expr
729+ , indent $ prettyPrintValue expr
715730 , line "has type"
716− , indent $ line $ prettyPrintType ty
717− , go err
731+ , indent $ typeAsBox ty
718732 ]
719− go (ErrorInApplication f t a err) =
733+ renderHint (ErrorInApplication f t a) =
720734 paras [ lineWithLevel "applying function"
721− , indent $ line $ prettyPrintValue f
735+ , indent $ prettyPrintValue f
722736 , line "of type"
723− , indent $ line $ prettyPrintType t
737+ , indent $ typeAsBox t
724738 , line "to argument"
725− , indent $ line $ prettyPrintValue a
726− , go err
727− ]
728− go (ErrorInDataConstructor nm err) =
729− paras [ lineWithLevel $ "in data constructor " ++ runProperName nm ++ ":"
730− , go err
731− ]
732− go (ErrorInTypeConstructor nm err) =
733− paras [ lineWithLevel $ "in type constructor " ++ runProperName nm ++ ":"
734− , go err
735− ]
736− go (ErrorInBindingGroup nms err) =
737− paras [ lineWithLevel $ "in binding group " ++ intercalate ", " (map showIdent nms) ++ ":"
738− , go err
739− ]
740− go (ErrorInDataBindingGroup err) =
741− paras [ lineWithLevel $ "in data binding group:"
742− , go err
743− ]
744− go (ErrorInTypeSynonym name err) =
745− paras [ lineWithLevel $ "in type synonym " ++ runProperName name ++ ":"
746− , go err
747− ]
748− go (ErrorInValueDeclaration n err) =
749− paras [ lineWithLevel $ "in value declaration " ++ showIdent n ++ ":"
750− , go err
751− ]
752− go (ErrorInTypeDeclaration n err) =
753− paras [ lineWithLevel $ "in type declaration for " ++ showIdent n ++ ":"
754− , go err
755− ]
756− go (ErrorInForeignImport nm err) =
757− paras [ lineWithLevel $ "in foreign import " ++ showIdent nm ++ ":"
758− , go err
759− ]
760− go (PositionedError srcSpan err) =
761− paras [ lineWithLevel $ "at " ++ displaySourceSpan srcSpan ++ ":"
762− , indent $ go err
763− ]
764− go (SimpleErrorWrapper sem) = goSimple sem
739+ , indent $ prettyPrintValue a
740+ ]
741+ renderHint (ErrorInDataConstructor nm) =
742+ lineWithLevel $ "in data constructor " ++ runProperName nm ++ ":"
743+ renderHint (ErrorInTypeConstructor nm) =
744+ lineWithLevel $ "in type constructor " ++ runProperName nm ++ ":"
745+ renderHint (ErrorInBindingGroup nms) =
746+ lineWithLevel $ "in binding group " ++ intercalate ", " (map showIdent nms) ++ ":"
747+ renderHint ErrorInDataBindingGroup =
748+ lineWithLevel "in data binding group:"
749+ renderHint (ErrorInTypeSynonym name) =
750+ lineWithLevel $ "in type synonym " ++ runProperName name ++ ":"
751+ renderHint (ErrorInValueDeclaration n) =
752+ lineWithLevel $ "in value declaration " ++ showIdent n ++ ":"
753+ renderHint (ErrorInTypeDeclaration n) =
754+ lineWithLevel $ "in type declaration for " ++ showIdent n ++ ":"
755+ renderHint (ErrorInForeignImport nm) =
756+ lineWithLevel $ "in foreign import " ++ showIdent nm ++ ":"
757+ renderHint (PositionedError srcSpan) =
758+ lineWithLevel $ "at " ++ displaySourceSpan srcSpan ++ ":"
765759
766760 lineWithLevel :: String -> Box.Box
767761 lineWithLevel text = line $ show level ++ " " ++ text
@@ -771,23 +765,19 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
771765 Error -> "error"
772766 Warning -> "warning"
773767
774− suggestions :: ErrorMessage -> [Box.Box]
775− suggestions = suggestions' . unwrapErrorMessage
776− where
777− suggestions' (ConflictingImport nm im) = [ line $ "Possible fix: hide " ++ show nm ++ " when importing " ++ runModuleName im ++ ":"
768+ suggestions :: SimpleErrorMessage -> [Box.Box]
769+ suggestions (ConflictingImport nm im) = [ line $ "Possible fix: hide " ++ show nm ++ " when importing " ++ runModuleName im ++ ":"
778770 , indent . line $ "import " ++ runModuleName im ++ " hiding (" ++ nm ++ ")"
779771 ]
780− suggestions' (TypesDoNotUnify t1 t2)
781− | isObject t1 && isFunction t2 = [line "Note that function composition in PureScript is defined using (<<<)"]
782− | otherwise = []
783− suggestions' _ = []
772+ suggestions (TypesDoNotUnify t1 t2)
773+ | isObject t1 && isFunction t2 = [line "Note that function composition in PureScript is defined using (<<<)"]
774+ | otherwise = []
775+ suggestions _ = []
784776
785777 paras :: [Box.Box] -> Box.Box
786778 paras = Box.vcat Box.left
787779
788− -- |
789780 -- Pretty print and export declaration
790− --
791781 prettyPrintExport :: DeclarationRef -> String
792782 prettyPrintExport (TypeRef pn _) = runProperName pn
793783 prettyPrintExport (ValueRef ident) = showIdent ident
@@ -796,38 +786,44 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
796786 prettyPrintExport (ModuleRef name) = "module " ++ runModuleName name
797787 prettyPrintExport (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
798788
799− -- |
800− -- Simplify an error message
801− --
802− simplifyErrorMessage :: ErrorMessage -> ErrorMessage
803− simplifyErrorMessage = unwrap Nothing
789+ -- Hints get added at the front, so we need to reverse them before rendering
790+ reverseHints :: ErrorMessage -> ErrorMessage
791+ reverseHints (ErrorMessage hints simple) = ErrorMessage (reverse hints) simple
792+
793+ -- | Put positional hints at the front of the list
794+ positionHintsFirst :: ErrorMessage -> ErrorMessage
795+ positionHintsFirst (ErrorMessage hints simple) = ErrorMessage (uncurry (++) $ partition (isPositionHint . hintCategory) hints) simple
804796 where
805− unwrap :: Maybe SourceSpan -> ErrorMessage -> ErrorMessage
806− unwrap pos (ErrorInExpression _ err) = unwrap pos err
807− unwrap pos (ErrorInInstance name ts err) = ErrorInInstance name ts (unwrap pos err)
808− unwrap pos (ErrorInSubsumption t1 t2 err) = ErrorInSubsumption t1 t2 (unwrap pos err)
809− unwrap pos (ErrorUnifyingTypes _ _ err) = unwrap pos err
810− unwrap pos (ErrorInferringType _ err) = unwrap pos err
811− unwrap pos (ErrorCheckingType _ _ err) = unwrap pos err
812− unwrap pos (ErrorCheckingKind ty err) = ErrorCheckingKind ty (unwrap pos err)
813− unwrap pos (ErrorInModule mn err) = ErrorInModule mn (unwrap pos err)
814− unwrap pos (ErrorInApplication _ _ _ err) = unwrap pos err
815− unwrap pos (ErrorInDataConstructor nm err) = ErrorInDataConstructor nm (unwrap pos err)
816− unwrap pos (ErrorInTypeConstructor nm err) = ErrorInTypeConstructor nm (unwrap pos err)
817− unwrap pos (ErrorInBindingGroup nms err) = ErrorInBindingGroup nms (unwrap pos err)
818− unwrap pos (ErrorInDataBindingGroup err) = ErrorInDataBindingGroup (unwrap pos err)
819− unwrap pos (ErrorInTypeSynonym nm err) = ErrorInTypeSynonym nm (unwrap pos err)
820− unwrap pos (ErrorInValueDeclaration nm err) = ErrorInValueDeclaration nm (unwrap pos err)
821− unwrap pos (ErrorInTypeDeclaration nm err) = ErrorInTypeDeclaration nm (unwrap pos err)
822− unwrap pos (ErrorInForeignImport nm err) = ErrorInForeignImport nm (unwrap pos err)
823− unwrap pos (NotYetDefined ns err) = NotYetDefined ns (unwrap pos err)
824− unwrap _ (PositionedError pos err) = unwrap (Just pos) err
825− unwrap pos other = wrap pos other
826−
827− wrap :: Maybe SourceSpan -> ErrorMessage -> ErrorMessage
828− wrap Nothing = id
829− wrap (Just pos) = PositionedError pos
797+ isPositionHint :: HintCategory -> Bool
798+ isPositionHint PositionHint = True
799+ isPositionHint OtherHint = True
800+ isPositionHint _ = False
830801
802+ -- | Simplify an error message
803+ simplifyErrorMessage :: ErrorMessage -> ErrorMessage
804+ simplifyErrorMessage (ErrorMessage hints simple) = ErrorMessage (simplifyHints hints) simple
805+ where
806+ -- Take the last instance of each "hint category"
807+ simplifyHints :: [ErrorMessageHint] -> [ErrorMessageHint]
808+ simplifyHints = reverse . nubBy categoriesEqual . reverse
809+
810+ -- Don't remove hints in the "other" category
811+ categoriesEqual :: ErrorMessageHint -> ErrorMessageHint -> Bool
812+ categoriesEqual x y =
813+ case (hintCategory x, hintCategory y) of
814+ (OtherHint, _) -> False
815+ (_, OtherHint) -> False
816+ (c1, c2) -> c1 == c2
817+
818+ hintCategory :: ErrorMessageHint -> HintCategory
819+ hintCategory ErrorCheckingType{} = ExprHint
820+ hintCategory ErrorInferringType{} = ExprHint
821+ hintCategory ErrorInExpression{} = ExprHint
822+ hintCategory ErrorUnifyingTypes{} = CheckHint
823+ hintCategory ErrorInSubsumption{} = CheckHint
824+ hintCategory ErrorInApplication{} = CheckHint
825+ hintCategory PositionedError{} = PositionHint
826+ hintCategory _ = OtherHint
831827
832828-- |
833829-- Pretty print multiple errors
@@ -843,11 +839,11 @@ prettyPrintMultipleWarnings full = renderBox . prettyPrintMultipleWarningsBox fu
843839
844840-- | Pretty print warnings as a Box
845841prettyPrintMultipleWarningsBox :: Bool -> MultipleErrors -> Box.Box
846−prettyPrintMultipleWarningsBox full = flip evalState M.empty . prettyPrintMultipleErrorsWith Warning "Warning found:" "Multiple warnings found:" full
842+prettyPrintMultipleWarningsBox full = flip evalState M.empty . prettyPrintMultipleErrorsWith Warning "Warning found:" "Warning" full
847843
848844-- | Pretty print errors as a Box
849845prettyPrintMultipleErrorsBox :: Bool -> MultipleErrors -> Box.Box
850−prettyPrintMultipleErrorsBox full = flip evalState M.empty . prettyPrintMultipleErrorsWith Error "Error found:" "Multiple errors found:" full
846+prettyPrintMultipleErrorsBox full = flip evalState M.empty . prettyPrintMultipleErrorsWith Error "Error found:" "Error" full
851847
852848prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> State UnknownMap Box.Box
853849prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
@@ -857,15 +853,16 @@ prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
857853 , result
858854 ]
859855prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) = do
860− result <- forM es $ (liftM $ Box.moveRight 2) . prettyPrintSingleError full level
861− return $
862− Box.vcat Box.left [ Box.text intro
863− , Box.vsep 1 Box.left result
864− ]
856+ result <- forM es $ prettyPrintSingleError full level
857+ return $ Box.vsep 1 Box.left $ concat $ zipWith withIntro [1 :: Int ..] result
858+ where
859+ withIntro i err = [ Box.text (intro ++ " " ++ show i ++ " of " ++ show (length es) ++ ":")
860+ , Box.moveRight 2 err
861+ ]
865862
866863-- | Pretty print a Parsec ParseError as a Box
867864prettyPrintParseError :: P.ParseError -> Box.Box
868−prettyPrintParseError = (prettyPrintParseErrorMessages "or" "unknown parse error" "expecting" "unexpected" "end of input") . PE.errorMessages
865+prettyPrintParseError = prettyPrintParseErrorMessages "or" "unknown parse error" "expecting" "unexpected" "end of input" . PE.errorMessages
869866
870867-- |
871868-- Pretty print ParseError detail messages.
@@ -878,9 +875,9 @@ prettyPrintParseErrorMessages msgOr msgUnknown msgExpecting msgUnExpected msgEnd
878875 | otherwise = Box.vcat Box.left $ map Box.text $ clean [showSysUnExpect,showUnExpect,showExpect,showMessages]
879876
880877 where
881− (sysUnExpect,msgs1) = span ((SysUnExpect "") ==) msgs
882− (unExpect,msgs2) = span ((UnExpect "") ==) msgs1
883− (expect,messages) = span ((Expect "") ==) msgs2
878+ (sysUnExpect,msgs1) = span (SysUnExpect "" ==) msgs
879+ (unExpect,msgs2) = span (UnExpect "" ==) msgs1
880+ (expect,messages) = span (Expect "" ==) msgs2
884881
885882 showExpect = showMany msgExpecting expect
886883 showUnExpect = showMany msgUnExpected unExpect
@@ -911,8 +908,9 @@ prettyPrintParseErrorMessages msgOr msgUnknown msgExpecting msgUnExpected msgEnd
911908
912909 clean = nub . filter (not . null)
913910
911+-- | Indent to the right, and pad on top and bottom.
914912indent :: Box.Box -> Box.Box
915−indent = Box.moveRight 2
913+indent = Box.moveUp 1 . Box.moveDown 1 . Box.moveRight 2
916914
917915line :: String -> Box.Box
918916line = Box.text
@@ -928,7 +926,7 @@ renderBox = unlines . map trimEnd . lines . Box.render
928926interpretMultipleErrorsAndWarnings :: (MonadError MultipleErrors m, MonadWriter MultipleErrors m) => (Either MultipleErrors a, MultipleErrors) -> m a
929927interpretMultipleErrorsAndWarnings (err, ws) = do
930928 tell ws
931− either throwError return $ err
929+ either throwError return err
932930
933931-- |
934932-- Rethrow an error with a more detailed error message in the case of failure
@@ -952,8 +950,7 @@ warnAndRethrowWithPosition :: (MonadError MultipleErrors m, MonadWriter Multiple
952950warnAndRethrowWithPosition pos = rethrowWithPosition pos . warnWithPosition pos
953951
954952withPosition :: SourceSpan -> ErrorMessage -> ErrorMessage
955−withPosition _ (PositionedError pos err) = withPosition pos err
956−withPosition pos err = PositionedError pos err
953+withPosition pos (ErrorMessage hints se) = ErrorMessage (PositionedError pos : hints) se
957954
958955-- |
959956-- Collect errors in in parallel
src/Language/PureScript/Linter.hs+5−4
@@ -40,7 +40,7 @@ import Language.PureScript.Linter.Exhaustive as L
4040-- |
4141-- | Right now, this pass only performs a shadowing check.
4242lint :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Module -> m ()
43−lint (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ mapM_ lintDeclaration ds
43+lint (Module _ _ mn ds _) = censor (addHint (ErrorInModule mn)) $ mapM_ lintDeclaration ds
4444 where
4545 moduleNames :: S.Set Ident
4646 moduleNames = S.fromList (nub (mapMaybe getDeclIdent ds))
@@ -58,9 +58,9 @@ lint (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ mapM_
5858 let (f, _, _, _, _) = everythingWithContextOnValues moduleNames mempty mappend stepD stepE stepB def def
5959
6060 f' :: Declaration -> MultipleErrors
61− f' (PositionedDeclaration pos _ dec) = onErrorMessages (PositionedError pos) (f' dec)
62− f' dec@(ValueDeclaration name _ _ _) = onErrorMessages (ErrorInValueDeclaration name) (f dec <> checkTypeVarsInDecl dec)
63− f' (TypeDeclaration name ty) = onErrorMessages (ErrorInTypeDeclaration name) (checkTypeVars ty)
61+ f' (PositionedDeclaration pos _ dec) = addHint (PositionedError pos) (f' dec)
62+ f' dec@(ValueDeclaration name _ _ _) = addHint (ErrorInValueDeclaration name) (f dec <> checkTypeVarsInDecl dec)
63+ f' (TypeDeclaration name ty) = addHint (ErrorInTypeDeclaration name) (checkTypeVars ty)
6464 f' dec = f dec <> checkTypeVarsInDecl dec
6565
6666 in tell (f' d)
@@ -86,6 +86,7 @@ lint (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ mapM_
8686 stepB :: S.Set Ident -> Binder -> (S.Set Ident, MultipleErrors)
8787 stepB s (VarBinder name) = bindName s name
8888 stepB s (NamedBinder name _) = bindName s name
89+ stepB s (TypedBinder _ b) = stepB s b
8990 stepB s _ = (s, mempty)
9091
9192 bindName :: S.Set Ident -> Ident -> (S.Set Ident, MultipleErrors)
src/Language/PureScript/Linter/Exhaustive.hs+30−20
@@ -46,8 +46,6 @@ import Language.PureScript.Kinds
4646import Language.PureScript.Types as P
4747import Language.PureScript.Errors
4848
49−import Language.PureScript.AST.Traversals (everywhereOnValuesTopDownM)
50−
5149-- | There are two modes of failure for the redudancy check:
5250--
5351-- 1. Exhaustivity was incomeplete due to too many cases, so we couldn't determine redundancy.
@@ -162,6 +160,7 @@ missingCasesSingle _ _ (BooleanBinder bl) (BooleanBinder br)
162160 | bl == br = ([], return True)
163161 | otherwise = ([BooleanBinder bl], return False)
164162missingCasesSingle env mn b (PositionedBinder _ _ cb) = missingCasesSingle env mn b cb
163+missingCasesSingle env mn b (TypedBinder _ cb) = missingCasesSingle env mn b cb
165164missingCasesSingle _ _ b _ = ([b], Left Unknown)
166165
167166-- |
@@ -273,28 +272,39 @@ checkExhaustive env mn numArgs cas = makeResult . first nub $ foldl' step ([init
273272-- Exhaustivity checking over a list of declarations
274273--
275274checkExhaustiveDecls :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Environment -> ModuleName -> [Declaration] -> m ()
276−checkExhaustiveDecls env mn ds =
277− let (f, _, _) = everywhereOnValuesTopDownM return checkExpr return
275+checkExhaustiveDecls env mn = mapM_ onDecl
276+ where
277+ onDecl :: Declaration -> m ()
278+ onDecl (BindingGroupDeclaration bs) = mapM_ (onDecl . convert) bs
279+ where
280+ convert :: (Ident, NameKind, Expr) -> Declaration
281+ convert (name, nk, e) = ValueDeclaration name nk [] (Right e)
282+ onDecl (ValueDeclaration name _ _ (Right e)) = censor (addHint (ErrorInValueDeclaration name)) (onExpr e)
283+ onDecl (PositionedDeclaration pos _ dec) = censor (addHint (PositionedError pos)) (onDecl dec)
284+ onDecl _ = return ()
278285
279− f' :: Declaration -> m Declaration
280− f' d@(BindingGroupDeclaration bs) = mapM_ (f' . convert) bs >> return d
281− where
282− convert :: (Ident, NameKind, Expr) -> Declaration
283− convert (name, nk, e) = ValueDeclaration name nk [] (Right e)
284− f' d@(ValueDeclaration name _ _ _) = censor (onErrorMessages (ErrorInValueDeclaration name)) $ f d
285− f' (PositionedDeclaration pos com dec) = PositionedDeclaration pos com <$> censor (onErrorMessages (PositionedError pos)) (f' dec)
286− -- Don't generate two warnings for desugared dictionaries.
287− f' d@TypeInstanceDeclaration{} = return d
288− f' d = f d
286+ onExpr :: Expr -> m ()
287+ onExpr (UnaryMinus e) = onExpr e
288+ onExpr (ArrayLiteral es) = mapM_ onExpr es
289+ onExpr (ObjectLiteral es) = mapM_ (onExpr . snd) es
290+ onExpr (TypeClassDictionaryConstructorApp _ e) = onExpr e
291+ onExpr (Accessor _ e) = onExpr e
292+ onExpr (ObjectUpdate o es) = onExpr o >> mapM_ (onExpr . snd) es
293+ onExpr (Abs _ e) = onExpr e
294+ onExpr (App e1 e2) = onExpr e1 >> onExpr e2
295+ onExpr (IfThenElse e1 e2 e3) = onExpr e1 >> onExpr e2 >> onExpr e3
296+ onExpr (Case es cas) = checkExhaustive env mn (length es) cas >> mapM_ onExpr es >> mapM_ onCaseAlternative cas
297+ onExpr (TypedValue _ e _) = onExpr e
298+ onExpr (Let ds e) = mapM_ onDecl ds >> onExpr e
299+ onExpr (PositionedValue pos _ e) = censor (addHint (PositionedError pos)) (onExpr e)
300+ onExpr _ = return ()
289301
290− in mapM_ f' ds
291− where
292− checkExpr :: Expr -> m Expr
293− checkExpr c@(Case expr cas) = checkExhaustive env mn (length expr) cas >> return c
294− checkExpr other = return other
302+ onCaseAlternative :: CaseAlternative -> m ()
303+ onCaseAlternative (CaseAlternative _ (Left es)) = mapM_ (\(e, g) -> onExpr e >> onExpr g) es
304+ onCaseAlternative (CaseAlternative _ (Right e)) = onExpr e
295305
296306-- |
297307-- Exhaustivity checking over a single module
298308--
299309checkExhaustiveModule :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Environment -> Module -> m ()
300−checkExhaustiveModule env (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ checkExhaustiveDecls env mn ds
310+checkExhaustiveModule env (Module _ _ mn ds _) = censor (addHint (ErrorInModule mn)) $ checkExhaustiveDecls env mn ds
src/Language/PureScript/Make.hs+125−62
@@ -19,6 +19,8 @@
1919{-# LANGUAGE RankNTypes #-}
2020{-# LANGUAGE RecordWildCards #-}
2121{-# LANGUAGE ScopedTypeVariables #-}
22+{-# LANGUAGE MultiParamTypeClasses #-}
23+{-# LANGUAGE TypeFamilies #-}
2224{-# LANGUAGE CPP #-}
2325
2426module Language.PureScript.Make
@@ -39,29 +41,31 @@ module Language.PureScript.Make
3941#if __GLASGOW_HASKELL__ < 710
4042import Control.Applicative
4143#endif
42−import Control.Arrow ((&&&))
4344import Control.Monad
4445import Control.Monad.Error.Class (MonadError(..))
4546import Control.Monad.Trans.Except
4647import Control.Monad.Reader
4748import Control.Monad.Writer.Strict
4849import Control.Monad.Supply
50+import Control.Monad.Base (MonadBase(..))
51+import Control.Monad.Trans.Control (MonadBaseControl(..))
4952
50−import Data.Function (on)
51−import Data.Either (partitionEithers)
52−import Data.List (sortBy, groupBy, foldl')
53−import Data.Maybe (fromMaybe)
53+import Control.Concurrent.Lifted as C
54+
55+import Data.List (foldl', sort)
56+import Data.Maybe (fromMaybe, catMaybes)
5457import Data.Time.Clock
5558import Data.String (fromString)
5659import Data.Foldable (for_)
5760#if __GLASGOW_HASKELL__ < 710
5861import Data.Traversable (traverse)
5962#endif
63+import Data.Traversable (for)
6064import Data.Version (showVersion)
6165import Data.Aeson (encode, decode)
6266import qualified Data.ByteString.Lazy as B
63−import qualified Data.Map as M
6467import qualified Data.Set as S
68+import qualified Data.Map as M
6569
6670import System.Directory
6771 (doesFileExist, getModificationTime, createDirectoryIfMissing)
@@ -150,65 +154,116 @@ data RebuildPolicy
150154-- If timestamps have not changed, the externs file can be used to provide the module's types without
151155-- having to typecheck the module again.
152156--
153−make :: forall m. (Functor m, Applicative m, Monad m, MonadReader Options m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
157+make :: forall m. (Functor m, Applicative m, Monad m, MonadBaseControl IO m, MonadReader Options m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
154158 => MakeActions m
155159 -> [Module]
156160 -> m Environment
157161make MakeActions{..} ms = do
158− (sorted, graph) <- sortModules $ map importPrim ms
159− toRebuild <- foldM (\s (Module _ _ moduleName' _ _) -> do
160− inputTimestamp <- getInputTimestamp moduleName'
161− outputTimestamp <- getOutputTimestamp moduleName'
162− return $ case (inputTimestamp, outputTimestamp) of
163− (Right (Just t1), Just t2) | t1 < t2 -> s
164− (Left RebuildNever, Just _) -> s
165− _ -> S.insert moduleName' s) S.empty sorted
166−
167− (externs, toBuild) <- partitionEithers <$> rebuildIfNecessary (reverseDependencies graph) toRebuild sorted
168− for_ toBuild lint
169− (desugared, nextVar) <- runSupplyT 0 $ desugar externs toBuild
170− let env = foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
171− evalSupplyT nextVar $ go env desugared
172− where
162+ checkModuleNamesAreUnique
163+
164+ (sorted, graph) <- sortModules ms
165+
166+ barriers <- zip (map getModuleName sorted) <$> replicateM (length ms) ((,) <$> C.newEmptyMVar <*> C.newEmptyMVar)
167+
168+ for_ sorted $ \m -> fork $ do
169+ let deps = fromMaybe (error "make: module not found in dependency graph.") (lookup (getModuleName m) graph)
170+ buildModule barriers (importPrim m) (deps `inOrderOf` map getModuleName sorted)
171+
172+ -- Wait for all threads to complete, and collect errors.
173+ errors <- catMaybes <$> for barriers (takeMVar . snd . snd)
174+
175+ -- All threads have completed, rethrow any caught errors.
176+ unless (null errors) $ throwError (mconcat errors)
177+
178+ -- Bundle up all the externs and return them as an Environment
179+ (warnings, externs) <- unzip . fromMaybe (error "make: externs were missing but no errors reported.") . sequence <$> for barriers (takeMVar . fst . snd)
180+ tell (mconcat warnings)
181+ return $ foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
173182
174− go :: Environment -> [Module] -> SupplyT m Environment
175− go env [] = return env
176− go env (m@(Module ss coms moduleName' _ exps) : ms') = do
177− lift . progress $ CompilingModule moduleName'
178− (checked@(Module _ _ _ elaborated _), env') <- lift . runCheck' env $ typeCheckModule Nothing m
179− checkExhaustiveModule env' checked
180− regrouped <- createBindingGroups moduleName' . collapseBindingGroups $ elaborated
181− let mod' = Module ss coms moduleName' regrouped exps
182− corefn = CF.moduleToCoreFn env' mod'
183− [renamed] = renameInModules [corefn]
184− exts = encode $ moduleToExternsFile mod' env'
185− codegen renamed env' exts
186− go env' ms'
187−
188− rebuildIfNecessary :: M.Map ModuleName [ModuleName] -> S.Set ModuleName -> [Module] -> m [Either ExternsFile Module]
189− rebuildIfNecessary graph = rebuildIfNecessary'
190− where
191− rebuildIfNecessary' :: S.Set ModuleName -> [Module] -> m [Either ExternsFile Module]
192− rebuildIfNecessary' _ [] = return []
193− rebuildIfNecessary' toRebuild (m@(Module _ _ moduleName' _ _) : ms')
194− | moduleName' `S.member` toRebuild = rebuild toRebuild m moduleName' ms'
195− rebuildIfNecessary' toRebuild (m@(Module _ _ moduleName' _ _) : ms') = do
196− (_, externsJson) <- readExterns moduleName'
197− case decode externsJson of
198− Just externs
199− | efVersion externs == showVersion Paths.version -> (Left externs :) <$> rebuildIfNecessary' toRebuild ms'
200− _ -> rebuild toRebuild m moduleName' ms'
201−
202− rebuild :: S.Set ModuleName -> Module -> ModuleName -> [Module] -> m [Either ExternsFile Module]
203− rebuild toRebuild m moduleName ms' = do
204− let deps = fromMaybe [] $ moduleName `M.lookup` graph
205− (Right m :) <$> rebuildIfNecessary' (toRebuild `S.union` S.fromList deps) ms'
206−
207−reverseDependencies :: ModuleGraph -> M.Map ModuleName [ModuleName]
208−reverseDependencies g = combine [ (dep, mn) | (mn, deps) <- g, dep <- deps ]
209183 where
210− combine :: (Ord a) => [(a, b)] -> M.Map a [b]
211− combine = M.fromList . map ((fst . head) &&& map snd) . groupBy ((==) `on` fst) . sortBy (compare `on` fst)
184+ checkModuleNamesAreUnique :: m ()
185+ checkModuleNamesAreUnique =
186+ case findDuplicate (map getModuleName ms) of
187+ Nothing -> return ()
188+ Just mn -> throwError . errorMessage $ DuplicateModuleName mn
189+
190+ -- Verify that a list of values has unique keys
191+ findDuplicate :: (Ord a) => [a] -> Maybe a
192+ findDuplicate = go . sort
193+ where
194+ go (x : y : xs)
195+ | x == y = Just x
196+ | otherwise = go (y : xs)
197+ go _ = Nothing
198+
199+ -- Sort a list so its elements appear in the same order as in another list.
200+ inOrderOf :: (Ord a) => [a] -> [a] -> [a]
201+ inOrderOf xs ys = let s = S.fromList xs in filter (`S.member` s) ys
202+
203+ buildModule :: [(ModuleName, (C.MVar (Maybe (MultipleErrors, ExternsFile)), C.MVar (Maybe MultipleErrors)))] -> Module -> [ModuleName] -> m ()
204+ buildModule barriers m@(Module _ _ moduleName _ _) deps = flip catchError (markComplete Nothing . Just) $ do
205+ -- We need to wait for dependencies to be built, before checking if the current
206+ -- module should be rebuilt, so the first thing to do is to wait on the
207+ -- MVars for the module's dependencies.
208+ mexterns <- fmap unzip . sequence <$> mapM (readMVar . fst . fromMaybe (error "make: no barrier") . flip lookup barriers) deps
209+
210+ outputTimestamp <- getOutputTimestamp moduleName
211+ dependencyTimestamp <- maximumMaybe <$> mapM (fmap shouldExist . getOutputTimestamp) deps
212+ inputTimestamp <- getInputTimestamp moduleName
213+
214+ let shouldRebuild = case (inputTimestamp, dependencyTimestamp, outputTimestamp) of
215+ (Right (Just t1), Just t3, Just t2) -> t1 > t2 || t3 > t2
216+ (Right (Just t1), Nothing, Just t2) -> t1 > t2
217+ (Left RebuildNever, _, Just _) -> False
218+ _ -> True
219+
220+ let rebuild =
221+ case mexterns of
222+ Just (_, externs) -> do
223+ (exts, warnings) <- listen $ do
224+ progress $ CompilingModule moduleName
225+ let env = foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
226+ lint m
227+ ([desugared], nextVar) <- runSupplyT 0 $ desugar externs [m]
228+ (checked@(Module ss coms _ elaborated exps), env') <- runCheck' env $ typeCheckModule desugared
229+ checkExhaustiveModule env' checked
230+ regrouped <- createBindingGroups moduleName . collapseBindingGroups $ elaborated
231+ let mod' = Module ss coms moduleName regrouped exps
232+ corefn = CF.moduleToCoreFn env' mod'
233+ [renamed] = renameInModules [corefn]
234+ exts = moduleToExternsFile mod' env'
235+ evalSupplyT nextVar $ codegen renamed env' $ encode exts
236+ return exts
237+ markComplete (Just (warnings, exts)) Nothing
238+ Nothing -> markComplete Nothing Nothing
239+
240+ if shouldRebuild
241+ then rebuild
242+ else do
243+ mexts <- decodeExterns . snd <$> readExterns moduleName
244+ case mexts of
245+ Just exts -> markComplete (Just (mempty, exts)) Nothing
246+ Nothing -> rebuild
247+ where
248+ markComplete :: Maybe (MultipleErrors, ExternsFile) -> Maybe MultipleErrors -> m ()
249+ markComplete externs errors = do
250+ putMVar (fst $ fromMaybe (error "make: no barrier") $ lookup moduleName barriers) externs
251+ putMVar (snd $ fromMaybe (error "make: no barrier") $ lookup moduleName barriers) errors
252+
253+ maximumMaybe :: (Ord a) => [a] -> Maybe a
254+ maximumMaybe [] = Nothing
255+ maximumMaybe xs = Just $ maximum xs
256+
257+ -- Make sure a dependency exists
258+ shouldExist :: Maybe UTCTime -> UTCTime
259+ shouldExist (Just t) = t
260+ shouldExist _ = error "make: dependency should already have been built."
261+
262+ decodeExterns :: B.ByteString -> Maybe ExternsFile
263+ decodeExterns bs = do
264+ externs <- decode bs
265+ guard $ efVersion externs == showVersion Paths.version
266+ return externs
212267
213268-- |
214269-- Add an import declaration for a module if it does not already explicitly import it.
@@ -231,6 +286,14 @@ importPrim = addDefaultImport (ModuleName [ProperName C.prim])
231286newtype Make a = Make { unMake :: ReaderT Options (WriterT MultipleErrors (ExceptT MultipleErrors IO)) a }
232287 deriving (Functor, Applicative, Monad, MonadIO, MonadError MultipleErrors, MonadWriter MultipleErrors, MonadReader Options)
233288
289+instance MonadBase IO Make where
290+ liftBase = liftIO
291+
292+instance MonadBaseControl IO Make where
293+ type StM Make a = Either MultipleErrors (a, MultipleErrors)
294+ liftBaseWith f = Make $ liftBaseWith $ \q -> f (q . unMake)
295+ restoreM = Make . restoreM
296+
234297-- |
235298-- Execute a 'Make' monad, returning either errors, or the result of the compile plus any warnings.
236299--
@@ -305,15 +368,15 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
305368 requiresForeign = not . null . CF.moduleForeign
306369
307370 getTimestamp :: FilePath -> Make (Maybe UTCTime)
308− getTimestamp path = makeIO (const (SimpleErrorWrapper $ CannotGetFileInfo path)) $ do
371+ getTimestamp path = makeIO (const (ErrorMessage [] $ CannotGetFileInfo path)) $ do
309372 exists <- doesFileExist path
310373 traverse (const $ getModificationTime path) $ guard exists
311374
312375 readTextFile :: FilePath -> Make B.ByteString
313− readTextFile path = makeIO (const (SimpleErrorWrapper $ CannotReadFile path)) $ B.readFile path
376+ readTextFile path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ B.readFile path
314377
315378 writeTextFile :: FilePath -> B.ByteString -> Make ()
316− writeTextFile path text = makeIO (const (SimpleErrorWrapper $ CannotWriteFile path)) $ do
379+ writeTextFile path text = makeIO (const (ErrorMessage [] $ CannotWriteFile path)) $ do
317380 mkdirp path
318381 B.writeFile path text
319382 where
src/Language/PureScript/ModuleDependencies.hs+9−7
@@ -23,20 +23,17 @@ import Control.Monad.Error.Class (MonadError(..))
2323
2424import Data.Graph
2525import Data.List (nub)
26−import Data.Maybe (mapMaybe)
26+import Data.Maybe (fromMaybe, mapMaybe)
2727
2828import Language.PureScript.AST
2929import Language.PureScript.Names
3030import Language.PureScript.Types
3131import Language.PureScript.Errors
3232
33−-- |
34−-- A list of modules with their dependencies
35−--
33+-- | A list of modules with their transitive dependencies
3634type ModuleGraph = [(ModuleName, [ModuleName])]
3735
38−-- |
39−-- Sort a collection of modules based on module dependencies.
36+-- | Sort a collection of modules based on module dependencies.
4037--
4138-- Reports an error if the module graph contains a cycle.
4239--
@@ -44,7 +41,12 @@ sortModules :: (MonadError MultipleErrors m) => [Module] -> m ([Module], ModuleG
4441sortModules ms = do
4542 let verts = map (\m@(Module _ _ _ ds _) -> (m, getModuleName m, nub (concatMap usedModules ds))) ms
4643 ms' <- mapM toModule $ stronglyConnComp verts
47− let moduleGraph = map (\(_, mn, deps) -> (mn, deps)) verts
44+ let (graph, fromVertex, toVertex) = graphFromEdges verts
45+ moduleGraph = do (_, mn, _) <- verts
46+ let v = fromMaybe (error "sortModules: vertex not found") (toVertex mn)
47+ deps = reachable graph v
48+ toKey i = case fromVertex i of (_, key, _) -> key
49+ return (mn, filter (/= mn) (map toKey deps))
4850 return (ms', moduleGraph)
4951
5052-- |
src/Language/PureScript/Names.hs+4
@@ -104,6 +104,10 @@ qualify _ (Qualified (Just m) a) = (m, a)
104104mkQualified :: a -> ModuleName -> Qualified a
105105mkQualified name mn = Qualified (Just mn) name
106106
107+-- | Remove the module name from a qualified name
108+disqualify :: Qualified a -> a
109+disqualify (Qualified _ a) = a
110+
107111-- |
108112-- Checks whether a qualified value is actually qualified with a module reference
109113--
src/Language/PureScript/Parser/Declarations.hs+18−18
@@ -176,9 +176,9 @@ parseImportDeclaration' = do
176176
177177parseDeclarationRef :: TokenParser DeclarationRef
178178parseDeclarationRef =
179− parseModuleRef <|> (
180− withSourceSpan PositionedDeclarationRef $
181− ValueRef <$> parseIdent
179+ parseModuleRef <|>
180+ withSourceSpan PositionedDeclarationRef
181+ (ValueRef <$> parseIdent
182182 <|> do name <- properName
183183 dctors <- P.optionMaybe $ parens (symbol' ".." *> pure Nothing <|> Just <$> commaSep properName)
184184 return $ maybe (TypeClassRef name) (TypeRef name) dctors
@@ -204,8 +204,8 @@ parseTypeClassDeclaration = do
204204 mark (P.many (same *> positioned parseTypeDeclaration))
205205 return $ TypeClassDeclaration className idents implies members
206206
207−parseTypeInstanceDeclaration :: TokenParser Declaration
208−parseTypeInstanceDeclaration = do
207+parseInstanceDeclaration :: TokenParser (TypeInstanceBody -> Declaration)
208+parseInstanceDeclaration = do
209209 reserved "instance"
210210 name <- parseIdent <* indented <* doubleColon
211211 deps <- P.optionMaybe $ do
@@ -215,24 +215,21 @@ parseTypeInstanceDeclaration = do
215215 return deps
216216 className <- indented *> parseQualified properName
217217 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
218223 members <- P.option [] . P.try $ do
219224 indented *> reserved "where"
220225 mark (P.many (same *> positioned parseValueDeclaration))
221− return $ TypeInstanceDeclaration name (fromMaybe [] deps) className ty (ExplicitInstance members)
226+ return $ instanceDecl (ExplicitInstance members)
222227
223228parseDerivingInstanceDeclaration :: TokenParser Declaration
224229parseDerivingInstanceDeclaration = do
225230 reserved "derive"
226− reserved "instance"
227− name <- parseIdent <* indented <* doubleColon
228− deps <- P.optionMaybe $ do
229− deps <- parens (commaSep1 ((,) <$> parseQualified properName <*> P.many (noWildcards parseTypeAtom)))
230− indented
231− rfatArrow
232− return deps
233− className <- indented *> parseQualified properName
234− ty <- P.many (indented *> noWildcards parseTypeAtom)
235− return $ TypeInstanceDeclaration name (fromMaybe [] deps) className ty DerivedInstance
231+ instanceDecl <- parseInstanceDeclaration
232+ return $ instanceDecl DerivedInstance
236233
237234positioned :: TokenParser Declaration -> TokenParser Declaration
238235positioned = withSourceSpan PositionedDeclaration
@@ -296,7 +293,7 @@ parseModulesFromFiles toFilePath input = do
296293 collect vss = [ (k, v) | (k, vs) <- vss, v <- vs ]
297294
298295toPositionedError :: P.ParseError -> ErrorMessage
299−toPositionedError perr = PositionedError (SourceSpan name start end) (SimpleErrorWrapper (ErrorParsingModule perr))
296+toPositionedError perr = ErrorMessage [ PositionedError (SourceSpan name start end) ] (ErrorParsingModule perr)
300297 where
301298 name = (P.sourceName . P.errorPos) perr
302299 start = (toSourcePos . P.errorPos) perr
@@ -526,10 +523,13 @@ parseIdentifierAndBinder = do
526523-- Parse a binder
527524--
528525parseBinder :: TokenParser Binder
529−parseBinder = withSourceSpan PositionedBinder (P.buildExpressionParser operators parseBinderAtom)
526+parseBinder = withSourceSpan PositionedBinder (P.buildExpressionParser operators (buildPostfixParser postfixTable parseBinderAtom))
530527 where
531528 -- TODO: remove this deprecation warning in 0.8
532529 operators = [ [ P.Infix (P.try $ C.indented *> colon *> featureWasRemoved "Cons binders are no longer supported. Consider using purescript-lists or purescript-sequences instead.") P.AssocRight ] ]
530+ -- TODO: parsePolyType when adding support for polymorphic types
531+ postfixTable = [ \b -> flip TypedBinder b <$> (P.try (indented *> doubleColon) *> parseType)
532+ ]
533533 parseBinderAtom :: TokenParser Binder
534534 parseBinderAtom = P.choice (map P.try
535535 [ parseNullBinder
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/Common.hs+11
@@ -17,8 +17,11 @@ module Language.PureScript.Pretty.Common where
1717
1818import Control.Monad.State
1919import Data.List (intercalate)
20+
2021import Language.PureScript.Parser.Lexer (reservedPsNames, opChars)
2122
23+import Text.PrettyPrint.Boxes
24+
2225-- |
2326-- Wrap a string in parentheses
2427--
@@ -67,3 +70,11 @@ prettyPrintObjectKey :: String -> String
6770prettyPrintObjectKey s | s `elem` reservedPsNames = show s
6871 | any (`elem` opChars) s = show s
6972 | otherwise = s
73+
74+-- | Place a box before another, vertically when the first box takes up multiple lines.
75+before :: Box -> Box -> Box
76+before b1 b2 | rows b1 > 1 = b1 // b2
77+ | otherwise = b1 <> b2
78+
79+beforeWithSpace :: Box -> Box -> Box
80+beforeWithSpace b1 = before (b1 <> text " ")
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/Pretty/Kinds.hs+2−3
@@ -45,14 +45,13 @@ funKind = mkPattern match
4545 match (FunKind arg ret) = Just (arg, ret)
4646 match _ = Nothing
4747
48−-- |
49−-- Generate a pretty-printed string representing a Kind
50−--
48+-- | Generate a pretty-printed string representing a Kind
5149prettyPrintKind :: Kind -> String
5250prettyPrintKind = fromMaybe (error "Incomplete pattern") . pattern matchKind ()
5351 where
5452 matchKind :: Pattern () Kind String
5553 matchKind = buildPrettyPrinter operators (typeLiterals <+> fmap parens matchKind)
54+
5655 operators :: OperatorTable () Kind String
5756 operators =
5857 OperatorTable [ [ Wrap matchRow $ \_ k -> "# " ++ k]
src/Language/PureScript/Pretty/Types.hs+58−35
@@ -14,13 +14,15 @@
1414-----------------------------------------------------------------------------
1515
1616module Language.PureScript.Pretty.Types (
17+ typeAsBox,
1718 prettyPrintType,
19+ typeAtomAsBox,
1820 prettyPrintTypeAtom,
21+ prettyPrintRowWith,
1922 prettyPrintRow
2023) where
2124
2225import Data.Maybe (fromMaybe)
23−import Data.List (intercalate)
2426
2527import Control.Arrow ((<+>))
2628import Control.PatternArrows
@@ -32,36 +34,56 @@ import Language.PureScript.Pretty.Common
3234import Language.PureScript.Pretty.Kinds
3335import Language.PureScript.Environment
3436
35−typeLiterals :: Pattern () Type String
37+import Text.PrettyPrint.Boxes hiding ((<+>))
38+
39+typeLiterals :: Pattern () Type Box
3640typeLiterals = mkPattern match
3741 where
38− match TypeWildcard = Just "_"
39− match (TypeVar var) = Just var
40− match (PrettyPrintObject row) = Just $ "{ " ++ prettyPrintRow row ++ " }"
41− match (TypeConstructor ctor) = Just $ showQualified runProperName ctor
42− match (TUnknown u) = Just $ '_' : show u
43− match (Skolem name s _) = Just $ name ++ show s
44− match (ConstrainedType deps ty) = Just $ "(" ++ intercalate ", " (map (\(pn, ty') -> showQualified runProperName pn ++ " " ++ unwords (map prettyPrintTypeAtom ty')) deps) ++ ") => " ++ prettyPrintType ty
45− match (SaturatedTypeSynonym name args) = Just $ showQualified runProperName name ++ "<" ++ intercalate "," (map prettyPrintTypeAtom args) ++ ">"
46− match REmpty = Just "()"
47− match row@RCons{} = Just $ '(' : prettyPrintRow row ++ ")"
42+ match TypeWildcard = Just $ text "_"
43+ match (TypeVar var) = Just $ text var
44+ match (PrettyPrintObject row) = Just $ prettyPrintRowWith '{' '}' row
45+ match (TypeConstructor ctor) = Just $ text $ runProperName $ disqualify ctor
46+ match (TUnknown u) = Just $ text $ '_' : show u
47+ match (Skolem name s _) = Just $ text $ name ++ show s
48+ match (ConstrainedType deps ty) = Just $ constraintsAsBox deps ty
49+ match REmpty = Just $ text "()"
50+ match row@RCons{} = Just $ prettyPrintRowWith '(' ')' row
4851 match _ = Nothing
4952
53+constraintsAsBox :: [(Qualified ProperName, [Type])] -> Type -> Box
54+constraintsAsBox [(pn, tys)] ty = text "(" <> constraintAsBox pn tys <> text ") => " <> typeAsBox ty
55+constraintsAsBox xs ty = vcat left (zipWith (\i (pn, tys) -> text (if i == 0 then "( " else ", ") <> constraintAsBox pn tys) [0 :: Int ..] xs) `before` (text ") => " <> typeAsBox ty)
56+
57+constraintAsBox :: Qualified ProperName -> [Type] -> Box
58+constraintAsBox pn tys = hsep 1 left (text (runProperName (disqualify pn)) : map typeAtomAsBox tys)
59+
5060-- |
5161-- Generate a pretty-printed string representing a Row
5262--
53−prettyPrintRow :: Type -> String
54−prettyPrintRow = (\(tys, rest) -> intercalate ", " (map (uncurry nameAndTypeToPs) tys) ++ tailToPs rest) . toList []
63+prettyPrintRowWith :: Char -> Char -> Type -> Box
64+prettyPrintRowWith open close = uncurry listToBox . toList []
5565 where
56− nameAndTypeToPs :: String -> Type -> String
57− nameAndTypeToPs name ty = prettyPrintObjectKey name ++ " :: " ++ prettyPrintType ty
58− tailToPs :: Type -> String
59− tailToPs REmpty = ""
60− tailToPs other = " | " ++ prettyPrintType other
66+ nameAndTypeToPs :: Char -> String -> Type -> Box
67+ nameAndTypeToPs start name ty = text (start : ' ' : prettyPrintObjectKey name ++ " :: ") <> typeAsBox ty
68+
69+ tailToPs :: Type -> Box
70+ tailToPs REmpty = nullBox
71+ tailToPs other = text "| " <> typeAsBox other
72+
73+ listToBox :: [(String, Type)] -> Type -> Box
74+ listToBox [] REmpty = text [open, close]
75+ listToBox [] rest = text [ open, ' ' ] <> tailToPs rest <> text [ ' ', close ]
76+ listToBox ts rest = vcat left $
77+ zipWith (\(nm, ty) i -> nameAndTypeToPs (if i == 0 then open else ',') nm ty) ts [0 :: Int ..] ++
78+ [ tailToPs rest, text [close] ]
79+
6180 toList :: [(String, Type)] -> Type -> ([(String, Type)], Type)
6281 toList tys (RCons name ty row) = toList ((name, ty):tys) row
6382 toList tys r = (tys, r)
6483
84+prettyPrintRow :: Type -> String
85+prettyPrintRow = render . prettyPrintRowWith '(' ')'
86+
6587typeApp :: Pattern () Type (Type, Type)
6688typeApp = mkPattern match
6789 where
@@ -92,19 +114,19 @@ insertPlaceholders = everywhereOnTypesTopDown convertForAlls . everywhereOnTypes
92114 go idents other = PrettyPrintForAll idents other
93115 convertForAlls other = other
94116
95−matchTypeAtom :: Pattern () Type String
96−matchTypeAtom = typeLiterals <+> fmap parens matchType
117+matchTypeAtom :: Pattern () Type Box
118+matchTypeAtom = typeLiterals <+> fmap ((`before` text ")") . (text "(" <>)) matchType
97119
98−matchType :: Pattern () Type String
120+matchType :: Pattern () Type Box
99121matchType = buildPrettyPrinter operators matchTypeAtom
100122 where
101− operators :: OperatorTable () Type String
123+ operators :: OperatorTable () Type Box
102124 operators =
103− OperatorTable [ [ AssocL typeApp $ \f x -> f ++ " " ++ x ]
104− , [ AssocR appliedFunction $ \arg ret -> arg ++ " -> " ++ ret
125+ OperatorTable [ [ AssocL typeApp $ \f x -> f `beforeWithSpace` x ]
126+ , [ AssocR appliedFunction $ \arg ret -> (arg <> text " ") `before` (text "-> " <> ret)
105127 ]
106− , [ Wrap forall_ $ \idents ty -> "forall " ++ unwords idents ++ ". " ++ ty ]
107− , [ Wrap kinded $ \k ty -> ty ++ " :: " ++ prettyPrintKind k ]
128+ , [ Wrap forall_ $ \idents ty -> text ("forall " ++ unwords idents ++ ". ") <> ty ]
129+ , [ Wrap kinded $ \k ty -> ty `before` (text (" :: " ++ prettyPrintKind k)) ]
108130 ]
109131
110132forall_ :: Pattern () Type ([String], Type)
@@ -113,15 +135,16 @@ forall_ = mkPattern match
113135 match (PrettyPrintForAll idents ty) = Just (idents, ty)
114136 match _ = Nothing
115137
116−-- |
117−-- Generate a pretty-printed string representing a Type, as it should appear inside parentheses
118−--
138+typeAtomAsBox :: Type -> Box
139+typeAtomAsBox = fromMaybe (error "Incomplete pattern") . pattern matchTypeAtom () . insertPlaceholders
140+
141+-- | Generate a pretty-printed string representing a Type, as it should appear inside parentheses
119142prettyPrintTypeAtom :: Type -> String
120−prettyPrintTypeAtom = fromMaybe (error "Incomplete pattern") . pattern matchTypeAtom () . insertPlaceholders
143+prettyPrintTypeAtom = render . typeAtomAsBox
121144
145+typeAsBox :: Type -> Box
146+typeAsBox = fromMaybe (error "Incomplete pattern") . pattern matchType () . insertPlaceholders
122147
123−-- |
124−-- Generate a pretty-printed string representing a Type
125−--
148+-- | Generate a pretty-printed string representing a Type
126149prettyPrintType :: Type -> String
127−prettyPrintType = fromMaybe (error "Incomplete pattern") . pattern matchType () . insertPlaceholders
150+prettyPrintType = render . typeAsBox
src/Language/PureScript/Pretty/Values.hs+98−152
@@ -21,174 +21,119 @@ module Language.PureScript.Pretty.Values (
2121 prettyPrintBinderAtom
2222) where
2323
24−import Data.Maybe (fromMaybe)
2524import Data.List (intercalate)
2625
27−import Control.Arrow ((<+>), runKleisli, second)
28−import Control.PatternArrows
29−import Control.Monad.State
30−#if __GLASGOW_HASKELL__ < 710
31−import Control.Applicative
32−#endif
26+import Control.Arrow (second)
3327
3428import Language.PureScript.AST
3529import Language.PureScript.Names
3630import Language.PureScript.Pretty.Common
37−import Language.PureScript.Pretty.Types (prettyPrintType, prettyPrintTypeAtom)
31+import Language.PureScript.Pretty.Types (typeAsBox, typeAtomAsBox)
3832
39−literals :: Pattern PrinterState Expr String
40−literals = mkPattern' match
33+import Text.PrettyPrint.Boxes
34+
35+-- | Render an aligned list of items separated with commas
36+list :: Char -> Char -> (a -> Box) -> [a] -> Box
37+list open close _ [] = text [open, close]
38+list open close f xs = vcat left (zipWith toLine [0 :: Int ..] xs ++ [ text [ close ] ])
4139 where
42− match :: Expr -> StateT PrinterState Maybe String
43− match (NumericLiteral n) = return $ either show show n
44− match (StringLiteral s) = return $ show s
45− match (CharLiteral c) = return $ show c
46− match (BooleanLiteral True) = return "true"
47− match (BooleanLiteral False) = return "false"
48− match (ArrayLiteral xs) = return $ "[" ++ intercalate ", " (map prettyPrintValue xs) ++ "]"
49− match (ObjectLiteral ps) = prettyPrintObject' $ second Just `map` ps
50− match (ObjectConstructor ps) = prettyPrintObject' ps
51− match (ObjectGetter prop) = return $ "(." ++ prop ++ ")"
52− match (TypeClassDictionaryConstructorApp className ps) = concat <$> sequence
53− [ return (showQualified runProperName className ++ "(\n")
54− , match ps
55− , return ")"
56− ]
57− match (Constructor name) = return $ showQualified runProperName name
58− match (Case values binders) = concat <$> sequence
59− [ return "case "
60− , unwords <$> forM values prettyPrintValue'
61− , return " of\n"
62− , withIndent $ prettyPrintMany prettyPrintCaseAlternative binders
63− , currentIndent
64− ]
65− match (Let ds val) = concat <$> sequence
66− [ return "let\n"
67− , withIndent $ prettyPrintMany prettyPrintDeclaration ds
68− , return "\n"
69− , currentIndent
70− , return "in "
71− , prettyPrintValue' val
72− ]
73− match (Var ident) = return $ showQualified showIdent ident
74− match (Do els) = concat <$> sequence
75− [ return "do\n"
76− , withIndent $ prettyPrintMany prettyPrintDoNotationElement els
77− , currentIndent
78− ]
79− match (OperatorSection op (Right val)) = return $ "(" ++ prettyPrintValue op ++ " " ++ prettyPrintValue val ++ ")"
80− match (OperatorSection op (Left val)) = return $ "(" ++ prettyPrintValue val ++ " " ++ prettyPrintValue op ++ ")"
81− match (TypeClassDictionary (name, tys) _) = return $ "<<dict " ++ showQualified runProperName name ++ " " ++ unwords (map prettyPrintTypeAtom tys) ++ ">>"
82− match (SuperClassDictionary name _) = return $ "<<superclass dict " ++ showQualified runProperName name ++ ">>"
83− match (TypedValue _ val _) = prettyPrintValue' val
84− match (PositionedValue _ _ val) = prettyPrintValue' val
85− match _ = mzero
86−
87−prettyPrintDeclaration :: Declaration -> StateT PrinterState Maybe String
88−prettyPrintDeclaration (TypeDeclaration ident ty) = return $ showIdent ident ++ " :: " ++ prettyPrintType ty
89−prettyPrintDeclaration (ValueDeclaration ident _ [] (Right val)) = concat <$> sequence
90− [ return $ showIdent ident ++ " = "
91− , prettyPrintValue' val
92− ]
40+ toLine i a = text [ if i == 0 then open else ',', ' ' ] <> f a
41+
42+prettyPrintObject :: [(String, Maybe Expr)] -> Box
43+prettyPrintObject = list '{' '}' prettyPrintObjectProperty
44+ where
45+ prettyPrintObjectProperty :: (String, Maybe Expr) -> Box
46+ prettyPrintObjectProperty (key, value) = text (prettyPrintObjectKey key ++ ": ") <> maybe (text "_") prettyPrintValue value
47+
48+-- | Pretty-print an expression
49+prettyPrintValue :: Expr -> Box
50+prettyPrintValue (IfThenElse cond th el) =
51+ (text "if " <> prettyPrintValueAtom cond)
52+ // moveRight 2 (vcat left [ text "then " <> prettyPrintValueAtom th
53+ , text "else " <> prettyPrintValueAtom el
54+ ])
55+prettyPrintValue (Accessor prop val) = prettyPrintValueAtom val <> text ("." ++ show prop)
56+prettyPrintValue (ObjectUpdate o ps) = prettyPrintValueAtom o <> text " " <> list '{' '}' (\(key, val) -> text (key ++ " = ") <> prettyPrintValue val) ps
57+prettyPrintValue (ObjectUpdater o ps) = maybe (text "_") prettyPrintValueAtom o <> text " " <> list '{' '}' (\(key, val) -> text (key ++ " = ") <> maybe (text "_") prettyPrintValue val) ps
58+prettyPrintValue (App val arg) = prettyPrintValueAtom val `beforeWithSpace` prettyPrintValueAtom arg
59+prettyPrintValue (Abs (Left arg) val) = text ('\\' : showIdent arg ++ " -> ") // moveRight 2 (prettyPrintValue val)
60+prettyPrintValue (TypeClassDictionaryConstructorApp className ps) =
61+ text (runProperName (disqualify className) ++ " ") <> prettyPrintValueAtom ps
62+prettyPrintValue (Case values binders) =
63+ (text "case " <> foldl1 beforeWithSpace (map prettyPrintValueAtom values) <> text " of") //
64+ moveRight 2 (vcat left (map prettyPrintCaseAlternative binders))
65+prettyPrintValue (Let ds val) =
66+ text "let" //
67+ moveRight 2 (vcat left (map prettyPrintDeclaration ds)) //
68+ (text "in " <> prettyPrintValue val)
69+prettyPrintValue (Do els) =
70+ text "do " <> vcat left (map prettyPrintDoNotationElement els)
71+prettyPrintValue (TypeClassDictionary (name, tys) _) = foldl1 beforeWithSpace $ text ("#dict " ++ runProperName (disqualify name)) : map typeAtomAsBox tys
72+prettyPrintValue (SuperClassDictionary name _) = text $ "#dict " ++ runProperName (disqualify name)
73+prettyPrintValue (TypedValue _ val _) = prettyPrintValue val
74+prettyPrintValue (PositionedValue _ _ val) = prettyPrintValue val
75+prettyPrintValue expr = prettyPrintValueAtom expr
76+
77+-- | Pretty-print an atomic expression, adding parentheses if necessary.
78+prettyPrintValueAtom :: Expr -> Box
79+prettyPrintValueAtom (NumericLiteral n) = text $ either show show n
80+prettyPrintValueAtom (StringLiteral s) = text $ show s
81+prettyPrintValueAtom (CharLiteral c) = text $ show c
82+prettyPrintValueAtom (BooleanLiteral True) = text "true"
83+prettyPrintValueAtom (BooleanLiteral False) = text "false"
84+prettyPrintValueAtom (ArrayLiteral xs) = list '[' ']' prettyPrintValue xs
85+prettyPrintValueAtom (ObjectLiteral ps) = prettyPrintObject $ second Just `map` ps
86+prettyPrintValueAtom (ObjectConstructor ps) = prettyPrintObject ps
87+prettyPrintValueAtom (ObjectGetter prop) = text $ "_." ++ show prop
88+prettyPrintValueAtom (Constructor name) = text $ runProperName (disqualify name)
89+prettyPrintValueAtom (Var ident) = text $ showIdent (disqualify ident)
90+prettyPrintValueAtom (OperatorSection op (Right val)) = ((text "(" <> prettyPrintValue op) `beforeWithSpace` prettyPrintValue val) `before` text ")"
91+prettyPrintValueAtom (OperatorSection op (Left val)) = ((text "(" <> prettyPrintValue val) `beforeWithSpace` prettyPrintValue op) `before` text ")"
92+prettyPrintValueAtom (TypedValue _ val _) = prettyPrintValueAtom val
93+prettyPrintValueAtom (PositionedValue _ _ val) = prettyPrintValueAtom val
94+prettyPrintValueAtom expr = (text "(" <> prettyPrintValue expr) `before` text ")"
95+
96+prettyPrintDeclaration :: Declaration -> Box
97+prettyPrintDeclaration (TypeDeclaration ident ty) =
98+ text (showIdent ident ++ " :: ") <> typeAsBox ty
99+prettyPrintDeclaration (ValueDeclaration ident _ [] (Right val)) =
100+ text (showIdent ident ++ " = ") <> prettyPrintValue val
101+prettyPrintDeclaration (BindingGroupDeclaration ds) =
102+ vsep 1 left (map (prettyPrintDeclaration . toDecl) ds)
103+ where
104+ toDecl (nm, t, e) = ValueDeclaration nm t [] (Right e)
93105prettyPrintDeclaration (PositionedDeclaration _ _ d) = prettyPrintDeclaration d
94106prettyPrintDeclaration _ = error "Invalid argument to prettyPrintDeclaration"
95107
96−prettyPrintCaseAlternative :: CaseAlternative -> StateT PrinterState Maybe String
108+prettyPrintCaseAlternative :: CaseAlternative -> Box
97109prettyPrintCaseAlternative (CaseAlternative binders result) =
98− concat <$> sequence
99− [ return (unwords (map prettyPrintBinderAtom binders))
100− , prettyPrintResult result
101− ]
110+ text (unwords (map prettyPrintBinderAtom binders)) <> prettyPrintResult result
102111 where
103− prettyPrintResult (Left gs) = concat <$> sequence
104− [ return "\n"
105− , withIndent $ prettyPrintMany prettyPrintGuardedValue gs
106− ]
107− prettyPrintResult (Right v) = (" -> " ++) <$> prettyPrintValue' v
108−
109− prettyPrintGuardedValue (grd, val) =
110− concat <$> sequence
111− [ return "| "
112− , prettyPrintValue' grd
113− , return " -> "
114− , prettyPrintValue' val
115− ]
116−
117−prettyPrintDoNotationElement :: DoNotationElement -> StateT PrinterState Maybe String
112+ prettyPrintResult :: Either [(Guard, Expr)] Expr -> Box
113+ prettyPrintResult (Left gs) =
114+ vcat left (map prettyPrintGuardedValue gs)
115+ prettyPrintResult (Right v) = text " -> " <> prettyPrintValue v
116+
117+ prettyPrintGuardedValue :: (Guard, Expr) -> Box
118+ prettyPrintGuardedValue (grd, val) = foldl1 before
119+ [ text " | "
120+ , prettyPrintValue grd
121+ , text " -> "
122+ , prettyPrintValue val
123+ ]
124+
125+prettyPrintDoNotationElement :: DoNotationElement -> Box
118126prettyPrintDoNotationElement (DoNotationValue val) =
119− prettyPrintValue' val
127+ prettyPrintValue val
120128prettyPrintDoNotationElement (DoNotationBind binder val) =
121− concat <$> sequence
122− [ return (prettyPrintBinder binder)
123− , return " <- "
124− , prettyPrintValue' val
125− ]
129+ text (prettyPrintBinder binder ++ " <- ") <> prettyPrintValue val
126130prettyPrintDoNotationElement (DoNotationLet ds) =
127− concat <$> sequence
128− [ return "let "
129− , withIndent $ prettyPrintMany prettyPrintDeclaration ds
130− ]
131+ text "let" //
132+ moveRight 2 (vcat left (map prettyPrintDeclaration ds))
131133prettyPrintDoNotationElement (PositionedDoNotationElement _ _ el) = prettyPrintDoNotationElement el
132134
133−prettyPrintObject' :: [(String, Maybe Expr)] -> StateT PrinterState Maybe String
134−prettyPrintObject' [] = return "{}"
135−prettyPrintObject' ps = return $ "{ " ++ intercalate ", " (map prettyPrintObjectProperty ps) ++ "}"
136− where
137− prettyPrintObjectProperty :: (String, Maybe Expr) -> String
138− prettyPrintObjectProperty (key, value) = prettyPrintObjectKey key ++ ": " ++ maybe "_" prettyPrintValue value
139−
140−ifThenElse :: Pattern PrinterState Expr ((Expr, Expr), Expr)
141−ifThenElse = mkPattern match
142− where
143− match (IfThenElse cond th el) = Just ((th, el), cond)
144− match _ = Nothing
145−
146−accessor :: Pattern PrinterState Expr (String, Expr)
147−accessor = mkPattern match
148− where
149− match (Accessor prop val) = Just (prop, val)
150− match _ = Nothing
151−
152−objectUpdate :: Pattern PrinterState Expr ([String], Expr)
153−objectUpdate = mkPattern match
154− where
155− match (ObjectUpdate o ps) = Just (flip map ps $ \(key, val) -> key ++ " = " ++ prettyPrintValue val, o)
156− match (ObjectUpdater o ps) = Just (flip map ps $ \(key, val) -> key ++ " = " ++ maybe "_" prettyPrintValue val, fromMaybe (Var (Qualified Nothing $ Ident "_")) o)
157− match _ = Nothing
158−
159−app :: Pattern PrinterState Expr (String, Expr)
160−app = mkPattern match
161− where
162− match (App val arg) = Just (prettyPrintValue arg, val)
163− match _ = Nothing
164−
165−lam :: Pattern PrinterState Expr (String, Expr)
166−lam = mkPattern match
167− where
168− match (Abs (Left arg) val) = Just (showIdent arg, val)
169− match _ = Nothing
170−
171−-- |
172−-- Generate a pretty-printed string representing an expression
173−--
174−prettyPrintValue :: Expr -> String
175−prettyPrintValue = fromMaybe (error "Incomplete pattern") . flip evalStateT (PrinterState 0) . prettyPrintValue'
176−
177−prettyPrintValue' :: Expr -> StateT PrinterState Maybe String
178−prettyPrintValue' = runKleisli $ runPattern matchValue
179− where
180− matchValue :: Pattern PrinterState Expr String
181− matchValue = buildPrettyPrinter operators (literals <+> fmap parens matchValue)
182− operators :: OperatorTable PrinterState Expr String
183− operators =
184− OperatorTable [ [ Wrap accessor $ \prop val -> val ++ "." ++ prop ]
185− , [ Wrap objectUpdate $ \ps val -> val ++ "{ " ++ intercalate ", " ps ++ " }" ]
186− , [ Wrap app $ \arg val -> val ++ "(" ++ arg ++ ")" ]
187− , [ Split lam $ \arg val -> "\\" ++ arg ++ " -> " ++ prettyPrintValue val ]
188− , [ Wrap ifThenElse $ \(th, el) cond -> "if " ++ cond ++ " then " ++ prettyPrintValue th ++ " else " ++ prettyPrintValue el ]
189− ]
190−
191135prettyPrintBinderAtom :: Binder -> String
136+
192137prettyPrintBinderAtom NullBinder = "_"
193138prettyPrintBinderAtom (StringBinder str) = show str
194139prettyPrintBinderAtom (CharBinder c) = show c
@@ -196,7 +141,7 @@ prettyPrintBinderAtom (NumberBinder num) = either show show num
196141prettyPrintBinderAtom (BooleanBinder True) = "true"
197142prettyPrintBinderAtom (BooleanBinder False) = "false"
198143prettyPrintBinderAtom (VarBinder ident) = showIdent ident
199−prettyPrintBinderAtom (ConstructorBinder ctor []) = showQualified runProperName ctor
144+prettyPrintBinderAtom (ConstructorBinder ctor []) = runProperName (disqualify ctor)
200145prettyPrintBinderAtom (ObjectBinder bs) =
201146 "{ "
202147 ++ intercalate ", " (map prettyPrintObjectPropertyBinder bs)
@@ -216,7 +161,8 @@ prettyPrintBinderAtom b = parens (prettyPrintBinder b)
216161-- Generate a pretty-printed string representing a Binder
217162--
218163prettyPrintBinder :: Binder -> String
219−prettyPrintBinder (ConstructorBinder ctor []) = showQualified runProperName ctor
220−prettyPrintBinder (ConstructorBinder ctor args) = showQualified runProperName ctor ++ " " ++ unwords (map prettyPrintBinderAtom args)
164+prettyPrintBinder (ConstructorBinder ctor []) = runProperName (disqualify ctor)
165+prettyPrintBinder (ConstructorBinder ctor args) = runProperName (disqualify ctor) ++ " " ++ unwords (map prettyPrintBinderAtom args)
221166prettyPrintBinder (PositionedBinder _ _ binder) = prettyPrintBinder binder
167+prettyPrintBinder (TypedBinder _ binder) = prettyPrintBinder binder
222168prettyPrintBinder b = prettyPrintBinderAtom b
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/BindingGroups.hs+1−1
@@ -184,7 +184,7 @@ toBindingGroup moduleName (CyclicSCC ds') =
184184 cycleError :: (MonadError MultipleErrors m) => Declaration -> [Declaration] -> m a
185185 cycleError (PositionedDeclaration p _ d) ds = rethrowWithPosition p $ cycleError d ds
186186 cycleError (ValueDeclaration n _ _ (Right _)) [] = throwError . errorMessage $ CycleInDeclaration n
187− cycleError d ds@(_:_) = rethrow (onErrorMessages (NotYetDefined (map getIdent ds))) $ cycleError d []
187+ cycleError d ds@(_:_) = rethrow (addHint (NotYetDefined (map getIdent ds))) $ cycleError d []
188188 cycleError _ _ = error "Expected ValueDeclaration"
189189
190190toDataBindingGroup :: (MonadError MultipleErrors m) => SCC Declaration -> m Declaration
src/Language/PureScript/Sugar/CaseDeclarations.hs+3−1
@@ -50,7 +50,7 @@ isLeft (Right _) = False
5050--
5151desugarCasesModule :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => [Module] -> m [Module]
5252desugarCasesModule ms = forM ms $ \(Module ss coms name ds exps) ->
53− rethrow (onErrorMessages (ErrorInModule name)) $
53+ rethrow (addHint (ErrorInModule name)) $
5454 Module ss coms name <$> (desugarCases <=< desugarAbs $ ds) <*> pure exps
5555
5656desugarAbs :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => [Declaration] -> m [Declaration]
@@ -104,12 +104,14 @@ toDecls [ValueDeclaration ident nameKind bs (Right val)] | all isVarBinder bs =
104104 isVarBinder NullBinder = True
105105 isVarBinder (VarBinder _) = True
106106 isVarBinder (PositionedBinder _ _ b) = isVarBinder b
107+ isVarBinder (TypedBinder _ b) = isVarBinder b
107108 isVarBinder _ = False
108109
109110 fromVarBinder :: Binder -> m Ident
110111 fromVarBinder NullBinder = Ident <$> freshName
111112 fromVarBinder (VarBinder name) = return name
112113 fromVarBinder (PositionedBinder _ _ b) = fromVarBinder b
114+ fromVarBinder (TypedBinder _ b) = fromVarBinder b
113115 fromVarBinder _ = error "fromVarBinder: Invalid argument"
114116toDecls ds@(ValueDeclaration ident _ bs result : _) = do
115117 let tuples = map toTuple ds
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+6−3
@@ -98,7 +98,7 @@ desugarImports externs modules = do
9898
9999 renameInModule' :: Env -> Module -> m Module
100100 renameInModule' env m@(Module _ _ mn _ _) =
101− rethrow (onErrorMessages (ErrorInModule mn)) $ do
101+ rethrow (addHint (ErrorInModule mn)) $ do
102102 let (_, imps, exps) = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn env
103103 elaborateImports imps <$> renameInModule env imps (elaborateExports exps m)
104104
@@ -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
@@ -190,6 +190,10 @@ renameInModule env imports (Module ss coms mn decls exps) =
190190 return ((Just pos, bound), v)
191191 updateBinder s@(pos, _) (ConstructorBinder name b) =
192192 (,) s <$> (ConstructorBinder <$> updateDataConstructorName name pos <*> pure b)
193+ updateBinder s (TypedBinder t b) = do
194+ (s'@ (span', _), b') <- updateBinder s b
195+ t' <- updateTypesEverywhere span' t
196+ return (s', TypedBinder t' b')
193197 updateBinder s v =
194198 return (s, v)
195199
@@ -207,7 +211,6 @@ renameInModule env imports (Module ss coms mn decls exps) =
207211 where
208212 updateType :: Type -> m Type
209213 updateType (TypeConstructor name) = TypeConstructor <$> updateTypeName name pos
210− updateType (SaturatedTypeSynonym name tys) = SaturatedTypeSynonym <$> updateTypeName name pos <*> pure tys
211214 updateType (ConstrainedType cs t) = ConstrainedType <$> updateConstraints pos cs <*> pure t
212215 updateType t = return t
213216
src/Language/PureScript/Sugar/Names/Exports.hs+4−5
@@ -43,7 +43,7 @@ import Language.PureScript.Sugar.Names.Env
4343--
4444findExportable :: forall m. (Applicative m, MonadError MultipleErrors m) => Module -> m Exports
4545findExportable (Module _ _ mn ds _) =
46− rethrow (onErrorMessages (ErrorInModule mn)) $ foldM updateExports nullExports ds
46+ rethrow (addHint (ErrorInModule mn)) $ foldM updateExports nullExports ds
4747 where
4848 updateExports :: Exports -> Declaration -> m Exports
4949 updateExports exps (TypeClassDeclaration tcn _ _ ds') = do
@@ -67,7 +67,7 @@ findExportable (Module _ _ mn ds _) =
6767--
6868resolveExports :: forall m. (Applicative m, MonadError MultipleErrors m) => Env -> ModuleName -> Imports -> Exports -> [DeclarationRef] -> m Exports
6969resolveExports env mn imps exps refs =
70− rethrow (onErrorMessages (ErrorInModule mn)) $ do
70+ rethrow (addHint (ErrorInModule mn)) $ do
7171 filtered <- filterModule mn exps refs
7272 foldM elaborateModuleExports filtered refs
7373
@@ -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/Names/Imports.hs+1−1
@@ -64,7 +64,7 @@ findImports = foldM (go Nothing) M.empty
6464--
6565resolveImports :: (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => Env -> Module -> m Imports
6666resolveImports env (Module _ _ currentModule decls _) =
67− censor (onErrorMessages (ErrorInModule currentModule)) $ do
67+ censor (addHint (ErrorInModule currentModule)) $ do
6868 scope <- M.insert currentModule [(Nothing, Implicit, Nothing)] <$> findImports decls
6969 foldM (resolveModuleImport currentModule env) nullImports (M.toList scope)
7070
src/Language/PureScript/Sugar/Operators.hs+1−1
@@ -102,7 +102,7 @@ ensureNoDuplicates m = go $ sortBy (compare `on` fst) m
102102 go [] = return ()
103103 go [_] = return ()
104104 go ((x@(Qualified (Just mn) name), _) : (y, pos) : _) | x == y =
105− rethrow (onErrorMessages (ErrorInModule mn)) $
105+ rethrow (addHint (ErrorInModule mn)) $
106106 rethrowWithPosition pos $
107107 throwError . errorMessage $ MultipleFixities name
108108 go (_ : rest) = go rest
src/Language/PureScript/Sugar/TypeClasses.hs+1−1
@@ -243,7 +243,7 @@ unit = TypeApp tyObject REmpty
243243
244244typeInstanceDictionaryDeclaration :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => Ident -> ModuleName -> [Constraint] -> Qualified ProperName -> [Type] -> [Declaration] -> Desugar m Declaration
245245typeInstanceDictionaryDeclaration name mn deps className tys decls =
246− rethrow (onErrorMessages (ErrorInInstance className tys)) $ do
246+ rethrow (addHint (ErrorInInstance className tys)) $ do
247247 m <- get
248248
249249 -- Lookup the type arguments and member types for the type class
src/Language/PureScript/Sugar/TypeDeclarations.hs+37−33
@@ -15,18 +15,19 @@
1515-----------------------------------------------------------------------------
1616
1717{-# LANGUAGE FlexibleContexts #-}
18+{-# LANGUAGE ScopedTypeVariables #-}
1819{-# LANGUAGE CPP #-}
1920
2021module Language.PureScript.Sugar.TypeDeclarations (
21− desugarTypeDeclarations,
2222 desugarTypeDeclarationsModule
2323) where
2424
2525#if __GLASGOW_HASKELL__ < 710
2626import Control.Applicative
2727#endif
28−import Control.Monad (forM)
28+import Control.Monad (forM, when)
2929import Control.Monad.Error.Class (MonadError(..))
30+import Control.Monad.Writer.Class (MonadWriter(tell))
3031
3132import Language.PureScript.AST
3233import Language.PureScript.Names
@@ -37,36 +38,39 @@ import Language.PureScript.Traversals
3738-- |
3839-- Replace all top level type declarations in a module with type annotations
3940--
40−desugarTypeDeclarationsModule :: (Functor m, Applicative m, MonadError MultipleErrors m) => [Module] -> m [Module]
41+desugarTypeDeclarationsModule :: forall m. (Functor m, Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => [Module] -> m [Module]
4142desugarTypeDeclarationsModule ms = forM ms $ \(Module ss coms name ds exps) ->
42− rethrow (onErrorMessages (ErrorInModule name)) $
43− Module ss coms name <$> desugarTypeDeclarations ds <*> pure exps
44−
45−-- |
46−-- Replace all top level type declarations with type annotations
47−--
48−desugarTypeDeclarations :: (Functor m, Applicative m, MonadError MultipleErrors m) => [Declaration] -> m [Declaration]
49−desugarTypeDeclarations (PositionedDeclaration pos com d : ds) = do
50− (d' : ds') <- rethrowWithPosition pos $ desugarTypeDeclarations (d : ds)
51− return (PositionedDeclaration pos com d' : ds')
52−desugarTypeDeclarations (TypeDeclaration name ty : d : rest) = do
53− (_, nameKind, val) <- fromValueDeclaration d
54− desugarTypeDeclarations (ValueDeclaration name nameKind [] (Right (TypedValue True val ty)) : rest)
43+ rethrow (addHint (ErrorInModule name)) $
44+ Module ss coms name <$> desugarTypeDeclarations True ds <*> pure exps
5545 where
56− fromValueDeclaration :: (Functor m, Applicative m, MonadError MultipleErrors m) => Declaration -> m (Ident, NameKind, Expr)
57− fromValueDeclaration (ValueDeclaration name' nameKind [] (Right val)) | name == name' = return (name', nameKind, val)
58− fromValueDeclaration (PositionedDeclaration pos com d') = do
59− (ident, nameKind, val) <- rethrowWithPosition pos $ fromValueDeclaration d'
60− return (ident, nameKind, PositionedValue pos com val)
61− fromValueDeclaration _ = throwError . errorMessage $ OrphanTypeDeclaration name
62−desugarTypeDeclarations (TypeDeclaration name _ : []) = throwError . errorMessage $ OrphanTypeDeclaration name
63−desugarTypeDeclarations (ValueDeclaration name nameKind bs val : rest) = do
64− let (_, f, _) = everywhereOnValuesTopDownM return go return
65− f' (Left gs) = Left <$> mapM (pairM return f) gs
66− f' (Right v) = Right <$> f v
67− (:) <$> (ValueDeclaration name nameKind bs <$> f' val) <*> desugarTypeDeclarations rest
68− where
69− go (Let ds val') = Let <$> desugarTypeDeclarations ds <*> pure val'
70− go other = return other
71−desugarTypeDeclarations (d:ds) = (:) d <$> desugarTypeDeclarations ds
72−desugarTypeDeclarations [] = return []
46+
47+ desugarTypeDeclarations :: Bool -> [Declaration] -> m [Declaration]
48+ desugarTypeDeclarations reqd (PositionedDeclaration pos com d : ds) = do
49+ (d' : ds') <- rethrowWithPosition pos $ desugarTypeDeclarations reqd (d : ds)
50+ return (PositionedDeclaration pos com d' : ds')
51+ desugarTypeDeclarations reqd (TypeDeclaration name ty : d : rest) = do
52+ (_, nameKind, val) <- fromValueDeclaration d
53+ desugarTypeDeclarations reqd (ValueDeclaration name nameKind [] (Right (TypedValue True val ty)) : rest)
54+ where
55+ fromValueDeclaration :: Declaration -> m (Ident, NameKind, Expr)
56+ fromValueDeclaration (ValueDeclaration name' nameKind [] (Right val)) | name == name' = return (name', nameKind, val)
57+ fromValueDeclaration (PositionedDeclaration pos com d') = do
58+ (ident, nameKind, val) <- rethrowWithPosition pos $ fromValueDeclaration d'
59+ return (ident, nameKind, PositionedValue pos com val)
60+ fromValueDeclaration _ = throwError . errorMessage $ OrphanTypeDeclaration name
61+ desugarTypeDeclarations _ [TypeDeclaration name _] = throwError . errorMessage $ OrphanTypeDeclaration name
62+ desugarTypeDeclarations reqd (ValueDeclaration name nameKind bs val : rest) = do
63+ -- At the top level, match a type signature or emit a warning.
64+ when reqd $ case val of
65+ Right TypedValue{} -> return ()
66+ Left _ -> error "desugarTypeDeclarations: cases were not desugared"
67+ _ -> tell (addHint (ErrorInValueDeclaration name) $ errorMessage $ MissingTypeDeclaration name)
68+ let (_, f, _) = everywhereOnValuesTopDownM return go return
69+ f' (Left gs) = Left <$> mapM (pairM return f) gs
70+ f' (Right v) = Right <$> f v
71+ (:) <$> (ValueDeclaration name nameKind bs <$> f' val) <*> desugarTypeDeclarations reqd rest
72+ where
73+ go (Let ds val') = Let <$> desugarTypeDeclarations False ds <*> pure val'
74+ go other = return other
75+ desugarTypeDeclarations reqd (d:ds) = (:) d <$> desugarTypeDeclarations reqd ds
76+ desugarTypeDeclarations _ [] = return []
src/Language/PureScript/TypeChecker.hs+78−50
@@ -27,7 +27,7 @@ import Language.PureScript.TypeChecker.Types as T
2727import Language.PureScript.TypeChecker.Synonyms as T
2828
2929import Data.Maybe
30−import Data.List (nub, (\\))
30+import Data.List (nub, (\\), sort, group)
3131import Data.Foldable (for_)
3232
3333import qualified Data.Map as M
@@ -51,7 +51,7 @@ addDataType moduleName dtype name args dctors ctorKind = do
5151 env <- getEnv
5252 putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (ctorKind, DataType args dctors) (types env) }
5353 forM_ dctors $ \(dctor, tys) ->
54− warnAndRethrow (onErrorMessages (ErrorInDataConstructor dctor)) $
54+ warnAndRethrow (addHint (ErrorInDataConstructor dctor)) $
5555 addDataConstructor moduleName dtype name (map fst args) dctor tys
5656
5757addDataConstructor :: ModuleName -> DataDeclType -> ProperName -> [String] -> ProperName -> [Type] -> Check ()
@@ -132,12 +132,12 @@ checkTypeSynonyms = void . replaceAllTypeSynonyms
132132--
133133-- * Process module imports
134134--
135−typeCheckAll :: Maybe ModuleName -> ModuleName -> [DeclarationRef] -> [Declaration] -> Check [Declaration]
136−typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFixities ds
135+typeCheckAll :: ModuleName -> [DeclarationRef] -> [Declaration] -> Check [Declaration]
136+typeCheckAll moduleName _ ds = mapM go ds <* mapM_ checkOrphanFixities ds
137137 where
138138 go :: Declaration -> Check Declaration
139139 go (DataDeclaration dtype name args dctors) = do
140− warnAndRethrow (onErrorMessages (ErrorInTypeConstructor name)) $ do
140+ warnAndRethrow (addHint (ErrorInTypeConstructor name)) $ do
141141 when (dtype == Newtype) $ checkNewtype dctors
142142 checkDuplicateTypeArguments $ map fst args
143143 ctorKind <- kindsOf True moduleName name args (concatMap snd dctors)
@@ -150,7 +150,7 @@ typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFix
150150 checkNewtype [(_, _)] = throwError . errorMessage $ InvalidNewtype
151151 checkNewtype _ = throwError . errorMessage $ InvalidNewtype
152152 go (d@(DataBindingGroupDeclaration tys)) = do
153− warnAndRethrow (onErrorMessages ErrorInDataBindingGroup) $ do
153+ warnAndRethrow (addHint ErrorInDataBindingGroup) $ do
154154 let syns = mapMaybe toTypeSynonym tys
155155 let dataDecls = mapMaybe toDataDecl tys
156156 (syn_ks, data_ks) <- kindsOfAll moduleName syns (map (\(_, name, args, dctors) -> (name, args, concatMap snd dctors)) dataDecls)
@@ -171,7 +171,7 @@ typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFix
171171 toDataDecl (PositionedDeclaration _ _ d') = toDataDecl d'
172172 toDataDecl _ = Nothing
173173 go (TypeSynonymDeclaration name args ty) = do
174− warnAndRethrow (onErrorMessages (ErrorInTypeSynonym name)) $ do
174+ warnAndRethrow (addHint (ErrorInTypeSynonym name)) $ do
175175 checkDuplicateTypeArguments $ map fst args
176176 kind <- kindsOf False moduleName name args [ty]
177177 let args' = args `withKinds` kind
@@ -179,17 +179,17 @@ typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFix
179179 return $ TypeSynonymDeclaration name args ty
180180 go (TypeDeclaration{}) = error "Type declarations should have been removed"
181181 go (ValueDeclaration name nameKind [] (Right val)) =
182− warnAndRethrow (onErrorMessages (ErrorInValueDeclaration name)) $ do
182+ warnAndRethrow (addHint (ErrorInValueDeclaration name)) $ do
183183 valueIsNotDefined moduleName name
184− [(_, (val', ty))] <- typesOf mainModuleName moduleName [(name, val)]
184+ [(_, (val', ty))] <- typesOf moduleName [(name, val)]
185185 addValue moduleName name ty nameKind
186186 return $ ValueDeclaration name nameKind [] $ Right val'
187187 go (ValueDeclaration{}) = error "Binders were not desugared"
188188 go (BindingGroupDeclaration vals) =
189− warnAndRethrow (onErrorMessages (ErrorInBindingGroup (map (\(ident, _, _) -> ident) vals))) $ do
189+ warnAndRethrow (addHint (ErrorInBindingGroup (map (\(ident, _, _) -> ident) vals))) $ do
190190 forM_ (map (\(ident, _, _) -> ident) vals) $ \name ->
191191 valueIsNotDefined moduleName name
192− tys <- typesOf mainModuleName moduleName $ map (\(ident, _, ty) -> (ident, ty)) vals
192+ tys <- typesOf moduleName $ map (\(ident, _, ty) -> (ident, ty)) vals
193193 vals' <- forM [ (name, val, nameKind, ty)
194194 | (name, nameKind, _) <- vals
195195 , (name', (val, ty)) <- tys
@@ -203,7 +203,7 @@ typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFix
203203 putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (kind, ExternData) (types env) }
204204 return d
205205 go (d@(ExternDeclaration name ty)) = do
206− warnAndRethrow (onErrorMessages (ErrorInForeignImport name)) $ do
206+ warnAndRethrow (addHint (ErrorInForeignImport name)) $ do
207207 env <- getEnv
208208 kind <- kindOf moduleName ty
209209 guardWith (errorMessage (ExpectedType ty kind)) $ kind == Star
@@ -216,8 +216,14 @@ typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFix
216216 go (d@(TypeClassDeclaration pn args implies tys)) = do
217217 addTypeClass moduleName pn args implies tys
218218 return d
219− go (d@(TypeInstanceDeclaration dictName deps className tys _)) =
220− goInstance d dictName deps className tys
219+ go (d@(TypeInstanceDeclaration dictName deps className tys body)) = rethrow (addHint (ErrorInInstance className tys)) $ do
220+ mapM_ (checkTypeClassInstance moduleName) tys
221+ forM_ deps $ mapM_ (checkTypeClassInstance moduleName) . snd
222+ checkOrphanInstance dictName className tys
223+ _ <- traverseTypeInstanceBody checkInstanceMembers body
224+ let dict = TypeClassDictionaryInScope (Qualified (Just moduleName) dictName) [] className tys (Just deps)
225+ addTypeClassDictionaries (Just moduleName) . M.singleton className $ M.singleton (tcdName dict) dict
226+ return d
221227 go (PositionedDeclaration pos com d) =
222228 warnAndRethrowWithPosition pos $ PositionedDeclaration pos com <$> go d
223229
@@ -229,29 +235,36 @@ typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFix
229235 warnAndRethrowWithPosition pos $ checkOrphanFixities d
230236 checkOrphanFixities _ = return ()
231237
232− goInstance :: Declaration -> Ident -> [Constraint] -> Qualified ProperName -> [Type] -> Check Declaration
233− goInstance d dictName deps className tys = do
234− mapM_ (checkTypeClassInstance moduleName) tys
235− forM_ deps $ mapM_ (checkTypeClassInstance moduleName) . snd
236− checkOrphanInstance moduleName className tys
237− let dict = TypeClassDictionaryInScope (Qualified (Just moduleName) dictName) [] className tys (Just deps)
238− addTypeClassDictionaries (Just moduleName) . M.singleton className $ M.singleton (tcdName dict) dict
239− return d
240−
238+ checkInstanceMembers :: [Declaration] -> Check [Declaration]
239+ checkInstanceMembers instDecls = do
240+ let idents = sort . map head . group . map memberName $ instDecls
241+ for_ (firstDuplicate idents) $ \ident ->
242+ throwError . errorMessage $ DuplicateValueDeclaration ident
243+ return instDecls
241244 where
245+ memberName :: Declaration -> Ident
246+ memberName (ValueDeclaration ident _ _ _) = ident
247+ memberName (PositionedDeclaration _ _ d) = memberName d
248+ memberName _ = error "checkInstanceMembers: Invalid declaration in type instance definition"
242249
243− checkOrphanInstance :: ModuleName -> Qualified ProperName -> [Type] -> Check ()
244− checkOrphanInstance mn (Qualified (Just mn') _) tys'
245− | mn == mn' || any checkType tys' = return ()
246− | otherwise = throwError . errorMessage $ OrphanInstance dictName className tys'
247− where
248− checkType :: Type -> Bool
249− checkType (TypeVar _) = False
250− checkType (TypeConstructor (Qualified (Just mn'') _)) = mn == mn''
251− checkType (TypeConstructor (Qualified Nothing _)) = error "Unqualified type name in checkOrphanInstance"
252− checkType (TypeApp t1 _) = checkType t1
253− checkType _ = error "Invalid type in instance in checkOrphanInstance"
254− checkOrphanInstance _ _ _ = error "Unqualified class name in checkOrphanInstance"
250+ firstDuplicate :: (Eq a) => [a] -> Maybe a
251+ firstDuplicate (x : xs@(y : _))
252+ | x == y = Just x
253+ | otherwise = firstDuplicate xs
254+ firstDuplicate _ = Nothing
255+
256+ checkOrphanInstance :: Ident -> Qualified ProperName -> [Type] -> Check ()
257+ checkOrphanInstance dictName className@(Qualified (Just mn') _) tys'
258+ | moduleName == mn' || any checkType tys' = return ()
259+ | otherwise = throwError . errorMessage $ OrphanInstance dictName className tys'
260+ where
261+ checkType :: Type -> Bool
262+ checkType (TypeVar _) = False
263+ checkType (TypeConstructor (Qualified (Just mn'') _)) = moduleName == mn''
264+ checkType (TypeConstructor (Qualified Nothing _)) = error "Unqualified type name in checkOrphanInstance"
265+ checkType (TypeApp t1 _) = checkType t1
266+ checkType _ = error "Invalid type in instance in checkOrphanInstance"
267+ checkOrphanInstance _ _ _ = error "Unqualified class name in checkOrphanInstance"
255268
256269 -- |
257270 -- This function adds the argument kinds for a type constructor so that they may appear in the externs file,
@@ -267,11 +280,11 @@ typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFix
267280-- Type check an entire module and ensure all types and classes defined within the module that are
268281-- required by exported members are also exported.
269282--
270−typeCheckModule :: Maybe ModuleName -> Module -> Check Module
271−typeCheckModule _ (Module _ _ _ _ Nothing) = error "exports should have been elaborated"
272−typeCheckModule mainModuleName (Module ss coms mn decls (Just exps)) = warnAndRethrow (onErrorMessages (ErrorInModule mn)) $ do
283+typeCheckModule :: Module -> Check Module
284+typeCheckModule (Module _ _ _ _ Nothing) = error "exports should have been elaborated"
285+typeCheckModule (Module ss coms mn decls (Just exps)) = warnAndRethrow (addHint (ErrorInModule mn)) $ do
273286 modify (\s -> s { checkCurrentModule = Just mn })
274− decls' <- typeCheckAll mainModuleName mn exps decls
287+ decls' <- typeCheckAll mn exps decls
275288 forM_ exps $ \e -> do
276289 checkTypesAreExported e
277290 checkClassMembersAreExported e
@@ -280,21 +293,36 @@ typeCheckModule mainModuleName (Module ss coms mn decls (Just exps)) = warnAndRe
280293 where
281294
282295 checkMemberExport :: (Type -> [DeclarationRef]) -> DeclarationRef -> Check ()
296+ checkMemberExport extract dr@(TypeRef name dctors) = do
297+ env <- getEnv
298+ case M.lookup (Qualified (Just mn) name) (typeSynonyms env) of
299+ Nothing -> return ()
300+ Just (_, ty) -> checkExport dr extract ty
301+ case dctors of
302+ Nothing -> return ()
303+ Just dctors' -> forM_ dctors' $ \dctor ->
304+ case M.lookup (Qualified (Just mn) dctor) (dataConstructors env) of
305+ Nothing -> return ()
306+ Just (_, _, ty, _) -> checkExport dr extract ty
307+ return ()
283308 checkMemberExport extract dr@(ValueRef name) = do
284309 ty <- lookupVariable mn (Qualified (Just mn) name)
285− case filter (not . exported) (extract ty) of
286− [] -> return ()
287− hidden -> throwError . errorMessage $ TransitiveExportError dr hidden
288− where
289− exported e = any (exports e) exps
290− exports (TypeRef pn1 _) (TypeRef pn2 _) = pn1 == pn2
291− exports (ValueRef id1) (ValueRef id2) = id1 == id2
292− exports (TypeClassRef pn1) (TypeClassRef pn2) = pn1 == pn2
293− exports (PositionedDeclarationRef _ _ r1) r2 = exports r1 r2
294− exports r1 (PositionedDeclarationRef _ _ r2) = exports r1 r2
295− exports _ _ = False
310+ checkExport dr extract ty
296311 checkMemberExport _ _ = return ()
297312
313+ checkExport :: DeclarationRef -> (Type -> [DeclarationRef]) -> Type -> Check ()
314+ checkExport dr extract ty = case filter (not . exported) (extract ty) of
315+ [] -> return ()
316+ hidden -> throwError . errorMessage $ TransitiveExportError dr hidden
317+ where
318+ exported e = any (exports e) exps
319+ exports (TypeRef pn1 _) (TypeRef pn2 _) = pn1 == pn2
320+ exports (ValueRef id1) (ValueRef id2) = id1 == id2
321+ exports (TypeClassRef pn1) (TypeClassRef pn2) = pn1 == pn2
322+ exports (PositionedDeclarationRef _ _ r1) r2 = exports r1 r2
323+ exports r1 (PositionedDeclarationRef _ _ r2) = exports r1 r2
324+ exports _ _ = False
325+
298326 -- Check that all the type constructors defined in the current module that appear in member types
299327 -- have also been exported from the module
300328 checkTypesAreExported :: DeclarationRef -> Check ()
src/Language/PureScript/TypeChecker/Entailment.hs+15−25
@@ -13,7 +13,6 @@
1313--
1414-----------------------------------------------------------------------------
1515
16−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1716{-# LANGUAGE CPP #-}
1817
1918module Language.PureScript.TypeChecker.Entailment (
@@ -38,10 +37,8 @@ import Control.Monad.Writer.Class (tell)
3837
3938import Language.PureScript.AST
4039import Language.PureScript.Errors
41−import Language.PureScript.Environment
4240import Language.PureScript.Names
4341import Language.PureScript.TypeChecker.Monad
44−import Language.PureScript.TypeChecker.Synonyms
4542import Language.PureScript.TypeChecker.Unify
4643import Language.PureScript.TypeClassDictionaries
4744import Language.PureScript.Types
@@ -51,8 +48,8 @@ import qualified Language.PureScript.Constants as C
5148-- Check that the current set of type class dictionaries entail the specified type class goal, and, if so,
5249-- return a type class dictionary reference.
5350--
54−entails :: Environment -> ModuleName -> M.Map (Maybe ModuleName) (M.Map (Qualified ProperName) (M.Map (Qualified Ident) TypeClassDictionaryInScope)) -> Constraint -> Check Expr
55−entails env moduleName context = solve
51+entails :: ModuleName -> M.Map (Maybe ModuleName) (M.Map (Qualified ProperName) (M.Map (Qualified Ident) TypeClassDictionaryInScope)) -> Constraint -> Check Expr
52+entails moduleName context = solve
5653 where
5754 forClassName :: Qualified ProperName -> [Type] -> [TypeClassDictionaryInScope]
5855 forClassName cn@(Qualified (Just mn) _) tys = concatMap (findDicts cn) (Nothing : Just mn : map Just (mapMaybe ctorModules tys))
@@ -75,14 +72,10 @@ entails env moduleName context = solve
7572 go :: Int -> Qualified ProperName -> [Type] -> Check DictionaryValue
7673 go work className' tys' | work > 1000 = throwError . errorMessage $ PossiblyInfiniteInstance className' tys'
7774 go work className' tys' = do
78− -- We need to desugar synonyms here so that forClassName can find the correct modules
79− -- in types hidden inside the synonyms.
80− -- TODO: this can go away when synonyms get desugared up front.
81− tys'' <- mapM expandAllTypeSynonyms tys'
8275 let instances = do
83− tcd <- forClassName className' tys''
76+ tcd <- forClassName className' tys'
8477 -- Make sure the type unifies with the type in the type instance definition
85− subst <- maybeToList . (>>= verifySubstitution) . fmap concat $ zipWithM (typeHeadsAreEqual moduleName env) tys'' (tcdInstanceTypes tcd)
78+ subst <- maybeToList . (>>= verifySubstitution) . fmap concat $ zipWithM (typeHeadsAreEqual moduleName) tys' (tcdInstanceTypes tcd)
8679 return (subst, tcd)
8780 (subst, tcd) <- unique instances
8881 -- Solve any necessary subgoals
@@ -140,7 +133,7 @@ entails env moduleName context = solve
140133 verifySubstitution :: [(String, Type)] -> Maybe [(String, Type)]
141134 verifySubstitution subst = do
142135 let grps = groupBy ((==) `on` fst) . sortBy (compare `on` fst) $ subst
143− guard (all (pairwise (unifiesWith env) . map snd) grps)
136+ guard (all (pairwise unifiesWith . map snd) grps)
144137 return $ map head grps
145138
146139 valUndefined :: Expr
@@ -150,24 +143,21 @@ entails env moduleName context = solve
150143-- Check whether the type heads of two types are equal (for the purposes of type class dictionary lookup),
151144-- and return a substitution from type variables to types which makes the type heads unify.
152145--
153−typeHeadsAreEqual :: ModuleName -> Environment -> Type -> Type -> Maybe [(String, Type)]
154−typeHeadsAreEqual _ _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []
155−typeHeadsAreEqual _ _ t (TypeVar v) = Just [(v, t)]
156−typeHeadsAreEqual _ _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []
157−typeHeadsAreEqual m e (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m e h1 h2
158− <*> typeHeadsAreEqual m e t1 t2
159−typeHeadsAreEqual m e (SaturatedTypeSynonym name args) t2 = case expandTypeSynonym' e name args of
160− Left _ -> Nothing
161− Right t1 -> typeHeadsAreEqual m e t1 t2
162−typeHeadsAreEqual _ _ REmpty REmpty = Just []
163−typeHeadsAreEqual m e r1@(RCons _ _ _) r2@(RCons _ _ _) =
146+typeHeadsAreEqual :: ModuleName -> Type -> Type -> Maybe [(String, Type)]
147+typeHeadsAreEqual _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []
148+typeHeadsAreEqual _ t (TypeVar v) = Just [(v, t)]
149+typeHeadsAreEqual _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []
150+typeHeadsAreEqual m (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m h1 h2
151+ <*> typeHeadsAreEqual m t1 t2
152+typeHeadsAreEqual _ REmpty REmpty = Just []
153+typeHeadsAreEqual m r1@RCons{} r2@RCons{} =
164154 let (s1, r1') = rowToList r1
165155 (s2, r2') = rowToList r2
166156
167157 int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
168158 sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
169159 sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]
170− in (++) <$> foldMap (\(t1, t2) -> typeHeadsAreEqual m e t1 t2) int
160+ in (++) <$> foldMap (uncurry (typeHeadsAreEqual m)) int
171161 <*> go sd1 r1' sd2 r2'
172162 where
173163 go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Maybe [(String, Type)]
@@ -177,7 +167,7 @@ typeHeadsAreEqual m e r1@(RCons _ _ _) r2@(RCons _ _ _) =
177167 go [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = Just []
178168 go sd r [] (TypeVar v) = Just [(v, rowFromList (sd, r))]
179169 go _ _ _ _ = Nothing
180−typeHeadsAreEqual _ _ _ _ = Nothing
170+typeHeadsAreEqual _ _ _ = Nothing
181171
182172-- |
183173-- Check all values in a list pairwise match a predicate
src/Language/PureScript/TypeChecker/Kinds.hs+4−4
@@ -83,7 +83,7 @@ kindOf _ ty = fst <$> kindOfWithScopedVars ty
8383--
8484kindOfWithScopedVars :: Type -> Check (Kind, [(String, Kind)])
8585kindOfWithScopedVars ty =
86− rethrow (onErrorMessages (ErrorCheckingKind ty)) $
86+ rethrow (addHint (ErrorCheckingKind ty)) $
8787 fmap tidyUp . liftUnify $ infer ty
8888 where
8989 tidyUp ((k, args), sub) = ( starIfUnknown (sub $? k)
@@ -161,7 +161,7 @@ starIfUnknown k = k
161161-- Infer a kind for a type
162162--
163163infer :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
164−infer ty = rethrow (onErrorMessages (ErrorCheckingKind ty)) $ infer' ty
164+infer ty = rethrow (addHint (ErrorCheckingKind ty)) $ infer' ty
165165
166166infer' :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
167167infer' (ForAll ident ty _) = do
@@ -215,8 +215,8 @@ infer' other = (, []) <$> go other
215215 return $ Row k1
216216 go (ConstrainedType deps ty) = do
217217 forM_ deps $ \(className, tys) -> do
218− _ <- go $ foldl TypeApp (TypeConstructor className) tys
219− return ()
218+ k <- go $ foldl TypeApp (TypeConstructor className) tys
219+ k =?= Star
220220 k <- go ty
221221 k =?= Star
222222 return Star
src/Language/PureScript/TypeChecker/Rows.hs−1
@@ -46,7 +46,6 @@ checkDuplicateLabels =
4646 where
4747 checkDups :: Type -> Check ()
4848 checkDups (TypeApp t1 t2) = checkDups t1 >> checkDups t2
49− checkDups (SaturatedTypeSynonym _ ts) = mapM_ checkDups ts
5049 checkDups (ForAll _ t _) = checkDups t
5150 checkDups (ConstrainedType args t) = do
5251 mapM_ checkDups $ concatMap snd args
src/Language/PureScript/TypeChecker/Skolems.hs+1−1
@@ -92,7 +92,7 @@ skolemEscapeCheck root@TypedValue{} =
9292 let (_, f, _, _, _) = everythingWithContextOnValues [] [] (++) def go def def def
9393 in case f root of
9494 [] -> return ()
95− ((binding, val) : _) -> throwError . singleError $ ErrorInExpression val $ SimpleErrorWrapper $ EscapedSkolem binding
95+ ((binding, val) : _) -> throwError . singleError $ ErrorMessage [ ErrorInExpression val ] $ EscapedSkolem binding
9696 where
9797 def s _ = (s, [])
9898
src/Language/PureScript/TypeChecker/Subsumption.hs+1−9
@@ -20,7 +20,6 @@ module Language.PureScript.TypeChecker.Subsumption (
2020import Data.List (sortBy)
2121import Data.Ord (comparing)
2222
23−import Control.Monad
2423import Control.Monad.Error.Class (MonadError(..))
2524import Control.Monad.Unify
2625
@@ -29,7 +28,6 @@ import Language.PureScript.Environment
2928import Language.PureScript.Errors
3029import Language.PureScript.TypeChecker.Monad
3130import Language.PureScript.TypeChecker.Skolems
32−import Language.PureScript.TypeChecker.Synonyms
3331import Language.PureScript.TypeChecker.Unify
3432import Language.PureScript.Types
3533
@@ -37,7 +35,7 @@ import Language.PureScript.Types
3735-- Check whether one type subsumes another, rethrowing errors to provide a better error message
3836--
3937subsumes :: Maybe Expr -> Type -> Type -> UnifyT Type Check (Maybe Expr)
40−subsumes val ty1 ty2 = rethrow (onErrorMessages (ErrorInSubsumption ty1 ty2)) $ subsumes' val ty1 ty2
38+subsumes val ty1 ty2 = rethrow (addHint (ErrorInSubsumption ty1 ty2)) $ subsumes' val ty1 ty2
4139
4240-- |
4341-- Check whether one type subsumes another
@@ -57,12 +55,6 @@ subsumes' val (TypeApp (TypeApp f1 arg1) ret1) (TypeApp (TypeApp f2 arg2) ret2)
5755 _ <- subsumes Nothing arg2 arg1
5856 _ <- subsumes Nothing ret1 ret2
5957 return val
60−subsumes' val (SaturatedTypeSynonym name tyArgs) ty2 = do
61− ty1 <- introduceSkolemScope <=< expandTypeSynonym name $ tyArgs
62− subsumes val ty1 ty2
63−subsumes' val ty1 (SaturatedTypeSynonym name tyArgs) = do
64− ty2 <- introduceSkolemScope <=< expandTypeSynonym name $ tyArgs
65− subsumes val ty1 ty2
6658subsumes' val (KindedType ty1 _) ty2 =
6759 subsumes val ty1 ty2
6860subsumes' val ty1 (KindedType ty2 _) =
src/Language/PureScript/TypeChecker/Synonyms.hs+20−66
@@ -9,22 +9,18 @@
99-- Portability :
1010--
1111-- |
12−-- Functions for replacing fully applied type synonyms with the @SaturatedTypeSynonym@ data constructor
12+-- Functions for replacing fully applied type synonyms
1313--
1414-----------------------------------------------------------------------------
1515
1616{-# LANGUAGE FlexibleContexts #-}
1717{-# LANGUAGE MultiParamTypeClasses #-}
18+{-# LANGUAGE PatternGuards #-}
1819{-# LANGUAGE GADTs #-}
1920{-# LANGUAGE CPP #-}
2021
2122module Language.PureScript.TypeChecker.Synonyms (
22− saturateAllTypeSynonyms,
23− desaturateAllTypeSynonyms,
24− replaceAllTypeSynonyms,
25− expandAllTypeSynonyms,
26− expandTypeSynonym,
27− expandTypeSynonym'
23+ replaceAllTypeSynonyms
2824) where
2925
3026import Data.Maybe (fromMaybe)
@@ -38,73 +34,31 @@ import Control.Monad.State
3834
3935import Language.PureScript.Environment
4036import Language.PureScript.Errors
41−import Language.PureScript.Names
4237import Language.PureScript.TypeChecker.Monad
4338import Language.PureScript.Types
4439
4540-- |
46−-- Build a type substitution for a type synonym
41+-- Replace fully applied type synonyms.
4742--
48−buildTypeSubstitution :: M.Map (Qualified ProperName) Int -> Type -> Either ErrorMessage (Maybe Type)
49−buildTypeSubstitution m = go 0 []
43+replaceAllTypeSynonyms' :: Environment -> Type -> Either MultipleErrors Type
44+replaceAllTypeSynonyms' env = everywhereOnTypesTopDownM try
5045 where
51− go :: Int -> [Type] -> Type -> Either ErrorMessage (Maybe Type)
52− go c args (TypeConstructor ctor) | M.lookup ctor m == Just c = return (Just $ SaturatedTypeSynonym ctor args)
53− go c _ (TypeConstructor ctor) | M.lookup ctor m > Just c = throwError $ SimpleErrorWrapper $ PartiallyAppliedSynonym ctor
54− go c args (TypeApp f arg) = go (c + 1) (arg:args) f
55− go _ _ _ = return Nothing
56−
57−-- |
58−-- Replace all type synonyms with the @SaturatedTypeSynonym@ data constructor
59−--
60−saturateAllTypeSynonyms :: M.Map (Qualified ProperName) Int -> Type -> Either ErrorMessage Type
61−saturateAllTypeSynonyms syns = everywhereOnTypesTopDownM replace
62− where
63− replace t = fromMaybe t <$> buildTypeSubstitution syns t
46+ try :: Type -> Either MultipleErrors Type
47+ try t = fromMaybe t <$> go 0 [] t
6448
65−-- |
66−-- \"Desaturate\" @SaturatedTypeSynonym@s
67−--
68−desaturateAllTypeSynonyms :: Type -> Type
69−desaturateAllTypeSynonyms = everywhereOnTypes replaceSaturatedTypeSynonym
70− where
71− replaceSaturatedTypeSynonym (SaturatedTypeSynonym name args) = foldl TypeApp (TypeConstructor name) args
72− replaceSaturatedTypeSynonym t = t
73−
74−-- |
75−-- Replace fully applied type synonyms with the @SaturatedTypeSynonym@ data constructor, which helps generate
76−-- better error messages during unification.
77−--
78−replaceAllTypeSynonyms' :: Environment -> Type -> Either ErrorMessage Type
79−replaceAllTypeSynonyms' env d =
80− let
81− syns = length . fst <$> typeSynonyms env
82− in
83− saturateAllTypeSynonyms syns d
49+ go :: Int -> [Type] -> Type -> Either MultipleErrors (Maybe Type)
50+ go c args (TypeConstructor ctor)
51+ | Just (synArgs, body) <- M.lookup ctor (typeSynonyms env)
52+ , c == length synArgs
53+ = let repl = replaceAllTypeVars (zip (map fst synArgs) args) body
54+ in Just <$> try repl
55+ | Just (synArgs, _) <- M.lookup ctor (typeSynonyms env)
56+ , length synArgs > c
57+ = throwError . errorMessage $ PartiallyAppliedSynonym ctor
58+ go c args (TypeApp f arg) = go (c + 1) (arg : args) f
59+ go _ _ _ = return Nothing
8460
8561replaceAllTypeSynonyms :: (e ~ MultipleErrors, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
8662replaceAllTypeSynonyms d = do
8763 env <- getEnv
88− either (throwError . singleError) return $ replaceAllTypeSynonyms' env d
89−
90−-- |
91−-- Replace a type synonym and its arguments with the aliased type
92−--
93−expandTypeSynonym' :: Environment -> Qualified ProperName -> [Type] -> Either ErrorMessage Type
94−expandTypeSynonym' env name args =
95− case M.lookup name (typeSynonyms env) of
96− Just (synArgs, body) -> do
97− let repl = replaceAllTypeVars (zip (map fst synArgs) args) body
98− replaceAllTypeSynonyms' env repl
99− Nothing -> error "Type synonym was not defined"
100−
101−expandTypeSynonym :: (e ~ MultipleErrors, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Qualified ProperName -> [Type] -> m Type
102−expandTypeSynonym name args = do
103− env <- getEnv
104− either (throwError . singleError) return $ expandTypeSynonym' env name args
105−
106−expandAllTypeSynonyms :: (e ~ MultipleErrors, Functor m, Applicative m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
107−expandAllTypeSynonyms = everywhereOnTypesTopDownM go
108− where
109− go (SaturatedTypeSynonym name args) = expandTypeSynonym name args
110− go other = return other
64+ either throwError return $ replaceAllTypeSynonyms' env d
src/Language/PureScript/TypeChecker/Types.hs+18−58
@@ -67,24 +67,17 @@ import Language.PureScript.TypeChecker.Synonyms
6767import Language.PureScript.TypeChecker.Unify
6868import Language.PureScript.TypeClassDictionaries
6969import Language.PureScript.Types
70−import qualified Language.PureScript.Constants as C
7170
7271-- |
7372-- Infer the types of multiple mutually-recursive values, and return elaborated values including
7473-- type class dictionaries and type annotations.
7574--
76−typesOf :: Maybe ModuleName -> ModuleName -> [(Ident, Expr)] -> Check [(Ident, (Expr, Type))]
77−typesOf mainModuleName moduleName vals = do
75+typesOf :: ModuleName -> [(Ident, Expr)] -> Check [(Ident, (Expr, Type))]
76+typesOf moduleName vals = do
7877 tys <- fmap tidyUp . liftUnifyWarnings replace $ do
7978 (untyped, typed, dict, untypedDict) <- typeDictionaryForBindingGroup moduleName vals
80− ds1 <- parU typed $ \e -> do
81− triple@(_, (_, ty)) <- checkTypedBindingGroupElement moduleName e dict
82− checkMain (fst e) ty
83− return triple
84− ds2 <- forM untyped $ \e -> do
85− triple@(_, (_, ty)) <- typeForBindingGroupElement e dict untypedDict
86− checkMain (fst e) ty
87− return triple
79+ ds1 <- parU typed $ \e -> checkTypedBindingGroupElement moduleName e dict
80+ ds2 <- forM untyped $ \e -> typeForBindingGroupElement e dict untypedDict
8881 return $ ds1 ++ ds2
8982
9083 forM tys $ \(ident, (val, ty)) -> do
@@ -94,21 +87,13 @@ typesOf mainModuleName moduleName vals = do
9487 skolemEscapeCheck val'
9588 -- Check rows do not contain duplicate labels
9689 checkDuplicateLabels val'
97− -- Remove type synonyms placeholders, and replace
98− -- top-level unification variables with named type variables.
99− let val'' = overTypes desaturateAllTypeSynonyms val'
100− ty' = varIfUnknown . desaturateAllTypeSynonyms $ ty
101− return (ident, (val'', ty'))
90+ return (ident, (val', varIfUnknown ty))
10291 where
10392 -- Apply the substitution that was returned from runUnify to both types and (type-annotated) values
10493 tidyUp (ts, sub) = map (\(i, (val, ty)) -> (i, (overTypes (sub $?) val, sub $? ty))) ts
10594 -- Replace all the wildcards types with their inferred types
106− replace sub (SimpleErrorWrapper (WildcardInferredType ty)) = SimpleErrorWrapper $ WildcardInferredType (sub $? ty)
95+ replace sub (ErrorMessage hints (WildcardInferredType ty)) = ErrorMessage hints $ WildcardInferredType (sub $? ty)
10796 replace _ em = em
108− -- If --main is enabled, need to check that `main` has type Eff eff a for some eff, a
109− checkMain nm ty = when (Just moduleName == mainModuleName && nm == Ident C.main) $ do
110− [eff, a] <- replicateM 2 fresh
111− ty =?= TypeApp (TypeApp (TypeConstructor (Qualified (Just (ModuleName [ProperName "Control", ProperName "Monad", ProperName "Eff"])) (ProperName "Eff"))) eff) a
11297
11398type TypeData = M.Map (ModuleName, Ident) (Type, NameKind, NameVisibility)
11499
@@ -182,9 +167,7 @@ replaceTypeClassDictionaries mn =
182167 let (_, f, _) = everywhereOnValuesTopDownM return go return
183168 in f
184169 where
185− go (TypeClassDictionary constraint dicts) = do
186− env <- getEnv
187− entails env mn dicts constraint
170+ go (TypeClassDictionary constraint dicts) = entails mn dicts constraint
188171 go other = return other
189172
190173-- |
@@ -214,7 +197,7 @@ instantiatePolyTypeWithUnknowns val ty = return (val, ty)
214197-- Infer a type for a value, rethrowing any error to provide a more useful error message
215198--
216199infer :: Expr -> UnifyT Type Check Expr
217−infer val = rethrow (onErrorMessages (ErrorInferringType val)) $ infer' val
200+infer val = rethrow (addHint (ErrorInferringType val)) $ infer' val
218201
219202-- |
220203-- Infer a type for a value
@@ -246,15 +229,10 @@ infer' (ObjectUpdate o ps) = do
246229 o' <- TypedValue True <$> check o oldTy <*> pure oldTy
247230 return $ TypedValue True (ObjectUpdate o' newVals) $ TypeApp tyObject $ rowFromList (newTys, row)
248231infer' (Accessor prop val) = do
249− typed@(TypedValue _ _ objTy) <- infer val
250− propTy <- inferProperty objTy prop
251− case propTy of
252− Nothing -> do
253− field <- fresh
254− rest <- fresh
255− _ <- subsumes Nothing objTy (TypeApp tyObject (RCons prop field rest))
256− return $ TypedValue True (Accessor prop typed) field
257− Just ty -> return $ TypedValue True (Accessor prop typed) ty
232+ field <- fresh
233+ rest <- fresh
234+ typed <- check val (TypeApp tyObject (RCons prop field rest))
235+ return $ TypedValue True (Accessor prop typed) field
258236infer' (Abs (Left arg) ret) = do
259237 ty <- fresh
260238 Just moduleName <- checkCurrentModule <$> get
@@ -339,21 +317,6 @@ inferLetBinding seen (PositionedDeclaration pos com d : ds) ret j = warnAndRethr
339317 return (PositionedDeclaration pos com d' : ds', val')
340318inferLetBinding _ _ _ _ = error "Invalid argument to inferLetBinding"
341319
342−-- |
343−-- Infer the type of a property inside a record with a given type
344−--
345−inferProperty :: Type -> String -> UnifyT Type Check (Maybe Type)
346−inferProperty (TypeApp obj row) prop | obj == tyObject = do
347− let (props, _) = rowToList row
348− return $ lookup prop props
349−inferProperty (SaturatedTypeSynonym name args) prop = do
350− replaced <- introduceSkolemScope <=< expandTypeSynonym name $ args
351− inferProperty replaced prop
352−inferProperty (ForAll ident ty _) prop = do
353− replaced <- replaceVarWithUnknown ident ty
354− inferProperty replaced prop
355−inferProperty _ _ = return Nothing
356−
357320-- |
358321-- Infer the types of variables brought into scope by a binder
359322--
@@ -407,6 +370,9 @@ inferBinder val (NamedBinder name binder) = do
407370 return $ M.insert name val m
408371inferBinder val (PositionedBinder pos _ binder) =
409372 warnAndRethrowWithPosition pos $ inferBinder val binder
373+-- TODO: When adding support for polymorphic types, check subsumption here
374+-- and change the definition of `binderRequiresMonotype`
375+inferBinder val (TypedBinder ty binder) = val =?= ty >> inferBinder val binder
410376
411377-- | Returns true if a binder requires its argument type to be a monotype.
412378-- | If this is the case, we need to instantiate any polymorphic types before checking binders.
@@ -419,7 +385,7 @@ binderRequiresMonotype _ = True
419385
420386-- | Instantiate polytypes only when necessitated by a binder.
421387instantiateForBinders :: [Expr] -> [CaseAlternative] -> UnifyT Type Check ([Expr], [Type])
422−instantiateForBinders vals cas = fmap unzip $ zipWithM (\val inst -> do
388+instantiateForBinders vals cas = unzip <$> zipWithM (\val inst -> do
423389 TypedValue _ val' ty <- infer val
424390 if inst
425391 then instantiatePolyTypeWithUnknowns val' ty
@@ -457,7 +423,7 @@ checkBinders nvals ret (CaseAlternative binders result : bs) = do
457423-- Check the type of a value, rethrowing errors to provide a better error message
458424--
459425check :: Expr -> Type -> UnifyT Type Check Expr
460−check val ty = rethrow (onErrorMessages (ErrorCheckingType val ty)) $ check' val ty
426+check val ty = rethrow (addHint (ErrorCheckingType val ty)) $ check' val ty
461427
462428-- |
463429-- Check the type of a value
@@ -493,9 +459,6 @@ check' val t@(ConstrainedType constraints ty) = do
493459
494460 instantiateSuperclass :: [String] -> [Type] -> [Type] -> [Type]
495461 instantiateSuperclass args supArgs tys = map (replaceAllTypeVars (zip args tys)) supArgs
496−check' val (SaturatedTypeSynonym name args) = do
497− ty <- introduceSkolemScope <=< expandTypeSynonym name $ args
498− check val ty
499462check' val u@(TUnknown _) = do
500463 val'@(TypedValue _ _ ty) <- infer val
501464 -- Don't unify an unknown with an inferred polytype
@@ -646,7 +609,7 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
646609-- Check the type of a function application, rethrowing errors to provide a better error message
647610--
648611checkFunctionApplication :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
649−checkFunctionApplication fn fnTy arg ret = rethrow (onErrorMessages (ErrorInApplication fn fnTy arg)) $ do
612+checkFunctionApplication fn fnTy arg ret = rethrow (addHint (ErrorInApplication fn fnTy arg)) $ do
650613 subst <- unifyCurrentSubstitution <$> UnifyT get
651614 checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
652615
@@ -674,9 +637,6 @@ checkFunctionApplication' fn u@(TUnknown _) arg ret = do
674637 ret' <- maybe fresh return ret
675638 u =?= function ty ret'
676639 return (ret', App fn arg')
677−checkFunctionApplication' fn (SaturatedTypeSynonym name tyArgs) arg ret = do
678− ty <- introduceSkolemScope <=< expandTypeSynonym name $ tyArgs
679− checkFunctionApplication fn ty arg ret
680640checkFunctionApplication' fn (KindedType ty _) arg ret =
681641 checkFunctionApplication fn ty arg ret
682642checkFunctionApplication' fn (ConstrainedType constraints fnTy) arg ret = do
src/Language/PureScript/TypeChecker/Unify.hs+11−26
@@ -36,11 +36,9 @@ import Control.Monad.Unify
3636import Control.Monad.Writer
3737import Control.Monad.Error.Class (MonadError(..))
3838
39−import Language.PureScript.Environment
4039import Language.PureScript.Errors
4140import Language.PureScript.TypeChecker.Monad
4241import Language.PureScript.TypeChecker.Skolems
43−import Language.PureScript.TypeChecker.Synonyms
4442import Language.PureScript.Types
4543
4644instance Partial Type where
@@ -63,16 +61,12 @@ instance Unifiable Check Type where
6361-- Unify two types, updating the current substitution
6462--
6563unifyTypes :: Type -> Type -> UnifyT Type Check ()
66−unifyTypes t1 t2 = rethrow (onErrorMessages (ErrorUnifyingTypes t1 t2)) $
64+unifyTypes t1 t2 = rethrow (addHint (ErrorUnifyingTypes t1 t2)) $
6765 unifyTypes' t1 t2
6866 where
6967 unifyTypes' (TUnknown u1) (TUnknown u2) | u1 == u2 = return ()
7068 unifyTypes' (TUnknown u) t = u =:= t
7169 unifyTypes' t (TUnknown u) = u =:= t
72− unifyTypes' (SaturatedTypeSynonym name args) ty = do
73− ty1 <- introduceSkolemScope <=< expandTypeSynonym name $ args
74− ty1 `unifyTypes` ty
75− unifyTypes' ty s@(SaturatedTypeSynonym _ _) = s `unifyTypes` ty
7670 unifyTypes' (ForAll ident1 ty1 sc1) (ForAll ident2 ty2 sc2) =
7771 case (sc1, sc2) of
7872 (Just sc1', Just sc2') -> do
@@ -132,10 +126,6 @@ unifyRows r1 r2 =
132126 rest <- fresh
133127 u1 =:= rowFromList (sd2, rest)
134128 u2 =:= rowFromList (sd1, rest)
135− unifyRows' sd1 (SaturatedTypeSynonym name args) sd2 r2' = do
136− r1' <- expandTypeSynonym name $ args
137− unifyRows (rowFromList (sd1, r1')) (rowFromList (sd2, r2'))
138− unifyRows' sd1 r1' sd2 r2'@(SaturatedTypeSynonym _ _) = unifyRows' sd2 r2' sd1 r1'
139129 unifyRows' [] REmpty [] REmpty = return ()
140130 unifyRows' [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = return ()
141131 unifyRows' [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = return ()
@@ -144,26 +134,21 @@ unifyRows r1 r2 =
144134-- |
145135-- Check that two types unify
146136--
147−unifiesWith :: Environment -> Type -> Type -> Bool
148−unifiesWith _ (TUnknown u1) (TUnknown u2) | u1 == u2 = True
149−unifiesWith _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = True
150−unifiesWith _ (TypeVar v1) (TypeVar v2) | v1 == v2 = True
151−unifiesWith _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = True
152−unifiesWith e (TypeApp h1 t1) (TypeApp h2 t2) = unifiesWith e h1 h2 && unifiesWith e t1 t2
153−unifiesWith e (SaturatedTypeSynonym name args) t2 =
154− case expandTypeSynonym' e name args of
155− Left _ -> False
156− Right t1 -> unifiesWith e t1 t2
157−unifiesWith e t1 t2@(SaturatedTypeSynonym _ _) = unifiesWith e t2 t1
158−unifiesWith _ REmpty REmpty = True
159−unifiesWith e r1@(RCons _ _ _) r2@(RCons _ _ _) =
137+unifiesWith :: Type -> Type -> Bool
138+unifiesWith (TUnknown u1) (TUnknown u2) | u1 == u2 = True
139+unifiesWith (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = True
140+unifiesWith (TypeVar v1) (TypeVar v2) | v1 == v2 = True
141+unifiesWith (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = True
142+unifiesWith (TypeApp h1 t1) (TypeApp h2 t2) = h1 `unifiesWith` h2 && t1 `unifiesWith` t2
143+unifiesWith REmpty REmpty = True
144+unifiesWith r1@RCons{} r2@RCons{} =
160145 let (s1, r1') = rowToList r1
161146 (s2, r2') = rowToList r2
162147
163148 int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
164149 sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
165150 sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]
166− in all (\(t1, t2) -> unifiesWith e t1 t2) int && go sd1 r1' sd2 r2'
151+ in all (uncurry unifiesWith) int && go sd1 r1' sd2 r2'
167152 where
168153 go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Bool
169154 go [] REmpty [] REmpty = True
@@ -173,7 +158,7 @@ unifiesWith e r1@(RCons _ _ _) r2@(RCons _ _ _) =
173158 go _ _ [] (TUnknown _) = True
174159 go _ (TUnknown _) _ (TUnknown _) = True
175160 go _ _ _ _ = False
176−unifiesWith _ _ _ = False
161+unifiesWith _ _ = False
177162
178163-- |
179164-- Replace a single type variable with a new unification variable
src/Language/PureScript/Types.hs+2−16
@@ -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
@@ -66,10 +67,6 @@ data Type
6667 --
6768 | TypeApp Type Type
6869 -- |
69− -- A type synonym which is \"saturated\", i.e. fully applied
70− --
71− | SaturatedTypeSynonym (Qualified ProperName) [Type]
72− -- |
7370 -- Forall quantifier
7471 --
7572 | ForAll String Type (Maybe SkolemScope)
@@ -156,12 +153,8 @@ replaceAllTypeVars = go []
156153 where
157154
158155 go :: [String] -> [(String, Type)] -> Type -> Type
159− go _ m (TypeVar v) =
160− case v `lookup` m of
161− Just r -> r
162− Nothing -> TypeVar v
156+ go _ m (TypeVar v) = fromMaybe (TypeVar v) (v `lookup` m)
163157 go bs m (TypeApp t1 t2) = TypeApp (go bs m t1) (go bs m t2)
164− go bs m (SaturatedTypeSynonym name' ts) = SaturatedTypeSynonym name' $ map (go bs m) ts
165158 go bs m f@(ForAll v t sco) | v `elem` keys = go bs (filter ((/= v) . fst) m) f
166159 | v `elem` usedVars =
167160 let v' = genName v (keys ++ bs ++ usedVars)
@@ -200,7 +193,6 @@ freeTypeVariables = nub . go []
200193 go :: [String] -> Type -> [String]
201194 go bound (TypeVar v) | v `notElem` bound = [v]
202195 go bound (TypeApp t1 t2) = go bound t1 ++ go bound t2
203− go bound (SaturatedTypeSynonym _ ts) = concatMap (go bound) ts
204196 go bound (ForAll v t _) = go (v : bound) t
205197 go bound (ConstrainedType cs t) = concatMap (concatMap (go bound) . snd) cs ++ go bound t
206198 go bound (RCons _ t r) = go bound t ++ go bound r
@@ -247,7 +239,6 @@ everywhereOnTypes :: (Type -> Type) -> Type -> Type
247239everywhereOnTypes f = go
248240 where
249241 go (TypeApp t1 t2) = f (TypeApp (go t1) (go t2))
250− go (SaturatedTypeSynonym name tys) = f (SaturatedTypeSynonym name (map go tys))
251242 go (ForAll arg ty sco) = f (ForAll arg (go ty) sco)
252243 go (ConstrainedType cs ty) = f (ConstrainedType (map (fmap (map go)) cs) (go ty))
253244 go (RCons name ty rest) = f (RCons name (go ty) (go rest))
@@ -261,7 +252,6 @@ everywhereOnTypesTopDown :: (Type -> Type) -> Type -> Type
261252everywhereOnTypesTopDown f = go . f
262253 where
263254 go (TypeApp t1 t2) = TypeApp (go (f t1)) (go (f t2))
264− go (SaturatedTypeSynonym name tys) = SaturatedTypeSynonym name (map (go . f) tys)
265255 go (ForAll arg ty sco) = ForAll arg (go (f ty)) sco
266256 go (ConstrainedType cs ty) = ConstrainedType (map (fmap (map (go . f))) cs) (go (f ty))
267257 go (RCons name ty rest) = RCons name (go (f ty)) (go (f rest))
@@ -275,7 +265,6 @@ everywhereOnTypesM :: (Functor m, Applicative m, Monad m) => (Type -> m Type) ->
275265everywhereOnTypesM f = go
276266 where
277267 go (TypeApp t1 t2) = (TypeApp <$> go t1 <*> go t2) >>= f
278− go (SaturatedTypeSynonym name tys) = (SaturatedTypeSynonym name <$> mapM go tys) >>= f
279268 go (ForAll arg ty sco) = (ForAll arg <$> go ty <*> pure sco) >>= f
280269 go (ConstrainedType cs ty) = (ConstrainedType <$> mapM (sndM (mapM go)) cs <*> go ty) >>= f
281270 go (RCons name ty rest) = (RCons name <$> go ty <*> go rest) >>= f
@@ -289,7 +278,6 @@ everywhereOnTypesTopDownM :: (Functor m, Applicative m, Monad m) => (Type -> m T
289278everywhereOnTypesTopDownM f = go <=< f
290279 where
291280 go (TypeApp t1 t2) = TypeApp <$> (f t1 >>= go) <*> (f t2 >>= go)
292− go (SaturatedTypeSynonym name tys) = SaturatedTypeSynonym name <$> mapM (go <=< f) tys
293281 go (ForAll arg ty sco) = ForAll arg <$> (f ty >>= go) <*> pure sco
294282 go (ConstrainedType cs ty) = ConstrainedType <$> mapM (sndM (mapM (go <=< f))) cs <*> (f ty >>= go)
295283 go (RCons name ty rest) = RCons name <$> (f ty >>= go) <*> (f rest >>= go)
@@ -303,7 +291,6 @@ everythingOnTypes :: (r -> r -> r) -> (Type -> r) -> Type -> r
303291everythingOnTypes (<>) f = go
304292 where
305293 go t@(TypeApp t1 t2) = f t <> go t1 <> go t2
306− go t@(SaturatedTypeSynonym _ tys) = foldl (<>) (f t) (map go tys)
307294 go t@(ForAll _ ty _) = f t <> go ty
308295 go t@(ConstrainedType cs ty) = foldl (<>) (f t) (map go $ concatMap snd cs) <> go ty
309296 go t@(RCons _ ty rest) = f t <> go ty <> go rest
@@ -318,7 +305,6 @@ everythingWithContextOnTypes s0 r0 (<>) f = go' s0
318305 where
319306 go' s t = let (s', r) = f s t in r <> go s' t
320307 go s (TypeApp t1 t2) = go' s t1 <> go' s t2
321− go s (SaturatedTypeSynonym _ tys) = foldl (<>) r0 (map (go' s) tys)
322308 go s (ForAll _ ty _) = go' s ty
323309 go s (ConstrainedType cs ty) = foldl (<>) r0 (map (go' s) $ concatMap snd cs) <> go' s ty
324310 go s (RCons _ ty rest) = go' s ty <> go' s rest