git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge branch 'master' into pure11
cd8e57fAndy Arvanitis
.gitignore+1
@@ -15,3 +15,4 @@ node_modules
15tmp/
15tmp/
16.stack-work/
16.stack-work/
17tests/support/flattened/
17tests/support/flattened/
18+output
.travis.yml+2−1
@@ -15,7 +15,7 @@ matrix:
15 - env: GHCVER=7.6.3
15 - env: GHCVER=7.6.3
16 compiler: ": #GHC 7.6.3"
16 compiler: ": #GHC 7.6.3"
17 addons: {apt: {packages: [cabal-install-1.22,ghc-7.6.3,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
17 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
19 compiler: ": #GHC 7.10.1"
19 compiler: ": #GHC 7.10.1"
20 addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.1,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
20 addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.1,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
21 - env: GHCVER=7.10.2 STACKAGE=lts=3.6 RUNSDISTTESTS=YES
21 - env: GHCVER=7.10.2 STACKAGE=lts=3.6 RUNSDISTTESTS=YES
@@ -74,6 +74,7 @@ deploy:
74 on:
74 on:
75 all_branches: true
75 all_branches: true
76 tags: true
76 tags: true
77+ condition: "$DEPLOY = yes"
77cache:
78cache:
78 directories:
79 directories:
79 - ~/cabal-sandboxes
80 - ~/cabal-sandboxes
INSTALL.md+12−2
@@ -24,15 +24,25 @@ requirements.
24## Compiling from source
24## Compiling from source
25
25
26GHC 7.6.1 or newer is required to compile from source. The easiest way is to
26GHC 7.6.1 or newer is required to compile from source. The easiest way is to
27−use `cabal-install`:
27+use stack:
28
28
29```
29```
30−$ cabal update && cabal install purescript
30+$ stack install purescript
31```
31```
32
32
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+
33The PureScript compiler has been known to run on OS X 10.6 when built with GHC
42The PureScript compiler has been known to run on OS X 10.6 when built with GHC
347.6.
437.6.
35
44
45+
36## The "curses" library
46## The "curses" library
37
47
38`psci` depends on the `curses` library (via the Haskell package `terminfo`). If
48`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
31 array
31 array
32 attoparsec
32 attoparsec
33 base
33 base
34+ binary
34 blaze-builder
35 blaze-builder
35 bower-json
36 bower-json
36 boxes
37 boxes
@@ -45,9 +46,10 @@ PureScript uses the following Haskell library packages. Their license files foll
45 haskeline
46 haskeline
46 integer-gmp
47 integer-gmp
47 language-javascript
48 language-javascript
49+ lifted-base
50+ monad-control
48 mtl
51 mtl
49 nats
52 nats
50− old-locale
51 optparse-applicative
53 optparse-applicative
52 parsec
54 parsec
53 pattern-arrows
55 pattern-arrows
@@ -59,12 +61,14 @@ PureScript uses the following Haskell library packages. Their license files foll
59 scientific
61 scientific
60 semigroups
62 semigroups
61 split
63 split
64+ stm
62 syb
65 syb
63 template-haskell
66 template-haskell
64 terminfo
67 terminfo
65 text
68 text
66 time
69 time
67 transformers
70 transformers
71+ transformers-base
68 transformers-compat
72 transformers-compat
69 unix
73 unix
70 unordered-containers
74 unordered-containers
@@ -449,6 +453,39 @@ base LICENSE file:
449
453
450 -----------------------------------------------------------------------------
454 -----------------------------------------------------------------------------
451
455
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+
452blaze-builder LICENSE file:
489blaze-builder LICENSE file:
453
490
454 Copyright Jasper Van der Jeugt 2010, Simon Meier 2010 & 2011
491 Copyright Jasper Van der Jeugt 2010, Simon Meier 2010 & 2011
@@ -967,6 +1004,70 @@ language-javascript LICENSE file:
967 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1004 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
968 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1005 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
969
1006
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+
970mtl LICENSE file:
1071mtl LICENSE file:
971
1072
972 The Glasgow Haskell Compiler License
1073 The Glasgow Haskell Compiler License
@@ -1034,72 +1135,6 @@ nats LICENSE file:
1034 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1135 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1035 POSSIBILITY OF SUCH DAMAGE.
1136 POSSIBILITY OF SUCH DAMAGE.
1036
1137
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−
1103optparse-applicative LICENSE file:
1138optparse-applicative LICENSE file:
1104
1139
1105 Copyright (c) 2012, Paolo Capriotti
1140 Copyright (c) 2012, Paolo Capriotti
@@ -1450,6 +1485,40 @@ split LICENSE file:
1450 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1485 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1451 SUCH DAMAGE.
1486 SUCH DAMAGE.
1452
1487
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+
1453syb LICENSE file:
1522syb LICENSE file:
1454
1523
1455 This library (libraries/syb) is derived from code from several
1524 This library (libraries/syb) is derived from code from several
@@ -1674,6 +1743,36 @@ transformers LICENSE file:
1674 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1743 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1675 DAMAGE.
1744 DAMAGE.
1676
1745
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+
1677transformers-compat LICENSE file:
1776transformers-compat LICENSE file:
1678
1777
1679 Copyright 2012 Edward Kmett
1778 Copyright 2012 Edward Kmett
@@ -1836,7 +1935,7 @@ vector LICENSE file:
1836
1935
1837void LICENSE file:
1936void LICENSE file:
1838
1937
1839− Copyright 2013 Edward Kmett
1938+ Copyright 2015 Edward Kmett
1840
1939
1841 All rights reserved.
1940 All rights reserved.
1842
1941
README.md+5−1
@@ -2,7 +2,11 @@
2
2
3A small strongly typed programming language with expressive types that compiles to Javascript, written in and inspired by Haskell.
3A small strongly typed programming language with expressive types that compiles to Javascript, written in and inspired by Haskell.
4
4
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)
6
10
7## Language info
11## Language info
8
12
core-tests/tests/generic-deriving/Main.purs+3
@@ -2,6 +2,8 @@ module GenericDeriving where
2
2
3import Prelude
3import Prelude
4
4
5+import Control.Monad.Eff (Eff())
6+import Control.Monad.Eff.Console (CONSOLE())
5import Data.Generic
7import Data.Generic
6
8
7data Void
9data Void
@@ -17,4 +19,5 @@ data A a
17
19
18derive instance genericA :: (Generic a) => Generic (A a)
20derive instance genericA :: (Generic a) => Generic (A a)
19
21
22+main :: forall eff. Eff (console :: CONSOLE | eff) Unit
20main = Control.Monad.Eff.Console.log (gShow (D { a: C [ A 1.0 "test", B 42, D { a: true } ] }))
23main = 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
9set -u # exit on undefined variable
9set -u # exit on undefined variable
10set -o pipefail # propagate nonzero exit codes through pipelines
10set -o pipefail # propagate nonzero exit codes through pipelines
11
11
12+export LC_CTYPE=C
13+export LANG=C
14+
12if ! which cabal-dependency-licenses >/dev/null; then
15if ! which cabal-dependency-licenses >/dev/null; then
13 echo "$0: the program 'cabal-dependency-licenses' is required." >&2
16 echo "$0: the program 'cabal-dependency-licenses' is required." >&2
14 echo "$0: see Hackage: https://hackage.haskell.org/package/cabal-dependency-licenses" >&2
17 echo "$0: see Hackage: https://hackage.haskell.org/package/cabal-dependency-licenses" >&2
pcc/Make.hs+10−15
@@ -26,9 +26,7 @@ module Make
26
26
27import Control.Monad
27import Control.Monad
28import Control.Monad.Error.Class (MonadError(..))
28import Control.Monad.Error.Class (MonadError(..))
29−import Control.Monad.Trans.Except
30import Control.Monad.Reader
29import Control.Monad.Reader
31−import Control.Monad.Writer.Strict
32
30
33import Data.FileEmbed (embedFile)
31import Data.FileEmbed (embedFile)
34import Data.List (intercalate)
32import Data.List (intercalate)
@@ -45,17 +43,14 @@ import System.FilePath ((</>), takeDirectory, addExtension, dropExtension)
45import System.IO.Error (tryIOError)
43import System.IO.Error (tryIOError)
46import System.IO.UTF8
44import System.IO.UTF8
47
45
46+import Language.PureScript.Errors
47+import Language.PureScript (Make, runMake)
48+
48import qualified Language.PureScript as P
49import qualified Language.PureScript as P
49import qualified Language.PureScript.CodeGen.Cpp as CPP
50import qualified Language.PureScript.CodeGen.Cpp as CPP
50import qualified Language.PureScript.CoreFn as CF
51import qualified Language.PureScript.CoreFn as CF
51import qualified Paths_purescript as Paths
52import qualified Paths_purescript as Paths
52
53
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−
59makeIO :: (IOError -> P.ErrorMessage) -> IO a -> Make a
54makeIO :: (IOError -> P.ErrorMessage) -> IO a -> Make a
60makeIO f io = do
55makeIO f io = do
61 e <- liftIO $ tryIOError io
56 e <- liftIO $ tryIOError io
@@ -67,7 +62,7 @@ traverseEither _ (Left x) = pure (Left x)
67traverseEither f (Right y) = Right <$> f y
62traverseEither f (Right y) = Right <$> f y
68
63
69buildMakeActions :: FilePath
64buildMakeActions :: FilePath
70− -> M.Map P.ModuleName (Either P.RebuildPolicy String)
65+ -> M.Map P.ModuleName (Either P.RebuildPolicy FilePath)
71 -> Bool
66 -> Bool
72 -> P.MakeActions Make
67 -> P.MakeActions Make
73buildMakeActions outputDir filePathMap usePrefix =
68buildMakeActions outputDir filePathMap usePrefix =
@@ -149,26 +144,26 @@ buildMakeActions outputDir filePathMap usePrefix =
149 requiresForeign = not . null . CF.moduleForeign
144 requiresForeign = not . null . CF.moduleForeign
150
145
151 dirExists :: FilePath -> Make Bool
146 dirExists :: FilePath -> Make Bool
152− dirExists path = makeIO (const (P.SimpleErrorWrapper $ P.CannotReadFile path)) $ do
147+ dirExists path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ do
153 doesDirectoryExist path
148 doesDirectoryExist path
154
149
155 textFileExists :: FilePath -> Make Bool
150 textFileExists :: FilePath -> Make Bool
156− textFileExists path = makeIO (const (P.SimpleErrorWrapper $ P.CannotReadFile path)) $ do
151+ textFileExists path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ do
157 doesFileExist path
152 doesFileExist path
158
153
159 getTimestamp :: FilePath -> Make (Maybe UTCTime)
154 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
161 exists <- doesFileExist path
156 exists <- doesFileExist path
162 traverse (const $ getModificationTime path) $ guard exists
157 traverse (const $ getModificationTime path) $ guard exists
163
158
164 readTextFile :: FilePath -> Make String
159 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
166
161
167 readTextFile' :: FilePath -> Make BL.ByteString
162 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
169
164
170 writeTextFile :: FilePath -> String -> Make ()
165 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
172 mkdirp path
167 mkdirp path
173 writeFile path text
168 writeFile path text
174 where
169 where
psci/PSCi.hs+6−6
@@ -263,10 +263,10 @@ makeIO f io = do
263
263
264make :: PSCiState -> [(Either P.RebuildPolicy FilePath, P.Module)] -> P.Make P.Environment
264make :: PSCiState -> [(Either P.RebuildPolicy FilePath, P.Module)] -> P.Make P.Environment
265make PSCiState{..} ms = P.make actions' (map snd (psciLoadedModules ++ ms))
265make PSCiState{..} ms = P.make actions' (map snd (psciLoadedModules ++ ms))
266− where
266+ where
267− filePathMap = M.fromList $ (first P.getModuleName . swap) `map` (psciLoadedModules ++ ms)
267+ filePathMap = M.fromList $ (first P.getModuleName . swap) `map` (psciLoadedModules ++ ms)
268− actions = P.buildMakeActions modulesDir filePathMap psciForeignFiles False
268+ actions = P.buildMakeActions modulesDir filePathMap psciForeignFiles False
269− actions' = actions { P.progress = const (return ()) }
269+ actions' = actions { P.progress = const (return ()) }
270
270
271-- |
271-- |
272-- Takes a value declaration and evaluates it with the current state.
272-- Takes a value declaration and evaluates it with the current state.
@@ -464,7 +464,7 @@ handleCommand (LoadFile filePath) = whenFileExists filePath $ \absPath -> do
464 Right mods -> PSCI . lift $ modify (updateModules (map ((,) (Right absPath)) mods))
464 Right mods -> PSCI . lift $ modify (updateModules (map ((,) (Right absPath)) mods))
465handleCommand (LoadForeign filePath) = whenFileExists filePath $ \absPath -> do
465handleCommand (LoadForeign filePath) = whenFileExists filePath $ \absPath -> do
466 foreignsOrError <- psciIO . runMake $ do
466 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)
468 P.parseForeignModulesFromFiles [(absPath, foreignFile)]
468 P.parseForeignModulesFromFiles [(absPath, foreignFile)]
469 case foreignsOrError of
469 case foreignsOrError of
470 Left err -> PSCI $ outputStrLn $ P.prettyPrintMultipleErrors False err
470 Left err -> PSCI $ outputStrLn $ P.prettyPrintMultipleErrors False err
@@ -533,7 +533,7 @@ loop PSCiOptions{..} = do
533 historyFilename <- getHistoryFilename
533 historyFilename <- getHistoryFilename
534 let settings = defaultSettings { historyFile = Just historyFilename }
534 let settings = defaultSettings { historyFile = Just historyFilename }
535 foreignsOrError <- runMake $ do
535 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))
537 P.parseForeignModulesFromFiles foreignFilesContent
537 P.parseForeignModulesFromFiles foreignFilesContent
538 case foreignsOrError of
538 case foreignsOrError of
539 Left errs -> putStrLn (P.prettyPrintMultipleErrors False errs) >> exitFailure
539 Left errs -> putStrLn (P.prettyPrintMultipleErrors False errs) >> exitFailure
purescript.cabal+13−2
@@ -1,5 +1,5 @@
1name: purescript
1name: purescript
2−version: 0.7.4.1
2+version: 0.7.5
3cabal-version: >=1.8
3cabal-version: >=1.8
4build-type: Simple
4build-type: Simple
5license: MIT
5license: MIT
@@ -25,6 +25,14 @@ extra-source-files: examples/passing/*.purs
25 , tests/support/bower.json
25 , tests/support/bower.json
26 , tests/support/setup-win.cmd
26 , tests/support/setup-win.cmd
27 , psci/tests/data/Sample.purs
27 , 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
28 , pcc/include/*.hh
36 , pcc/include/*.hh
29
37
30source-repository head
38source-repository head
@@ -33,6 +41,9 @@ source-repository head
33
41
34library
42library
35 build-depends: base >=4.6 && <5,
43 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,
36 containers -any,
47 containers -any,
37 unordered-containers -any,
48 unordered-containers -any,
38 dlist -any,
49 dlist -any,
@@ -192,7 +203,7 @@ executable psc
192 main-is: Main.hs
203 main-is: Main.hs
193 buildable: True
204 buildable: True
194 hs-source-dirs: psc
205 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"
196
207
197executable psci
208executable psci
198 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
209 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
21import Language.PureScript.AST.SourcePos
21import Language.PureScript.AST.SourcePos
22import Language.PureScript.Names
22import Language.PureScript.Names
23import Language.PureScript.Comments
23import Language.PureScript.Comments
24+import Language.PureScript.Types
24
25
25-- |
26-- |
26-- Data type for binders
27-- Data type for binders
@@ -69,7 +70,11 @@ data Binder
69 -- |
70 -- |
70 -- A binder with source position information
71 -- A binder with source position information
71 --
72 --
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)
73
78
74-- |
79-- |
75-- Collect all names introduced in binders in an expression
80-- Collect all names introduced in binders in an expression
@@ -83,4 +88,5 @@ binderNames = go []
83 go ns (ArrayBinder bs) = foldl go ns bs
88 go ns (ArrayBinder bs) = foldl go ns bs
84 go ns (NamedBinder name b) = go (name : ns) b
89 go ns (NamedBinder name b) = go (name : ns) b
85 go ns (PositionedBinder _ _ b) = go ns b
90 go ns (PositionedBinder _ _ b) = go ns b
91+ go ns (TypedBinder _ b) = go ns b
86 go ns _ = ns
92 go ns _ = ns
src/Language/PureScript/AST/Exported.hs+1−1
@@ -66,7 +66,7 @@ filterInstances (Just exps) =
66 -- * the name is defined in a different module (and must be exported from
66 -- * the name is defined in a different module (and must be exported from
67 -- that module; the code would fail to compile otherwise).
67 -- that module; the code would fail to compile otherwise).
68 visibleOutside _ (Qualified (Just _) _) = True
68 visibleOutside _ (Qualified (Just _) _) = True
69− visibleOutside refs (Qualified Nothing n) = any (== n) refs
69+ visibleOutside refs (Qualified Nothing n) = n `elem` refs
70
70
71 typeName (TypeRef n _) = Just n
71 typeName (TypeRef n _) = Just n
72 typeName (PositionedDeclarationRef _ _ r) = typeName r
72 typeName (PositionedDeclarationRef _ _ r) = typeName r
src/Language/PureScript/AST/Traversals.hs+9−3
@@ -79,6 +79,7 @@ everywhereOnValues f g h = (f', g', h')
79 h' (ArrayBinder bs) = h (ArrayBinder (map h' bs))
79 h' (ArrayBinder bs) = h (ArrayBinder (map h' bs))
80 h' (NamedBinder name b) = h (NamedBinder name (h' b))
80 h' (NamedBinder name b) = h (NamedBinder name (h' b))
81 h' (PositionedBinder pos com b) = h (PositionedBinder pos com (h' b))
81 h' (PositionedBinder pos com b) = h (PositionedBinder pos com (h' b))
82+ h' (TypedBinder t b) = h (TypedBinder t (h' b))
82 h' other = h other
83 h' other = h other
83
84
84 handleCaseAlternative :: CaseAlternative -> CaseAlternative
85 handleCaseAlternative :: CaseAlternative -> CaseAlternative
@@ -135,6 +136,7 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
135 h' (ArrayBinder bs) = ArrayBinder <$> mapM (h' <=< h) bs
136 h' (ArrayBinder bs) = ArrayBinder <$> mapM (h' <=< h) bs
136 h' (NamedBinder name b) = NamedBinder name <$> (h b >>= h')
137 h' (NamedBinder name b) = NamedBinder name <$> (h b >>= h')
137 h' (PositionedBinder pos com b) = PositionedBinder pos com <$> (h b >>= h')
138 h' (PositionedBinder pos com b) = PositionedBinder pos com <$> (h b >>= h')
139+ h' (TypedBinder t b) = TypedBinder t <$> (h b >>= h')
138 h' other = h other
140 h' other = h other
139
141
140 handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM (h' <=< h) bs
142 handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM (h' <=< h) bs
@@ -187,6 +189,7 @@ everywhereOnValuesM f g h = (f', g', h')
187 h' (ArrayBinder bs) = (ArrayBinder <$> mapM h' bs) >>= h
189 h' (ArrayBinder bs) = (ArrayBinder <$> mapM h' bs) >>= h
188 h' (NamedBinder name b) = (NamedBinder name <$> h' b) >>= h
190 h' (NamedBinder name b) = (NamedBinder name <$> h' b) >>= h
189 h' (PositionedBinder pos com b) = (PositionedBinder pos com <$> h' b) >>= h
191 h' (PositionedBinder pos com b) = (PositionedBinder pos com <$> h' b) >>= h
192+ h' (TypedBinder t b) = (TypedBinder t <$> h' b) >>= h
190 h' other = h other
193 h' other = h other
191
194
192 handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM h' bs
195 handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM h' bs
@@ -216,10 +219,10 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
216 f' d = f d
219 f' d = f d
217
220
218 g' v@(UnaryMinus v1) = g v <> g' v1
221 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
220 g' v@(Parens v1) = g v <> g' v1
223 g' v@(Parens v1) = g v <> g' v1
221− g' v@(OperatorSection op (Left v1)) = g v <> g op <> g' v1
224+ 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
225+ g' v@(OperatorSection op (Right v1)) = g v <> g' op <> g' v1
223 g' v@(ArrayLiteral vs) = foldl (<>) (g v) (map g' vs)
226 g' v@(ArrayLiteral vs) = foldl (<>) (g v) (map g' vs)
224 g' v@(ObjectLiteral vs) = foldl (<>) (g v) (map (g' . snd) vs)
227 g' v@(ObjectLiteral vs) = foldl (<>) (g v) (map (g' . snd) vs)
225 g' v@(ObjectConstructor vs) = foldl (<>) (g v) (map g' (mapMaybe snd vs))
228 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')
242 h' b@(ArrayBinder bs) = foldl (<>) (h b) (map h' bs)
245 h' b@(ArrayBinder bs) = foldl (<>) (h b) (map h' bs)
243 h' b@(NamedBinder _ b1) = h b <> h' b1
246 h' b@(NamedBinder _ b1) = h b <> h' b1
244 h' b@(PositionedBinder _ _ b1) = h b <> h' b1
247 h' b@(PositionedBinder _ _ b1) = h b <> h' b1
248+ h' b@(TypedBinder _ b1) = h b <> h' b1
245 h' b = h b
249 h' b = h b
246
250
247 i' ca@(CaseAlternative bs (Right val)) = foldl (<>) (i ca) (map h' bs) <> g' val
251 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'
310 h' s (ArrayBinder bs) = foldl (<>) r0 (map (h'' s) bs)
314 h' s (ArrayBinder bs) = foldl (<>) r0 (map (h'' s) bs)
311 h' s (NamedBinder _ b1) = h'' s b1
315 h' s (NamedBinder _ b1) = h'' s b1
312 h' s (PositionedBinder _ _ b1) = h'' s b1
316 h' s (PositionedBinder _ _ b1) = h'' s b1
317+ h' s (TypedBinder _ b1) = h'' s b1
313 h' _ _ = r0
318 h' _ _ = r0
314
319
315 i'' s ca = let (s', r) = i s ca in r <> i' s' ca
320 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
379 h' s (ArrayBinder bs) = ArrayBinder <$> mapM (h'' s) bs
384 h' s (ArrayBinder bs) = ArrayBinder <$> mapM (h'' s) bs
380 h' s (NamedBinder name b) = NamedBinder name <$> h'' s b
385 h' s (NamedBinder name b) = NamedBinder name <$> h'' s b
381 h' s (PositionedBinder pos com b) = PositionedBinder pos com <$> h'' s b
386 h' s (PositionedBinder pos com b) = PositionedBinder pos com <$> h'' s b
387+ h' s (TypedBinder t b) = TypedBinder t <$> h'' s b
382 h' _ other = return other
388 h' _ other = return other
383
389
384 i'' s = uncurry i' <=< i s
390 i'' s = uncurry i' <=< i s
src/Language/PureScript/Bundle.hs+1−1
@@ -385,7 +385,7 @@ isModuleEmpty (Module _ els) = all isElementEmpty els
385 where
385 where
386 isElementEmpty :: ModuleElement -> Bool
386 isElementEmpty :: ModuleElement -> Bool
387 isElementEmpty (ExportsList exps) = null exps
387 isElementEmpty (ExportsList exps) = null exps
388− isElementEmpty (Require _ _ _) = True
388+ isElementEmpty Require{} = True
389 isElementEmpty (Other _) = True
389 isElementEmpty (Other _) = True
390 isElementEmpty _ = False
390 isElementEmpty _ = False
391
391
src/Language/PureScript/CodeGen/JS.hs+2−1
@@ -27,6 +27,7 @@ module Language.PureScript.CodeGen.JS
27 ) where
27 ) where
28
28
29import Data.List ((\\), delete, intersect)
29import Data.List ((\\), delete, intersect)
30+import Data.Maybe (isNothing)
30import qualified Data.Traversable as T (traverse)
31import qualified Data.Traversable as T (traverse)
31
32
32#if __GLASGOW_HASKELL__ < 710
33#if __GLASGOW_HASKELL__ < 710
@@ -62,7 +63,7 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign_ = do
62 comments <- not <$> asks optionsNoComments
63 comments <- not <$> asks optionsNoComments
63 let strict = JSStringLiteral "use strict"
64 let strict = JSStringLiteral "use strict"
64 let header = if comments && not (null coms) then JSComment coms strict else strict
65 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_]
66 let moduleBody = header : foreign' ++ jsImports ++ concat optimized
67 let moduleBody = header : foreign' ++ jsImports ++ concat optimized
67 let foreignExps = exps `intersect` (fst `map` foreigns)
68 let foreignExps = exps `intersect` (fst `map` foreigns)
68 let standardExps = exps \\ foreignExps
69 let standardExps = exps \\ foreignExps
src/Language/PureScript/CodeGen/JS/Optimizer/Inliner.hs+1−1
@@ -255,7 +255,7 @@ inlineFnComposition = everywhereOnJSTopDownM convert
255 return $ JSFunction Nothing [arg] (JSBlock [JSReturn $ JSApp x [JSApp y [JSVar arg]]])
255 return $ JSFunction Nothing [arg] (JSBlock [JSReturn $ JSApp x [JSApp y [JSVar arg]]])
256 convert other = return other
256 convert other = return other
257 isFnCompose :: JS -> JS -> Bool
257 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)
259
259
260isDict :: (String, String) -> JS -> Bool
260isDict :: (String, String) -> JS -> Bool
261isDict (moduleName, dictName) (JSAccessor x (JSVar y)) = x == dictName && y == moduleName
261isDict (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
124 hasFunction :: JS -> Bool
124 hasFunction :: JS -> Bool
125 hasFunction = getAny . everythingOnJS mappend (Any . isFunction)
125 hasFunction = getAny . everythingOnJS mappend (Any . isFunction)
126 where
126 where
127− isFunction (JSFunction _ _ _) = True
127+ isFunction JSFunction{} = True
128 isFunction _ = False
128 isFunction _ = False
src/Language/PureScript/CodeGen/JS/Optimizer/Unused.hs+1−1
@@ -29,7 +29,7 @@ removeCodeAfterReturnStatements = everywhereOnJS (removeFromBlock go)
29 where
29 where
30 go :: [JS] -> [JS]
30 go :: [JS] -> [JS]
31 go jss | not (any isJSReturn jss) = jss
31 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]
33 isJSReturn (JSReturn _) = True
33 isJSReturn (JSReturn _) = True
34 isJSReturn _ = False
34 isJSReturn _ = False
35
35
src/Language/PureScript/CoreFn/Desugar.hs+2
@@ -166,6 +166,8 @@ moduleToCoreFn env (A.Module _ coms mn decls (Just exps)) =
166 NamedBinder (ss, com, Nothing, Nothing) name (binderToCoreFn ss [] b)
166 NamedBinder (ss, com, Nothing, Nothing) name (binderToCoreFn ss [] b)
167 binderToCoreFn _ com (A.PositionedBinder ss com1 b) =
167 binderToCoreFn _ com (A.PositionedBinder ss com1 b) =
168 binderToCoreFn (Just ss) (com ++ com1) b
168 binderToCoreFn (Just ss) (com ++ com1) b
169+ binderToCoreFn ss com (A.TypedBinder _ b) =
170+ binderToCoreFn ss com b
169
171
170 -- |
172 -- |
171 -- Gets metadata for values.
173 -- Gets metadata for values.
src/Language/PureScript/CoreFn/Expr.hs+1−1
@@ -101,7 +101,7 @@ data CaseAlternative a = CaseAlternative
101instance Functor CaseAlternative where
101instance Functor CaseAlternative where
102
102
103 fmap f (CaseAlternative cabs car) = CaseAlternative
103 fmap f (CaseAlternative cabs car) = CaseAlternative
104− (fmap (fmap f) $ cabs)
104+ (fmap (fmap f) cabs)
105 (either (Left . fmap (fmap f *** fmap f)) (Right . fmap f) car)
105 (either (Left . fmap (fmap f *** fmap f)) (Right . fmap f) car)
106
106
107-- |
107-- |
src/Language/PureScript/Docs/Convert.hs+2−3
@@ -147,7 +147,7 @@ convertDeclaration (P.ExternDataDeclaration _ kind') title =
147 basicDeclaration title (ExternDataDeclaration kind')
147 basicDeclaration title (ExternDataDeclaration kind')
148convertDeclaration (P.TypeSynonymDeclaration _ args ty) title =
148convertDeclaration (P.TypeSynonymDeclaration _ args ty) title =
149 basicDeclaration title (TypeSynonymDeclaration args ty)
149 basicDeclaration title (TypeSynonymDeclaration args ty)
150−convertDeclaration (P.TypeClassDeclaration _ args implies ds) title = do
150+convertDeclaration (P.TypeClassDeclaration _ args implies ds) title =
151 Just (Right (mkDeclaration title info) { declChildren = children })
151 Just (Right (mkDeclaration title info) { declChildren = children })
152 where
152 where
153 info = TypeClassDeclaration args implies
153 info = TypeClassDeclaration args implies
@@ -158,7 +158,7 @@ convertDeclaration (P.TypeClassDeclaration _ args implies ds) title = do
158 ChildDeclaration (P.showIdent ident') Nothing Nothing (ChildTypeClassMember ty)
158 ChildDeclaration (P.showIdent ident') Nothing Nothing (ChildTypeClassMember ty)
159 convertClassMember _ =
159 convertClassMember _ =
160 error "Invalid argument to convertClassMember."
160 error "Invalid argument to convertClassMember."
161−convertDeclaration (P.TypeInstanceDeclaration _ constraints className tys _) title = do
161+convertDeclaration (P.TypeInstanceDeclaration _ constraints className tys _) title =
162 Just (Left (classNameString : typeNameStrings, AugmentChild childDecl))
162 Just (Left (classNameString : typeNameStrings, AugmentChild childDecl))
163 where
163 where
164 classNameString = unQual className
164 classNameString = unQual className
@@ -166,7 +166,6 @@ convertDeclaration (P.TypeInstanceDeclaration _ constraints className tys _) tit
166 unQual x = let (P.Qualified _ y) = x in P.runProperName y
166 unQual x = let (P.Qualified _ y) = x in P.runProperName y
167
167
168 extractProperNames (P.TypeConstructor n) = [unQual n]
168 extractProperNames (P.TypeConstructor n) = [unQual n]
169− extractProperNames (P.SaturatedTypeSynonym n _) = [unQual n]
170 extractProperNames _ = []
169 extractProperNames _ = []
171
170
172 childDecl = ChildDeclaration title Nothing Nothing (ChildInstance constraints classApp)
171 childDecl = ChildDeclaration title Nothing Nothing (ChildInstance constraints classApp)
src/Language/PureScript/Docs/Render.hs+3−2
@@ -10,6 +10,7 @@
10
10
11module Language.PureScript.Docs.Render where
11module Language.PureScript.Docs.Render where
12
12
13+import Data.Maybe (maybeToList)
13import Data.Monoid ((<>))
14import Data.Monoid ((<>))
14import qualified Language.PureScript as P
15import qualified Language.PureScript as P
15
16
@@ -46,7 +47,7 @@ renderDeclarationWithOptions opts Declaration{..} =
46 ]
47 ]
47 TypeClassDeclaration args implies ->
48 TypeClassDeclaration args implies ->
48 [ keywordClass ]
49 [ keywordClass ]
49− ++ maybe [] (:[]) superclasses
50+ ++ maybeToList superclasses
50 ++ [renderType' (typeApp declTitle args)]
51 ++ [renderType' (typeApp declTitle args)]
51 ++ if any (isTypeClassMember . cdeclInfo) declChildren
52 ++ if any (isTypeClassMember . cdeclInfo) declChildren
52 then [keywordWhere]
53 then [keywordWhere]
@@ -75,7 +76,7 @@ renderChildDeclarationWithOptions opts ChildDeclaration{..} =
75 [ keywordInstance
76 [ keywordInstance
76 , ident cdeclTitle
77 , ident cdeclTitle
77 , syntax "::"
78 , syntax "::"
78− ] ++ maybe [] (:[]) (renderConstraints constraints)
79+ ] ++ maybeToList (renderConstraints constraints)
79 ++ [ renderType' ty ]
80 ++ [ renderType' ty ]
80 ChildDataConstructor args ->
81 ChildDataConstructor args ->
81 [ renderType' typeApp' ]
82 [ renderType' typeApp' ]
src/Language/PureScript/Docs/Types.hs+1−1
@@ -425,7 +425,7 @@ asSourceSpan = P.SourceSpan <$> key "name" asString
425
425
426instance A.ToJSON a => A.ToJSON (Package a) where
426instance A.ToJSON a => A.ToJSON (Package a) where
427 toJSON Package{..} =
427 toJSON Package{..} =
428− A.object $
428+ A.object
429 [ "packageMeta" .= pkgMeta
429 [ "packageMeta" .= pkgMeta
430 , "version" .= showVersion pkgVersion
430 , "version" .= showVersion pkgVersion
431 , "versionTag" .= pkgVersionTag
431 , "versionTag" .= pkgVersionTag
src/Language/PureScript/Errors.hs+338−341
@@ -20,10 +20,11 @@
20module Language.PureScript.Errors where
20module Language.PureScript.Errors where
21
21
22import Data.Either (lefts, rights)
22import Data.Either (lefts, rights)
23−import Data.List (intercalate, transpose)
23+import Data.List (intercalate, transpose, nub, nubBy, partition)
24import Data.Function (on)
24import Data.Function (on)
25#if __GLASGOW_HASKELL__ < 710
25#if __GLASGOW_HASKELL__ < 710
26import Data.Foldable (fold, foldMap)
26import Data.Foldable (fold, foldMap)
27+import Data.Traversable (traverse)
27#else
28#else
28import Data.Foldable (fold)
29import Data.Foldable (fold)
29#endif
30#endif
@@ -52,11 +53,8 @@ import qualified Text.PrettyPrint.Boxes as Box
52import qualified Text.Parsec as P
53import qualified Text.Parsec as P
53import qualified Text.Parsec.Error as PE
54import qualified Text.Parsec.Error as PE
54import Text.Parsec.Error (Message(..))
55import Text.Parsec.Error (Message(..))
55−import Data.List (nub)
56
56
57−-- |
58−-- A type of error messages
57+-- | A type of error messages
59−--
60data SimpleErrorMessage
58data SimpleErrorMessage
61 = ErrorParsingExterns P.ParseError
59 = ErrorParsingExterns P.ParseError
62 | ErrorParsingFFIModule FilePath
60 | ErrorParsingFFIModule FilePath
@@ -100,6 +98,7 @@ data SimpleErrorMessage
100 | CtorConflictsWithClass ProperName
98 | CtorConflictsWithClass ProperName
101 | ClassConflictsWithType ProperName
99 | ClassConflictsWithType ProperName
102 | ClassConflictsWithCtor ProperName
100 | ClassConflictsWithCtor ProperName
101+ | DuplicateModuleName ModuleName
103 | DuplicateClassExport ProperName
102 | DuplicateClassExport ProperName
104 | DuplicateValueExport Ident
103 | DuplicateValueExport Ident
105 | DuplicateTypeArgument String
104 | DuplicateTypeArgument String
@@ -143,45 +142,54 @@ data SimpleErrorMessage
143 | ShadowedTypeVar String
142 | ShadowedTypeVar String
144 | UnusedTypeVar String
143 | UnusedTypeVar String
145 | WildcardInferredType Type
144 | WildcardInferredType Type
145+ | MissingTypeDeclaration Ident
146 | NotExhaustivePattern [[Binder]] Bool
146 | NotExhaustivePattern [[Binder]] Bool
147 | OverlappingPattern [[Binder]] Bool
147 | OverlappingPattern [[Binder]] Bool
148 | IncompleteExhaustivityCheck
148 | IncompleteExhaustivityCheck
149 | ClassOperator ProperName Ident
149 | ClassOperator ProperName Ident
150 | MisleadingEmptyTypeImport ModuleName ProperName
150 | MisleadingEmptyTypeImport ModuleName ProperName
151 | ImportHidingModule ModuleName
151 | ImportHidingModule ModuleName
152− deriving (Show)
152+ deriving Show
153−
153+
154−-- |
154+-- | Error message hints, providing more detailed information about failure.
155−-- Wrapper of simpler errors
155+data ErrorMessageHint
156−--
157−data ErrorMessage
158− = NotYetDefined [Ident] ErrorMessage
156+ = NotYetDefined [Ident]
159− | ErrorUnifyingTypes Type Type ErrorMessage
157+ | ErrorUnifyingTypes Type Type
160− | ErrorInExpression Expr ErrorMessage
158+ | ErrorInExpression Expr
161− | ErrorInModule ModuleName ErrorMessage
159+ | ErrorInModule ModuleName
162− | ErrorInInstance (Qualified ProperName) [Type] ErrorMessage
160+ | ErrorInInstance (Qualified ProperName) [Type]
163− | ErrorInSubsumption Type Type ErrorMessage
161+ | ErrorInSubsumption Type Type
164− | ErrorCheckingType Expr Type ErrorMessage
162+ | ErrorCheckingType Expr Type
165− | ErrorCheckingKind Type ErrorMessage
163+ | ErrorCheckingKind Type
166− | ErrorInferringType Expr ErrorMessage
164+ | ErrorInferringType Expr
167− | ErrorInApplication Expr Type Expr ErrorMessage
165+ | ErrorInApplication Expr Type Expr
168− | ErrorInDataConstructor ProperName ErrorMessage
166+ | ErrorInDataConstructor ProperName
169− | ErrorInTypeConstructor ProperName ErrorMessage
167+ | ErrorInTypeConstructor ProperName
170− | ErrorInBindingGroup [Ident] ErrorMessage
168+ | ErrorInBindingGroup [Ident]
171− | ErrorInDataBindingGroup ErrorMessage
169+ | ErrorInDataBindingGroup
172− | ErrorInTypeSynonym ProperName ErrorMessage
170+ | ErrorInTypeSynonym ProperName
173− | ErrorInValueDeclaration Ident ErrorMessage
171+ | ErrorInValueDeclaration Ident
174− | ErrorInTypeDeclaration Ident ErrorMessage
172+ | ErrorInTypeDeclaration Ident
175− | ErrorInForeignImport Ident ErrorMessage
173+ | ErrorInForeignImport Ident
176− | PositionedError SourceSpan ErrorMessage
174+ | PositionedError SourceSpan
177− | SimpleErrorWrapper SimpleErrorMessage
175+ deriving Show
178− 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)
179
187
180instance UnificationError Type ErrorMessage where
188instance UnificationError Type ErrorMessage where
181− occursCheckFailed t = SimpleErrorWrapper $ InfiniteType t
189+ occursCheckFailed t = ErrorMessage [] $ InfiniteType t
182
190
183instance UnificationError Kind ErrorMessage where
191instance UnificationError Kind ErrorMessage where
184− occursCheckFailed k = SimpleErrorWrapper $ InfiniteKind k
192+ occursCheckFailed k = ErrorMessage [] $ InfiniteKind k
185
193
186-- |
194-- |
187-- Get the error code for a particular error type
195-- Get the error code for a particular error type
@@ -230,6 +238,7 @@ errorCode em = case unwrapErrorMessage em of
230 CtorConflictsWithClass{} -> "CtorConflictsWithClass"
238 CtorConflictsWithClass{} -> "CtorConflictsWithClass"
231 ClassConflictsWithType{} -> "ClassConflictsWithType"
239 ClassConflictsWithType{} -> "ClassConflictsWithType"
232 ClassConflictsWithCtor{} -> "ClassConflictsWithCtor"
240 ClassConflictsWithCtor{} -> "ClassConflictsWithCtor"
241+ DuplicateModuleName{} -> "DuplicateModuleName"
233 DuplicateClassExport{} -> "DuplicateClassExport"
242 DuplicateClassExport{} -> "DuplicateClassExport"
234 DuplicateValueExport{} -> "DuplicateValueExport"
243 DuplicateValueExport{} -> "DuplicateValueExport"
235 DuplicateTypeArgument{} -> "DuplicateTypeArgument"
244 DuplicateTypeArgument{} -> "DuplicateTypeArgument"
@@ -273,6 +282,7 @@ errorCode em = case unwrapErrorMessage em of
273 ShadowedTypeVar{} -> "ShadowedTypeVar"
282 ShadowedTypeVar{} -> "ShadowedTypeVar"
274 UnusedTypeVar{} -> "UnusedTypeVar"
283 UnusedTypeVar{} -> "UnusedTypeVar"
275 WildcardInferredType{} -> "WildcardInferredType"
284 WildcardInferredType{} -> "WildcardInferredType"
285+ MissingTypeDeclaration{} -> "MissingTypeDeclaration"
276 NotExhaustivePattern{} -> "NotExhaustivePattern"
286 NotExhaustivePattern{} -> "NotExhaustivePattern"
277 OverlappingPattern{} -> "OverlappingPattern"
287 OverlappingPattern{} -> "OverlappingPattern"
278 IncompleteExhaustivityCheck{} -> "IncompleteExhaustivityCheck"
288 IncompleteExhaustivityCheck{} -> "IncompleteExhaustivityCheck"
@@ -300,7 +310,7 @@ nonEmpty = not . null . runMultipleErrors
300-- Create an error set from a single simple error message
310-- Create an error set from a single simple error message
301--
311--
302errorMessage :: SimpleErrorMessage -> MultipleErrors
312errorMessage :: SimpleErrorMessage -> MultipleErrors
303−errorMessage err = MultipleErrors [SimpleErrorWrapper err]
313+errorMessage err = MultipleErrors [ErrorMessage [] err]
304
314
305
315
306-- |
316-- |
@@ -309,12 +319,14 @@ errorMessage err = MultipleErrors [SimpleErrorWrapper err]
309singleError :: ErrorMessage -> MultipleErrors
319singleError :: ErrorMessage -> MultipleErrors
310singleError = MultipleErrors . pure
320singleError = MultipleErrors . pure
311
321
312−-- |
313−-- Lift a function on ErrorMessage to a function on MultipleErrors
322+-- | Lift a function on ErrorMessage to a function on MultipleErrors
314−--
315onErrorMessages :: (ErrorMessage -> ErrorMessage) -> MultipleErrors -> MultipleErrors
323onErrorMessages :: (ErrorMessage -> ErrorMessage) -> MultipleErrors -> MultipleErrors
316onErrorMessages f = MultipleErrors . map f . runMultipleErrors
324onErrorMessages f = MultipleErrors . map f . runMultipleErrors
317
325
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+
318-- | The various types of things which might need to be relabelled in errors messages.
330-- | The various types of things which might need to be relabelled in errors messages.
319data LabelType = TypeLabel | SkolemLabel String deriving (Show, Read, Eq, Ord)
331data LabelType = TypeLabel | SkolemLabel String deriving (Show, Read, Eq, Ord)
320
332
@@ -328,27 +340,7 @@ data Level = Error | Warning deriving Show
328-- Extract nested error messages from wrapper errors
340-- Extract nested error messages from wrapper errors
329--
341--
330unwrapErrorMessage :: ErrorMessage -> SimpleErrorMessage
342unwrapErrorMessage :: ErrorMessage -> SimpleErrorMessage
331−unwrapErrorMessage em = case em of
343+unwrapErrorMessage (ErrorMessage _ se) = se
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
352
344
353replaceUnknowns :: Type -> State UnknownMap Type
345replaceUnknowns :: Type -> State UnknownMap Type
354replaceUnknowns = everywhereOnTypesM replaceTypes
346replaceUnknowns = everywhereOnTypesM replaceTypes
@@ -364,404 +356,406 @@ replaceUnknowns = everywhereOnTypesM replaceTypes
364 replaceTypes other = return other
356 replaceTypes other = return other
365
357
366onTypesInErrorMessageM :: (Applicative m) => (Type -> m Type) -> ErrorMessage -> m ErrorMessage
358onTypesInErrorMessageM :: (Applicative m) => (Type -> m Type) -> ErrorMessage -> m ErrorMessage
367−onTypesInErrorMessageM f = g
359+onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse gHint hints <*> gSimple simple
368 where
360 where
369− gSimple (InfiniteType t) = InfiniteType <$> (f t)
361+ gSimple (InfiniteType t) = InfiniteType <$> f t
370− gSimple (TypesDoNotUnify t1 t2) = TypesDoNotUnify <$> (f t1) <*> (f t2)
362+ gSimple (TypesDoNotUnify t1 t2) = TypesDoNotUnify <$> f t1 <*> f t2
371− gSimple (ConstrainedTypeUnified t1 t2) = ConstrainedTypeUnified <$> (f t1) <*> (f t2)
363+ gSimple (ConstrainedTypeUnified t1 t2) = ConstrainedTypeUnified <$> f t1 <*> f t2
372− gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> (f t)
364+ gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> f t
373− gSimple (PropertyIsMissing s t) = PropertyIsMissing s <$> (f t)
365+ gSimple (PropertyIsMissing s t) = PropertyIsMissing s <$> f t
374− gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> (pure e)
366+ gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> pure e
375 gSimple (InvalidInstanceHead t) = InvalidInstanceHead <$> f t
367 gSimple (InvalidInstanceHead t) = InvalidInstanceHead <$> f t
376 gSimple other = pure other
368 gSimple other = pure other
377− g (ErrorInSubsumption t1 t2 em) = ErrorInSubsumption <$> (f t1) <*> (f t2) <*> (g em)
369+ gHint (ErrorInSubsumption t1 t2) = ErrorInSubsumption <$> f t1 <*> f t2
378− g (ErrorUnifyingTypes t1 t2 e) = ErrorUnifyingTypes <$> (f t1) <*> (f t2) <*> (g e)
370+ gHint (ErrorUnifyingTypes t1 t2) = ErrorUnifyingTypes <$> f t1 <*> f t2
379− g (ErrorCheckingType e t em) = ErrorCheckingType e <$> (f t) <*> (g em)
371+ gHint (ErrorCheckingType e t) = ErrorCheckingType e <$> f t
380− g (ErrorCheckingKind t em) = ErrorCheckingKind <$> (f t) <*> g em
372+ gHint (ErrorCheckingKind t) = ErrorCheckingKind <$> f t
381− g (ErrorInApplication e1 t1 e2 em) = ErrorInApplication e1 <$> (f t1) <*> (pure e2) <*> (g em)
373+ gHint (ErrorInApplication e1 t1 e2) = ErrorInApplication e1 <$> f t1 <*> pure e2
382− g (NotYetDefined x e) = NotYetDefined x <$> (g e)
374+ gHint other = pure other
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
397
375
398-- |
376-- |
399-- Pretty print a single error, simplifying if necessary
377-- Pretty print a single error, simplifying if necessary
400--
378--
401prettyPrintSingleError :: Bool -> Level -> ErrorMessage -> State UnknownMap Box.Box
379prettyPrintSingleError :: 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)
403 where
381 where
404− -- |
382+
405 -- Pretty print an ErrorMessage
383 -- Pretty print an ErrorMessage
406− --
407 prettyPrintErrorMessage :: ErrorMessage -> Box.Box
384 prettyPrintErrorMessage :: ErrorMessage -> Box.Box
408− prettyPrintErrorMessage em =
385+ prettyPrintErrorMessage (ErrorMessage hints simple) =
409 paras $
386 paras $
387+ map renderHint hints ++
388+ renderSimpleErrorMessage simple :
410− go em:suggestions em ++
389+ suggestions simple ++
411 [line $ "See " ++ wikiUri ++ " for more information, or to contribute content related to this " ++ levelText ++ "."]
390 [line $ "See " ++ wikiUri ++ " for more information, or to contribute content related to this " ++ levelText ++ "."]
412 where
391 where
413 wikiUri :: String
392 wikiUri :: String
414 wikiUri = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
393 wikiUri = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
415
394
416− go :: ErrorMessage -> Box.Box
395+ renderSimpleErrorMessage :: SimpleErrorMessage -> Box.Box
417− goSimple (CannotGetFileInfo path) =
396+ renderSimpleErrorMessage (CannotGetFileInfo path) =
418 paras [ line "Unable to read file info: "
397 paras [ line "Unable to read file info: "
419 , indent . line $ path
398 , indent . line $ path
420 ]
399 ]
421− goSimple (CannotReadFile path) =
400+ renderSimpleErrorMessage (CannotReadFile path) =
422 paras [ line "Unable to read file: "
401 paras [ line "Unable to read file: "
423 , indent . line $ path
402 , indent . line $ path
424 ]
403 ]
425− goSimple (CannotWriteFile path) =
404+ renderSimpleErrorMessage (CannotWriteFile path) =
426 paras [ line "Unable to write file: "
405 paras [ line "Unable to write file: "
427 , indent . line $ path
406 , indent . line $ path
428 ]
407 ]
429− goSimple (ErrorParsingExterns err) =
408+ renderSimpleErrorMessage (ErrorParsingExterns err) =
430 paras [ lineWithLevel "parsing externs files: "
409 paras [ lineWithLevel "parsing externs files: "
431− , indent . prettyPrintParseError $ err
410+ , prettyPrintParseError err
432 ]
411 ]
433− goSimple (ErrorParsingFFIModule path) =
412+ renderSimpleErrorMessage (ErrorParsingFFIModule path) =
434 paras [ line "Unable to parse module from FFI file: "
413 paras [ line "Unable to parse module from FFI file: "
435 , indent . line $ path
414 , indent . line $ path
436 ]
415 ]
437− goSimple (ErrorParsingModule err) =
416+ renderSimpleErrorMessage (ErrorParsingModule err) =
438 paras [ line "Unable to parse module: "
417 paras [ line "Unable to parse module: "
439− , indent . prettyPrintParseError $ err
418+ , prettyPrintParseError err
440 ]
419 ]
441− goSimple (MissingFFIModule mn) =
420+ renderSimpleErrorMessage (MissingFFIModule mn) =
442 line $ "Missing FFI implementations for module " ++ runModuleName mn
421 line $ "Missing FFI implementations for module " ++ runModuleName mn
443− goSimple (UnnecessaryFFIModule mn path) =
422+ renderSimpleErrorMessage (UnnecessaryFFIModule mn path) =
444 paras [ line $ "Unnecessary FFI implementations have been provided for module " ++ runModuleName mn ++ ": "
423 paras [ line $ "Unnecessary FFI implementations have been provided for module " ++ runModuleName mn ++ ": "
445 , indent . line $ path
424 , indent . line $ path
446 ]
425 ]
447− goSimple (MultipleFFIModules mn paths) =
426+ renderSimpleErrorMessage (MultipleFFIModules mn paths) =
448− paras $ [ line $ "Multiple FFI implementations have been provided for module " ++ runModuleName mn ++ ": " ]
427+ paras [ line $ "Multiple FFI implementations have been provided for module " ++ runModuleName mn ++ ": "
449− ++ map (indent . line) paths
428+ , indent . paras $ map line paths
429+ ]
450− goSimple (InvalidExternsFile path) =
430+ renderSimpleErrorMessage (InvalidExternsFile path) =
451 paras [ line "Externs file is invalid: "
431 paras [ line "Externs file is invalid: "
452 , indent . line $ path
432 , indent . line $ path
453 ]
433 ]
454− goSimple InvalidDoBind =
434+ renderSimpleErrorMessage InvalidDoBind =
455 line "Bind statement cannot be the last statement in a do block. The last statement must be an expression."
435 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 =
457 line "Let statement cannot be the last statement in a do block. The last statement must be an expression."
437 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 =
459 line "Unable to reorder operators"
439 line "Unable to reorder operators"
460− goSimple UnspecifiedSkolemScope =
440+ renderSimpleErrorMessage UnspecifiedSkolemScope =
461 line "Skolem variable scope is unspecified"
441 line "Skolem variable scope is unspecified"
462− goSimple OverlappingNamesInLet =
442+ renderSimpleErrorMessage OverlappingNamesInLet =
463 line "Overlapping names in let binding."
443 line "Overlapping names in let binding."
464− goSimple (InfiniteType ty) =
444+ renderSimpleErrorMessage (InfiniteType ty) =
465 paras [ line "An infinite type was inferred for an expression: "
445 paras [ line "An infinite type was inferred for an expression: "
466− , indent $ line $ prettyPrintType ty
446+ , indent $ typeAsBox ty
467 ]
447 ]
468− goSimple (InfiniteKind ki) =
448+ renderSimpleErrorMessage (InfiniteKind ki) =
469 paras [ line "An infinite kind was inferred for a type: "
449 paras [ line "An infinite kind was inferred for a type: "
470 , indent $ line $ prettyPrintKind ki
450 , indent $ line $ prettyPrintKind ki
471 ]
451 ]
472− goSimple (MultipleFixities name) =
452+ renderSimpleErrorMessage (MultipleFixities name) =
473 line $ "Multiple fixity declarations for " ++ showIdent name
453 line $ "Multiple fixity declarations for " ++ showIdent name
474− goSimple (OrphanTypeDeclaration nm) =
454+ renderSimpleErrorMessage (OrphanTypeDeclaration nm) =
475 line $ "Orphan type declaration for " ++ showIdent nm
455 line $ "Orphan type declaration for " ++ showIdent nm
476− goSimple (OrphanFixityDeclaration op) =
456+ renderSimpleErrorMessage (OrphanFixityDeclaration op) =
477 line $ "Orphan fixity declaration for " ++ show op
457 line $ "Orphan fixity declaration for " ++ show op
478− goSimple (RedefinedModule name filenames) =
458+ renderSimpleErrorMessage (RedefinedModule name filenames) =
479− paras $ line ("Module " ++ runModuleName name ++ " has been defined multiple times:")
459+ paras [ line ("Module " ++ runModuleName name ++ " has been defined multiple times:")
480− : map (indent . line . displaySourceSpan) filenames
460+ , indent . paras $ map (line . displaySourceSpan) filenames
461+ ]
481− goSimple (RedefinedIdent name) =
462+ renderSimpleErrorMessage (RedefinedIdent name) =
482 line $ "Name " ++ showIdent name ++ " has been defined multiple times"
463 line $ "Name " ++ showIdent name ++ " has been defined multiple times"
483− goSimple (UnknownModule mn) =
464+ renderSimpleErrorMessage (UnknownModule mn) =
484 line $ "Unknown module " ++ runModuleName mn
465 line $ "Unknown module " ++ runModuleName mn
485− goSimple (UnknownType name) =
466+ renderSimpleErrorMessage (UnknownType name) =
486 line $ "Unknown type " ++ showQualified runProperName name
467 line $ "Unknown type " ++ showQualified runProperName name
487− goSimple (UnknownTypeClass name) =
468+ renderSimpleErrorMessage (UnknownTypeClass name) =
488 line $ "Unknown type class " ++ showQualified runProperName name
469 line $ "Unknown type class " ++ showQualified runProperName name
489− goSimple (UnknownValue name) =
470+ renderSimpleErrorMessage (UnknownValue name) =
490 line $ "Unknown value " ++ showQualified showIdent name
471 line $ "Unknown value " ++ showQualified showIdent name
491− goSimple (UnknownTypeConstructor name) =
472+ renderSimpleErrorMessage (UnknownTypeConstructor name) =
492 line $ "Unknown type constructor " ++ showQualified runProperName name
473 line $ "Unknown type constructor " ++ showQualified runProperName name
493− goSimple (UnknownDataConstructor dc tc) =
474+ renderSimpleErrorMessage (UnknownDataConstructor dc tc) =
494 line $ "Unknown data constructor " ++ showQualified runProperName dc ++ foldMap ((" for type constructor " ++) . showQualified runProperName) tc
475 line $ "Unknown data constructor " ++ showQualified runProperName dc ++ foldMap ((" for type constructor " ++) . showQualified runProperName) tc
495− goSimple (UnknownImportType mn name) =
476+ renderSimpleErrorMessage (UnknownImportType mn name) =
496 line $ "Module " ++ runModuleName mn ++ " does not export type " ++ runProperName name
477 line $ "Module " ++ runModuleName mn ++ " does not export type " ++ runProperName name
497− goSimple (UnknownExportType name) =
478+ renderSimpleErrorMessage (UnknownExportType name) =
498 line $ "Cannot export unknown type " ++ runProperName name
479 line $ "Cannot export unknown type " ++ runProperName name
499− goSimple (UnknownImportTypeClass mn name) =
480+ renderSimpleErrorMessage (UnknownImportTypeClass mn name) =
500 line $ "Module " ++ runModuleName mn ++ " does not export type class " ++ runProperName name
481 line $ "Module " ++ runModuleName mn ++ " does not export type class " ++ runProperName name
501− goSimple (UnknownExportTypeClass name) =
482+ renderSimpleErrorMessage (UnknownExportTypeClass name) =
502 line $ "Cannot export unknown type class " ++ runProperName name
483 line $ "Cannot export unknown type class " ++ runProperName name
503− goSimple (UnknownImportValue mn name) =
484+ renderSimpleErrorMessage (UnknownImportValue mn name) =
504 line $ "Module " ++ runModuleName mn ++ " does not export value " ++ showIdent name
485 line $ "Module " ++ runModuleName mn ++ " does not export value " ++ showIdent name
505− goSimple (UnknownExportValue name) =
486+ renderSimpleErrorMessage (UnknownExportValue name) =
506 line $ "Cannot export unknown value " ++ showIdent name
487 line $ "Cannot export unknown value " ++ showIdent name
507− goSimple (UnknownExportModule name) =
488+ renderSimpleErrorMessage (UnknownExportModule name) =
508 line $ "Cannot export unknown module " ++ runModuleName name ++ ", it either does not exist or has not been imported by the current module"
489 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) =
510 line $ "Module " ++ runModuleName mn ++ " does not export data constructor " ++ runProperName dcon ++ " for type " ++ runProperName tcon
491 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) =
512 line $ "Cannot export data constructor " ++ runProperName dcon ++ " for type " ++ runProperName tcon ++ " as it has not been declared"
493 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) =
514 line $ "Cannot declare " ++ show nm ++ " since another declaration of that name was imported from " ++ runModuleName mn
495 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) =
516 line $ "Conflicting imports for " ++ nm ++ " from modules " ++ runModuleName m1 ++ " and " ++ runModuleName m2
497 line $ "Conflicting imports for " ++ nm ++ " from modules " ++ runModuleName m1 ++ " and " ++ runModuleName m2
517− goSimple (ConflictingTypeDecls nm) =
498+ renderSimpleErrorMessage (ConflictingTypeDecls nm) =
518 line $ "Conflicting type declarations for " ++ runProperName nm
499 line $ "Conflicting type declarations for " ++ runProperName nm
519− goSimple (ConflictingCtorDecls nm) =
500+ renderSimpleErrorMessage (ConflictingCtorDecls nm) =
520 line $ "Conflicting data constructor declarations for " ++ runProperName nm
501 line $ "Conflicting data constructor declarations for " ++ runProperName nm
521− goSimple (TypeConflictsWithClass nm) =
502+ renderSimpleErrorMessage (TypeConflictsWithClass nm) =
522 line $ "Type " ++ runProperName nm ++ " conflicts with type class declaration of the same name"
503 line $ "Type " ++ runProperName nm ++ " conflicts with type class declaration of the same name"
523− goSimple (CtorConflictsWithClass nm) =
504+ renderSimpleErrorMessage (CtorConflictsWithClass nm) =
524 line $ "Data constructor " ++ runProperName nm ++ " conflicts with type class declaration of the same name"
505 line $ "Data constructor " ++ runProperName nm ++ " conflicts with type class declaration of the same name"
525− goSimple (ClassConflictsWithType nm) =
506+ renderSimpleErrorMessage (ClassConflictsWithType nm) =
526 line $ "Type class " ++ runProperName nm ++ " conflicts with type declaration of the same name"
507 line $ "Type class " ++ runProperName nm ++ " conflicts with type declaration of the same name"
527− goSimple (ClassConflictsWithCtor nm) =
508+ renderSimpleErrorMessage (ClassConflictsWithCtor nm) =
528 line $ "Type class " ++ runProperName nm ++ " conflicts with data constructor declaration of the same name"
509 line $ "Type class " ++ runProperName nm ++ " conflicts with data constructor declaration of the same name"
510+ renderSimpleErrorMessage (DuplicateModuleName mn) =
511+ line $ "Module " ++ runModuleName mn ++ " has been defined multiple times."
529− goSimple (DuplicateClassExport nm) =
512+ renderSimpleErrorMessage (DuplicateClassExport nm) =
530 line $ "Duplicate export declaration for type class " ++ runProperName nm
513 line $ "Duplicate export declaration for type class " ++ runProperName nm
531− goSimple (DuplicateValueExport nm) =
514+ renderSimpleErrorMessage (DuplicateValueExport nm) =
532 line $ "Duplicate export declaration for value " ++ showIdent nm
515 line $ "Duplicate export declaration for value " ++ showIdent nm
533− goSimple (CycleInDeclaration nm) =
516+ renderSimpleErrorMessage (CycleInDeclaration nm) =
534 line $ "Cycle in declaration of " ++ showIdent nm
517 line $ "Cycle in declaration of " ++ showIdent nm
535− goSimple (CycleInModules mns) =
518+ renderSimpleErrorMessage (CycleInModules mns) =
536 line $ "Cycle in module dependencies: " ++ intercalate ", " (map runModuleName mns)
519 line $ "Cycle in module dependencies: " ++ intercalate ", " (map runModuleName mns)
537− goSimple (CycleInTypeSynonym pn) =
520+ renderSimpleErrorMessage (CycleInTypeSynonym pn) =
538 line $ "Cycle in type synonym" ++ foldMap ((" " ++) . runProperName) pn
521 line $ "Cycle in type synonym" ++ foldMap ((" " ++) . runProperName) pn
539− goSimple (NameIsUndefined ident) =
522+ renderSimpleErrorMessage (NameIsUndefined ident) =
540 line $ showIdent ident ++ " is undefined"
523 line $ showIdent ident ++ " is undefined"
541− goSimple (NameNotInScope ident) =
524+ renderSimpleErrorMessage (NameNotInScope ident) =
542 line $ showIdent ident ++ " may not be defined in the current scope"
525 line $ showIdent ident ++ " may not be defined in the current scope"
543− goSimple (UndefinedTypeVariable name) =
526+ renderSimpleErrorMessage (UndefinedTypeVariable name) =
544 line $ "Type variable " ++ runProperName name ++ " is undefined"
527 line $ "Type variable " ++ runProperName name ++ " is undefined"
545− goSimple (PartiallyAppliedSynonym name) =
528+ renderSimpleErrorMessage (PartiallyAppliedSynonym name) =
546 paras [ line $ "Partially applied type synonym " ++ showQualified runProperName name
529 paras [ line $ "Partially applied type synonym " ++ showQualified runProperName name
547 , line "Type synonyms must be applied to all of their type arguments."
530 , line "Type synonyms must be applied to all of their type arguments."
548 ]
531 ]
549− goSimple (EscapedSkolem binding) =
532+ renderSimpleErrorMessage (EscapedSkolem binding) =
550 paras $ [ line "A type variable has escaped its scope." ]
533 paras $ [ line "A type variable has escaped its scope." ]
551 <> foldMap (\expr -> [ line "Relevant expression: "
534 <> foldMap (\expr -> [ line "Relevant expression: "
552− , indent $ line $ prettyPrintValue expr
535+ , indent $ prettyPrintValue expr
553 ]) binding
536 ]) binding
554− goSimple (TypesDoNotUnify t1 t2)
537+ renderSimpleErrorMessage (TypesDoNotUnify t1 t2)
555 = paras [ line "Cannot unify type"
538 = paras [ line "Cannot unify type"
556− , indent $ line $ prettyPrintType t1
539+ , indent $ typeAsBox t1
557 , line "with type"
540 , line "with type"
558− , indent $ line $ prettyPrintType t2
541+ , indent $ typeAsBox t2
559 ]
542 ]
560− goSimple (KindsDoNotUnify k1 k2) =
543+ renderSimpleErrorMessage (KindsDoNotUnify k1 k2) =
561 paras [ line "Cannot unify kind"
544 paras [ line "Cannot unify kind"
562 , indent $ line $ prettyPrintKind k1
545 , indent $ line $ prettyPrintKind k1
563 , line "with kind"
546 , line "with kind"
564 , indent $ line $ prettyPrintKind k2
547 , indent $ line $ prettyPrintKind k2
565 ]
548 ]
566− goSimple (ConstrainedTypeUnified t1 t2) =
549+ renderSimpleErrorMessage (ConstrainedTypeUnified t1 t2) =
567 paras [ line "Cannot unify constrained type"
550 paras [ line "Cannot unify constrained type"
568− , indent $ line $ prettyPrintType t1
551+ , indent $ typeAsBox t1
569 , line "with type"
552 , line "with type"
570− , indent $ line $ prettyPrintType t2
553+ , indent $ typeAsBox t2
571− ]
554+ ]
572− goSimple (OverlappingInstances nm ts (d : ds)) =
555+ renderSimpleErrorMessage (OverlappingInstances nm ts (d : ds)) =
573− paras [ line $ "Overlapping instances found for " ++ showQualified runProperName nm ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ ":"
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:"
574 , indent $ paras (line (showQualified showIdent d ++ " (chosen)") : map (line . showQualified showIdent) ds)
561 , indent $ paras (line (showQualified showIdent d ++ " (chosen)") : map (line . showQualified showIdent) ds)
575 ]
562 ]
576− goSimple OverlappingInstances{} = error "OverlappingInstances: empty instance list"
563+ renderSimpleErrorMessage OverlappingInstances{} = error "OverlappingInstances: empty instance list"
577− goSimple (NoInstanceFound nm ts) =
564+ renderSimpleErrorMessage (NoInstanceFound nm ts) =
578− line $ "No instance found for " ++ showQualified runProperName nm ++ " " ++ unwords (map prettyPrintTypeAtom 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+ ]
579− goSimple (PossiblyInfiniteInstance nm ts) =
570+ renderSimpleErrorMessage (PossiblyInfiniteInstance nm ts) =
580− line $ "Instance for " ++ showQualified runProperName nm ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ " is possibly infinite."
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+ ]
581− goSimple (CannotDerive nm ts) =
577+ renderSimpleErrorMessage (CannotDerive nm ts) =
582− line $ "Cannot derive " ++ showQualified runProperName nm ++ " instance for " ++ unwords (map prettyPrintTypeAtom 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− goSimple (CannotFindDerivingType nm) =
583+ renderSimpleErrorMessage (CannotFindDerivingType nm) =
584 line $ "Cannot derive instance, because the type declaration for " ++ runProperName nm ++ " could not be found."
584 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) =
586 paras $ [ line $ "Duplicate label " ++ show l ++ " in row." ]
586 paras $ [ line $ "Duplicate label " ++ show l ++ " in row." ]
587 <> foldMap (\expr' -> [ line "Relevant expression: "
587 <> foldMap (\expr' -> [ line "Relevant expression: "
588− , indent $ line $ prettyPrintValue expr'
588+ , indent $ prettyPrintValue expr'
589 ]) expr
589 ]) expr
590− goSimple (DuplicateTypeArgument name) =
590+ renderSimpleErrorMessage (DuplicateTypeArgument name) =
591 line $ "Duplicate type argument " ++ show name
591 line $ "Duplicate type argument " ++ show name
592− goSimple (DuplicateValueDeclaration nm) =
592+ renderSimpleErrorMessage (DuplicateValueDeclaration nm) =
593 line $ "Duplicate value declaration for " ++ showIdent nm
593 line $ "Duplicate value declaration for " ++ showIdent nm
594− goSimple (ArgListLengthsDiffer ident) =
594+ renderSimpleErrorMessage (ArgListLengthsDiffer ident) =
595 line $ "Argument list lengths differ in declaration " ++ showIdent ident
595 line $ "Argument list lengths differ in declaration " ++ showIdent ident
596− goSimple (OverlappingArgNames ident) =
596+ renderSimpleErrorMessage (OverlappingArgNames ident) =
597 line $ "Overlapping names in function/binder" ++ foldMap ((" in declaration" ++) . showIdent) ident
597 line $ "Overlapping names in function/binder" ++ foldMap ((" in declaration" ++) . showIdent) ident
598− goSimple (MissingClassMember ident) =
598+ renderSimpleErrorMessage (MissingClassMember ident) =
599 line $ "Member " ++ showIdent ident ++ " has not been implemented"
599 line $ "Member " ++ showIdent ident ++ " has not been implemented"
600− goSimple (ExtraneousClassMember ident) =
600+ renderSimpleErrorMessage (ExtraneousClassMember ident) =
601 line $ "Member " ++ showIdent ident ++ " is not a member of the class being instantiated"
601 line $ "Member " ++ showIdent ident ++ " is not a member of the class being instantiated"
602− goSimple (ExpectedType ty kind) =
602+ renderSimpleErrorMessage (ExpectedType ty kind) =
603 paras [ line "In a type-annotated expression x :: t, the type t must have kind *."
603 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."
605 ]
609 ]
606− goSimple (IncorrectConstructorArity nm) =
610+ renderSimpleErrorMessage (IncorrectConstructorArity nm) =
607 line $ "Wrong number of arguments to constructor " ++ showQualified runProperName nm
611 line $ "Wrong number of arguments to constructor " ++ showQualified runProperName nm
608− goSimple SubsumptionCheckFailed = line "Unable to check type subsumption"
612+ renderSimpleErrorMessage SubsumptionCheckFailed = line "Unable to check type subsumption"
609− goSimple (ExprDoesNotHaveType expr ty) =
613+ renderSimpleErrorMessage (ExprDoesNotHaveType expr ty) =
610 paras [ line "Expression"
614 paras [ line "Expression"
611− , indent $ line $ prettyPrintValue expr
615+ , indent $ prettyPrintValue expr
612 , line "does not have type"
616 , line "does not have type"
613− , indent $ line $ prettyPrintType ty
617+ , indent $ typeAsBox ty
614 ]
618 ]
615− goSimple (PropertyIsMissing prop row) =
619+ renderSimpleErrorMessage (PropertyIsMissing prop row) =
620+ paras [ line "Row"
621+ , indent $ prettyPrintRowWith '(' ')' row
616− line $ "Row " ++ prettyPrintRow row ++ " lacks required property " ++ show prop
622+ , line $ "lacks required property " ++ show prop
623+ ]
617− goSimple (CannotApplyFunction fn arg) =
624+ renderSimpleErrorMessage (CannotApplyFunction fn arg) =
618 paras [ line "Cannot apply function of type"
625 paras [ line "Cannot apply function of type"
619− , indent $ line $ prettyPrintType fn
626+ , indent $ typeAsBox fn
620 , line "to argument"
627 , line "to argument"
621− , indent $ line $ prettyPrintValue arg
628+ , indent $ prettyPrintValue arg
622 ]
629 ]
623− goSimple TypeSynonymInstance =
630+ renderSimpleErrorMessage TypeSynonymInstance =
624 line "Type synonym instances are disallowed"
631 line "Type synonym instances are disallowed"
625− goSimple (OrphanInstance nm cnm ts) =
632+ renderSimpleErrorMessage (OrphanInstance nm cnm ts) =
626− paras [ line $ "Instance " ++ showIdent nm ++ " for " ++ showQualified runProperName cnm ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ " is an orphan instance."
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."
627 , line "An orphan instance is an instance which is defined in neither the class module nor the data type module."
638 , line "An orphan instance is an instance which is defined in neither the class module nor the data type module."
628 , line "Consider moving the instance, if possible, or using a newtype wrapper."
639 , line "Consider moving the instance, if possible, or using a newtype wrapper."
629 ]
640 ]
630− goSimple InvalidNewtype =
641+ renderSimpleErrorMessage InvalidNewtype =
631 line "Newtypes must define a single constructor with a single argument"
642 line "Newtypes must define a single constructor with a single argument"
632− goSimple (InvalidInstanceHead ty) =
643+ renderSimpleErrorMessage (InvalidInstanceHead ty) =
633 paras [ line "Invalid type in class instance head:"
644 paras [ line "Invalid type in class instance head:"
634− , indent $ line $ prettyPrintType ty
645+ , indent $ typeAsBox ty
635 ]
646 ]
636− goSimple (TransitiveExportError x ys) =
647+ renderSimpleErrorMessage (TransitiveExportError x ys) =
637 paras $ line ("An export for " ++ prettyPrintExport x ++ " requires the following to also be exported: ")
648 paras $ line ("An export for " ++ prettyPrintExport x ++ " requires the following to also be exported: ")
638 : map (line . prettyPrintExport) ys
649 : map (line . prettyPrintExport) ys
639− goSimple (ShadowedName nm) =
650+ renderSimpleErrorMessage (ShadowedName nm) =
640 line $ "Name '" ++ showIdent nm ++ "' was shadowed"
651 line $ "Name '" ++ showIdent nm ++ "' was shadowed"
641− goSimple (ShadowedTypeVar tv) =
652+ renderSimpleErrorMessage (ShadowedTypeVar tv) =
642 line $ "Type variable '" ++ tv ++ "' was shadowed"
653 line $ "Type variable '" ++ tv ++ "' was shadowed"
643− goSimple (UnusedTypeVar tv) =
654+ renderSimpleErrorMessage (UnusedTypeVar tv) =
644 line $ "Type variable '" ++ tv ++ "' was declared but not used"
655 line $ "Type variable '" ++ tv ++ "' was declared but not used"
645− goSimple (ClassOperator className opName) =
656+ renderSimpleErrorMessage (ClassOperator className opName) =
646 paras [ line $ "Class '" ++ runProperName className ++ "' declares operator " ++ showIdent opName ++ "."
657 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:"
658+ , 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"
659+ , indent . line $ showIdent opName ++ " = someMember"
649 ]
660 ]
650− goSimple (MisleadingEmptyTypeImport mn name) =
661+ renderSimpleErrorMessage (MisleadingEmptyTypeImport mn name) =
651 line $ "Importing type " ++ runProperName name ++ "(..) from " ++ runModuleName mn ++ " is misleading as it has no exported data constructors"
662 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) =
653 line $ "Attempted to hide module " ++ runModuleName name ++ " in import expression, this is not permitted"
664 line $ "Attempted to hide module " ++ runModuleName name ++ " in import expression, this is not permitted"
654− goSimple (WildcardInferredType ty) =
665+ renderSimpleErrorMessage (WildcardInferredType ty) =
655− line $ "The wildcard type definition has the inferred type " ++ prettyPrintType 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+ ]
656− goSimple (NotExhaustivePattern bs b) =
675+ renderSimpleErrorMessage (NotExhaustivePattern bs b) =
657 paras $ [ line "A case expression could not be determined to cover all inputs."
676 paras $ [ line "A case expression could not be determined to cover all inputs."
658 , line "The following additional cases are required to cover all inputs:\n"
677 , line "The following additional cases are required to cover all inputs:\n"
659 , Box.hsep 1 Box.left (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs))
678 , Box.hsep 1 Box.left (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs))
660 ] ++
679 ] ++
661 [ line "..." | not b ]
680 [ line "..." | not b ]
662− goSimple (OverlappingPattern bs b) =
681+ renderSimpleErrorMessage (OverlappingPattern bs b) =
663 paras $ [ line "A case expression contains unreachable cases:\n"
682 paras $ [ line "A case expression contains unreachable cases:\n"
664 , Box.hsep 1 Box.left (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs))
683 , Box.hsep 1 Box.left (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs))
665 ] ++
684 ] ++
666 [ line "..." | not b ]
685 [ line "..." | not b ]
667− goSimple IncompleteExhaustivityCheck =
686+ renderSimpleErrorMessage IncompleteExhaustivityCheck =
668 paras [ line "An exhaustivity check was abandoned due to too many possible cases."
687 paras [ line "An exhaustivity check was abandoned due to too many possible cases."
669 , line "You may want to decomposing your data types into smaller types."
688 , line "You may want to decomposing your data types into smaller types."
670 ]
689 ]
690+
691+ renderHint :: ErrorMessageHint -> Box.Box
671− go (NotYetDefined names err) =
692+ renderHint (NotYetDefined names) =
672− paras [ line $ "The following are not yet defined here: " ++ intercalate ", " (map showIdent names) ++ ":"
693+ line $ "The following are not yet defined here: " ++ intercalate ", " (map showIdent names) ++ ":"
673− , indent $ go err
674− ]
675− go (ErrorUnifyingTypes t1 t2 err) =
694+ renderHint (ErrorUnifyingTypes t1 t2) =
676 paras [ lineWithLevel "unifying type "
695 paras [ lineWithLevel "unifying type "
677− , indent $ line $ prettyPrintType t1
696+ , indent $ typeAsBox t1
678 , line "with type"
697 , line "with type"
679− , indent $ line $ prettyPrintType t2
698+ , indent $ typeAsBox t2
680− , go err
681 ]
699 ]
682− go (ErrorInExpression expr err) =
700+ renderHint (ErrorInExpression expr) =
683 paras [ lineWithLevel "in expression:"
701 paras [ lineWithLevel "in expression:"
684− , indent $ line $ prettyPrintValue expr
702+ , indent $ prettyPrintValue expr
685− , go err
686 ]
703 ]
687− go (ErrorInModule mn err) =
704+ renderHint (ErrorInModule mn) =
688 paras [ lineWithLevel $ "in module " ++ runModuleName mn ++ ":"
705 paras [ lineWithLevel $ "in module " ++ runModuleName mn ++ ":"
689− , go err
690 ]
706 ]
691− go (ErrorInSubsumption t1 t2 err) =
707+ renderHint (ErrorInSubsumption t1 t2) =
692 paras [ lineWithLevel "checking that type "
708 paras [ lineWithLevel "checking that type "
693− , indent $ line $ prettyPrintType t1
709+ , indent $ typeAsBox t1
694 , line "subsumes type"
710 , line "subsumes type"
695− , indent $ line $ prettyPrintType t2
711+ , indent $ typeAsBox t2
696− , go err
697 ]
712 ]
698− go (ErrorInInstance name ts err) =
713+ renderHint (ErrorInInstance nm ts) =
699− paras [ lineWithLevel $ "in type class instance " ++ showQualified runProperName name ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ ":"
714+ paras [ lineWithLevel "in type class instance"
700− , go err
715+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
716+ , Box.vcat Box.left (map typeAtomAsBox ts)
717+ ]
701 ]
718 ]
702− go (ErrorCheckingKind ty err) =
719+ renderHint (ErrorCheckingKind ty) =
703 paras [ lineWithLevel "checking kind of type "
720 paras [ lineWithLevel "checking kind of type "
704− , indent $ line $ prettyPrintType ty
721+ , indent $ typeAsBox ty
705− , go err
706 ]
722 ]
707− go (ErrorInferringType expr err) =
723+ renderHint (ErrorInferringType expr) =
708 paras [ lineWithLevel "inferring type of value "
724 paras [ lineWithLevel "inferring type of value "
709− , indent $ line $ prettyPrintValue expr
725+ , indent $ prettyPrintValue expr
710− , go err
711 ]
726 ]
712− go (ErrorCheckingType expr ty err) =
727+ renderHint (ErrorCheckingType expr ty) =
713 paras [ lineWithLevel "checking that value "
728 paras [ lineWithLevel "checking that value "
714− , indent $ line $ prettyPrintValue expr
729+ , indent $ prettyPrintValue expr
715 , line "has type"
730 , line "has type"
716− , indent $ line $ prettyPrintType ty
731+ , indent $ typeAsBox ty
717− , go err
718 ]
732 ]
719− go (ErrorInApplication f t a err) =
733+ renderHint (ErrorInApplication f t a) =
720 paras [ lineWithLevel "applying function"
734 paras [ lineWithLevel "applying function"
721− , indent $ line $ prettyPrintValue f
735+ , indent $ prettyPrintValue f
722 , line "of type"
736 , line "of type"
723− , indent $ line $ prettyPrintType t
737+ , indent $ typeAsBox t
724 , line "to argument"
738 , line "to argument"
725− , indent $ line $ prettyPrintValue a
739+ , indent $ prettyPrintValue a
726− , go err
727− ]
740+ ]
728− go (ErrorInDataConstructor nm err) =
741+ renderHint (ErrorInDataConstructor nm) =
729− paras [ lineWithLevel $ "in data constructor " ++ runProperName nm ++ ":"
742+ lineWithLevel $ "in data constructor " ++ runProperName nm ++ ":"
730− , go err
731− ]
732− go (ErrorInTypeConstructor nm err) =
743+ renderHint (ErrorInTypeConstructor nm) =
733− paras [ lineWithLevel $ "in type constructor " ++ runProperName nm ++ ":"
744+ lineWithLevel $ "in type constructor " ++ runProperName nm ++ ":"
734− , go err
735− ]
736− go (ErrorInBindingGroup nms err) =
745+ renderHint (ErrorInBindingGroup nms) =
737− paras [ lineWithLevel $ "in binding group " ++ intercalate ", " (map showIdent nms) ++ ":"
746+ lineWithLevel $ "in binding group " ++ intercalate ", " (map showIdent nms) ++ ":"
738− , go err
739− ]
740− go (ErrorInDataBindingGroup err) =
747+ renderHint ErrorInDataBindingGroup =
741− paras [ lineWithLevel $ "in data binding group:"
748+ lineWithLevel "in data binding group:"
742− , go err
743− ]
744− go (ErrorInTypeSynonym name err) =
749+ renderHint (ErrorInTypeSynonym name) =
745− paras [ lineWithLevel $ "in type synonym " ++ runProperName name ++ ":"
750+ lineWithLevel $ "in type synonym " ++ runProperName name ++ ":"
746− , go err
747− ]
748− go (ErrorInValueDeclaration n err) =
751+ renderHint (ErrorInValueDeclaration n) =
749− paras [ lineWithLevel $ "in value declaration " ++ showIdent n ++ ":"
752+ lineWithLevel $ "in value declaration " ++ showIdent n ++ ":"
750− , go err
751− ]
752− go (ErrorInTypeDeclaration n err) =
753+ renderHint (ErrorInTypeDeclaration n) =
753− paras [ lineWithLevel $ "in type declaration for " ++ showIdent n ++ ":"
754+ lineWithLevel $ "in type declaration for " ++ showIdent n ++ ":"
754− , go err
755− ]
756− go (ErrorInForeignImport nm err) =
755+ renderHint (ErrorInForeignImport nm) =
757− paras [ lineWithLevel $ "in foreign import " ++ showIdent nm ++ ":"
756+ lineWithLevel $ "in foreign import " ++ showIdent nm ++ ":"
758− , go err
759− ]
760− go (PositionedError srcSpan err) =
757+ renderHint (PositionedError srcSpan) =
761− paras [ lineWithLevel $ "at " ++ displaySourceSpan srcSpan ++ ":"
758+ lineWithLevel $ "at " ++ displaySourceSpan srcSpan ++ ":"
762− , indent $ go err
763− ]
764− go (SimpleErrorWrapper sem) = goSimple sem
765
759
766 lineWithLevel :: String -> Box.Box
760 lineWithLevel :: String -> Box.Box
767 lineWithLevel text = line $ show level ++ " " ++ text
761 lineWithLevel text = line $ show level ++ " " ++ text
@@ -771,23 +765,19 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
771 Error -> "error"
765 Error -> "error"
772 Warning -> "warning"
766 Warning -> "warning"
773
767
774− suggestions :: ErrorMessage -> [Box.Box]
768+ suggestions :: SimpleErrorMessage -> [Box.Box]
775− suggestions = suggestions' . unwrapErrorMessage
776− where
777− suggestions' (ConflictingImport nm im) = [ line $ "Possible fix: hide " ++ show nm ++ " when importing " ++ runModuleName im ++ ":"
769+ suggestions (ConflictingImport nm im) = [ line $ "Possible fix: hide " ++ show nm ++ " when importing " ++ runModuleName im ++ ":"
778 , indent . line $ "import " ++ runModuleName im ++ " hiding (" ++ nm ++ ")"
770 , indent . line $ "import " ++ runModuleName im ++ " hiding (" ++ nm ++ ")"
779 ]
771 ]
780− suggestions' (TypesDoNotUnify t1 t2)
772+ suggestions (TypesDoNotUnify t1 t2)
781− | isObject t1 && isFunction t2 = [line "Note that function composition in PureScript is defined using (<<<)"]
773+ | isObject t1 && isFunction t2 = [line "Note that function composition in PureScript is defined using (<<<)"]
782− | otherwise = []
774+ | otherwise = []
783− suggestions' _ = []
775+ suggestions _ = []
784
776
785 paras :: [Box.Box] -> Box.Box
777 paras :: [Box.Box] -> Box.Box
786 paras = Box.vcat Box.left
778 paras = Box.vcat Box.left
787
779
788− -- |
789 -- Pretty print and export declaration
780 -- Pretty print and export declaration
790− --
791 prettyPrintExport :: DeclarationRef -> String
781 prettyPrintExport :: DeclarationRef -> String
792 prettyPrintExport (TypeRef pn _) = runProperName pn
782 prettyPrintExport (TypeRef pn _) = runProperName pn
793 prettyPrintExport (ValueRef ident) = showIdent ident
783 prettyPrintExport (ValueRef ident) = showIdent ident
@@ -796,38 +786,44 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
796 prettyPrintExport (ModuleRef name) = "module " ++ runModuleName name
786 prettyPrintExport (ModuleRef name) = "module " ++ runModuleName name
797 prettyPrintExport (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
787 prettyPrintExport (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
798
788
799− -- |
789+ -- Hints get added at the front, so we need to reverse them before rendering
800− -- Simplify an error message
790+ reverseHints :: ErrorMessage -> ErrorMessage
801− --
791+ reverseHints (ErrorMessage hints simple) = ErrorMessage (reverse hints) simple
792+
793+ -- | Put positional hints at the front of the list
802− simplifyErrorMessage :: ErrorMessage -> ErrorMessage
794+ positionHintsFirst :: ErrorMessage -> ErrorMessage
803− simplifyErrorMessage = unwrap Nothing
795+ positionHintsFirst (ErrorMessage hints simple) = ErrorMessage (uncurry (++) $ partition (isPositionHint . hintCategory) hints) simple
804 where
796 where
805− unwrap :: Maybe SourceSpan -> ErrorMessage -> ErrorMessage
797+ isPositionHint :: HintCategory -> Bool
806− unwrap pos (ErrorInExpression _ err) = unwrap pos err
798+ isPositionHint PositionHint = True
807− unwrap pos (ErrorInInstance name ts err) = ErrorInInstance name ts (unwrap pos err)
799+ isPositionHint OtherHint = True
808− unwrap pos (ErrorInSubsumption t1 t2 err) = ErrorInSubsumption t1 t2 (unwrap pos err)
800+ isPositionHint _ = False
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
830
801
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
831
827
832-- |
828-- |
833-- Pretty print multiple errors
829-- Pretty print multiple errors
@@ -843,11 +839,11 @@ prettyPrintMultipleWarnings full = renderBox . prettyPrintMultipleWarningsBox fu
843
839
844-- | Pretty print warnings as a Box
840-- | Pretty print warnings as a Box
845prettyPrintMultipleWarningsBox :: Bool -> MultipleErrors -> Box.Box
841prettyPrintMultipleWarningsBox :: 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
847
843
848-- | Pretty print errors as a Box
844-- | Pretty print errors as a Box
849prettyPrintMultipleErrorsBox :: Bool -> MultipleErrors -> Box.Box
845prettyPrintMultipleErrorsBox :: 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
851
847
852prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> State UnknownMap Box.Box
848prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> State UnknownMap Box.Box
853prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
849prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
@@ -857,15 +853,16 @@ prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
857 , result
853 , result
858 ]
854 ]
859prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) = do
855prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) = do
860− result <- forM es $ (liftM $ Box.moveRight 2) . prettyPrintSingleError full level
856+ result <- forM es $ prettyPrintSingleError full level
861− return $
857+ return $ Box.vsep 1 Box.left $ concat $ zipWith withIntro [1 :: Int ..] result
862− Box.vcat Box.left [ Box.text intro
858+ where
863− , Box.vsep 1 Box.left result
859+ withIntro i err = [ Box.text (intro ++ " " ++ show i ++ " of " ++ show (length es) ++ ":")
860+ , Box.moveRight 2 err
864− ]
861+ ]
865
862
866-- | Pretty print a Parsec ParseError as a Box
863-- | Pretty print a Parsec ParseError as a Box
867prettyPrintParseError :: P.ParseError -> Box.Box
864prettyPrintParseError :: 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
869
866
870-- |
867-- |
871-- Pretty print ParseError detail messages.
868-- Pretty print ParseError detail messages.
@@ -878,9 +875,9 @@ prettyPrintParseErrorMessages msgOr msgUnknown msgExpecting msgUnExpected msgEnd
878 | otherwise = Box.vcat Box.left $ map Box.text $ clean [showSysUnExpect,showUnExpect,showExpect,showMessages]
875 | otherwise = Box.vcat Box.left $ map Box.text $ clean [showSysUnExpect,showUnExpect,showExpect,showMessages]
879
876
880 where
877 where
881− (sysUnExpect,msgs1) = span ((SysUnExpect "") ==) msgs
878+ (sysUnExpect,msgs1) = span (SysUnExpect "" ==) msgs
882− (unExpect,msgs2) = span ((UnExpect "") ==) msgs1
879+ (unExpect,msgs2) = span (UnExpect "" ==) msgs1
883− (expect,messages) = span ((Expect "") ==) msgs2
880+ (expect,messages) = span (Expect "" ==) msgs2
884
881
885 showExpect = showMany msgExpecting expect
882 showExpect = showMany msgExpecting expect
886 showUnExpect = showMany msgUnExpected unExpect
883 showUnExpect = showMany msgUnExpected unExpect
@@ -911,8 +908,9 @@ prettyPrintParseErrorMessages msgOr msgUnknown msgExpecting msgUnExpected msgEnd
911
908
912 clean = nub . filter (not . null)
909 clean = nub . filter (not . null)
913
910
911+-- | Indent to the right, and pad on top and bottom.
914indent :: Box.Box -> Box.Box
912indent :: Box.Box -> Box.Box
915−indent = Box.moveRight 2
913+indent = Box.moveUp 1 . Box.moveDown 1 . Box.moveRight 2
916
914
917line :: String -> Box.Box
915line :: String -> Box.Box
918line = Box.text
916line = Box.text
@@ -928,7 +926,7 @@ renderBox = unlines . map trimEnd . lines . Box.render
928interpretMultipleErrorsAndWarnings :: (MonadError MultipleErrors m, MonadWriter MultipleErrors m) => (Either MultipleErrors a, MultipleErrors) -> m a
926interpretMultipleErrorsAndWarnings :: (MonadError MultipleErrors m, MonadWriter MultipleErrors m) => (Either MultipleErrors a, MultipleErrors) -> m a
929interpretMultipleErrorsAndWarnings (err, ws) = do
927interpretMultipleErrorsAndWarnings (err, ws) = do
930 tell ws
928 tell ws
931− either throwError return $ err
929+ either throwError return err
932
930
933-- |
931-- |
934-- Rethrow an error with a more detailed error message in the case of failure
932-- Rethrow an error with a more detailed error message in the case of failure
@@ -952,8 +950,7 @@ warnAndRethrowWithPosition :: (MonadError MultipleErrors m, MonadWriter Multiple
952warnAndRethrowWithPosition pos = rethrowWithPosition pos . warnWithPosition pos
950warnAndRethrowWithPosition pos = rethrowWithPosition pos . warnWithPosition pos
953
951
954withPosition :: SourceSpan -> ErrorMessage -> ErrorMessage
952withPosition :: SourceSpan -> ErrorMessage -> ErrorMessage
955−withPosition _ (PositionedError pos err) = withPosition pos err
953+withPosition pos (ErrorMessage hints se) = ErrorMessage (PositionedError pos : hints) se
956−withPosition pos err = PositionedError pos err
957
954
958-- |
955-- |
959-- Collect errors in in parallel
956-- Collect errors in in parallel
src/Language/PureScript/Linter.hs+5−4
@@ -40,7 +40,7 @@ import Language.PureScript.Linter.Exhaustive as L
40-- |
40-- |
41-- | Right now, this pass only performs a shadowing check.
41-- | Right now, this pass only performs a shadowing check.
42lint :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Module -> m ()
42lint :: 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
44 where
44 where
45 moduleNames :: S.Set Ident
45 moduleNames :: S.Set Ident
46 moduleNames = S.fromList (nub (mapMaybe getDeclIdent ds))
46 moduleNames = S.fromList (nub (mapMaybe getDeclIdent ds))
@@ -58,9 +58,9 @@ lint (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ mapM_
58 let (f, _, _, _, _) = everythingWithContextOnValues moduleNames mempty mappend stepD stepE stepB def def
58 let (f, _, _, _, _) = everythingWithContextOnValues moduleNames mempty mappend stepD stepE stepB def def
59
59
60 f' :: Declaration -> MultipleErrors
60 f' :: Declaration -> MultipleErrors
61− f' (PositionedDeclaration pos _ dec) = onErrorMessages (PositionedError pos) (f' dec)
61+ f' (PositionedDeclaration pos _ dec) = addHint (PositionedError pos) (f' dec)
62− f' dec@(ValueDeclaration name _ _ _) = onErrorMessages (ErrorInValueDeclaration name) (f dec <> checkTypeVarsInDecl dec)
62+ f' dec@(ValueDeclaration name _ _ _) = addHint (ErrorInValueDeclaration name) (f dec <> checkTypeVarsInDecl dec)
63− f' (TypeDeclaration name ty) = onErrorMessages (ErrorInTypeDeclaration name) (checkTypeVars ty)
63+ f' (TypeDeclaration name ty) = addHint (ErrorInTypeDeclaration name) (checkTypeVars ty)
64 f' dec = f dec <> checkTypeVarsInDecl dec
64 f' dec = f dec <> checkTypeVarsInDecl dec
65
65
66 in tell (f' d)
66 in tell (f' d)
@@ -86,6 +86,7 @@ lint (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ mapM_
86 stepB :: S.Set Ident -> Binder -> (S.Set Ident, MultipleErrors)
86 stepB :: S.Set Ident -> Binder -> (S.Set Ident, MultipleErrors)
87 stepB s (VarBinder name) = bindName s name
87 stepB s (VarBinder name) = bindName s name
88 stepB s (NamedBinder name _) = bindName s name
88 stepB s (NamedBinder name _) = bindName s name
89+ stepB s (TypedBinder _ b) = stepB s b
89 stepB s _ = (s, mempty)
90 stepB s _ = (s, mempty)
90
91
91 bindName :: S.Set Ident -> Ident -> (S.Set Ident, MultipleErrors)
92 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
46import Language.PureScript.Types as P
46import Language.PureScript.Types as P
47import Language.PureScript.Errors
47import Language.PureScript.Errors
48
48
49−import Language.PureScript.AST.Traversals (everywhereOnValuesTopDownM)
50−
51-- | There are two modes of failure for the redudancy check:
49-- | There are two modes of failure for the redudancy check:
52--
50--
53-- 1. Exhaustivity was incomeplete due to too many cases, so we couldn't determine redundancy.
51-- 1. Exhaustivity was incomeplete due to too many cases, so we couldn't determine redundancy.
@@ -162,6 +160,7 @@ missingCasesSingle _ _ (BooleanBinder bl) (BooleanBinder br)
162 | bl == br = ([], return True)
160 | bl == br = ([], return True)
163 | otherwise = ([BooleanBinder bl], return False)
161 | otherwise = ([BooleanBinder bl], return False)
164missingCasesSingle env mn b (PositionedBinder _ _ cb) = missingCasesSingle env mn b cb
162missingCasesSingle env mn b (PositionedBinder _ _ cb) = missingCasesSingle env mn b cb
163+missingCasesSingle env mn b (TypedBinder _ cb) = missingCasesSingle env mn b cb
165missingCasesSingle _ _ b _ = ([b], Left Unknown)
164missingCasesSingle _ _ b _ = ([b], Left Unknown)
166
165
167-- |
166-- |
@@ -273,28 +272,39 @@ checkExhaustive env mn numArgs cas = makeResult . first nub $ foldl' step ([init
273-- Exhaustivity checking over a list of declarations
272-- Exhaustivity checking over a list of declarations
274--
273--
275checkExhaustiveDecls :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Environment -> ModuleName -> [Declaration] -> m ()
274checkExhaustiveDecls :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Environment -> ModuleName -> [Declaration] -> m ()
276−checkExhaustiveDecls env mn ds =
275+checkExhaustiveDecls env mn = mapM_ onDecl
277− let (f, _, _) = everywhereOnValuesTopDownM return checkExpr return
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 ()
278
285
279− f' :: Declaration -> m Declaration
286+ onExpr :: Expr -> m ()
280− f' d@(BindingGroupDeclaration bs) = mapM_ (f' . convert) bs >> return d
287+ onExpr (UnaryMinus e) = onExpr e
281− where
288+ onExpr (ArrayLiteral es) = mapM_ onExpr es
282− convert :: (Ident, NameKind, Expr) -> Declaration
289+ onExpr (ObjectLiteral es) = mapM_ (onExpr . snd) es
283− convert (name, nk, e) = ValueDeclaration name nk [] (Right e)
290+ onExpr (TypeClassDictionaryConstructorApp _ e) = onExpr e
284− f' d@(ValueDeclaration name _ _ _) = censor (onErrorMessages (ErrorInValueDeclaration name)) $ f d
291+ onExpr (Accessor _ e) = onExpr e
285− f' (PositionedDeclaration pos com dec) = PositionedDeclaration pos com <$> censor (onErrorMessages (PositionedError pos)) (f' dec)
292+ onExpr (ObjectUpdate o es) = onExpr o >> mapM_ (onExpr . snd) es
286− -- Don't generate two warnings for desugared dictionaries.
293+ onExpr (Abs _ e) = onExpr e
287− f' d@TypeInstanceDeclaration{} = return d
294+ onExpr (App e1 e2) = onExpr e1 >> onExpr e2
288− f' d = f d
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 ()
289
301
290− in mapM_ f' ds
302+ onCaseAlternative :: CaseAlternative -> m ()
291− where
303+ onCaseAlternative (CaseAlternative _ (Left es)) = mapM_ (\(e, g) -> onExpr e >> onExpr g) es
292− checkExpr :: Expr -> m Expr
304+ onCaseAlternative (CaseAlternative _ (Right e)) = onExpr e
293− checkExpr c@(Case expr cas) = checkExhaustive env mn (length expr) cas >> return c
294− checkExpr other = return other
295
305
296-- |
306-- |
297-- Exhaustivity checking over a single module
307-- Exhaustivity checking over a single module
298--
308--
299checkExhaustiveModule :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Environment -> Module -> m ()
309checkExhaustiveModule :: 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 @@
19{-# LANGUAGE RankNTypes #-}
19{-# LANGUAGE RankNTypes #-}
20{-# LANGUAGE RecordWildCards #-}
20{-# LANGUAGE RecordWildCards #-}
21{-# LANGUAGE ScopedTypeVariables #-}
21{-# LANGUAGE ScopedTypeVariables #-}
22+{-# LANGUAGE MultiParamTypeClasses #-}
23+{-# LANGUAGE TypeFamilies #-}
22{-# LANGUAGE CPP #-}
24{-# LANGUAGE CPP #-}
23
25
24module Language.PureScript.Make
26module Language.PureScript.Make
@@ -39,29 +41,31 @@ module Language.PureScript.Make
39#if __GLASGOW_HASKELL__ < 710
41#if __GLASGOW_HASKELL__ < 710
40import Control.Applicative
42import Control.Applicative
41#endif
43#endif
42−import Control.Arrow ((&&&))
43import Control.Monad
44import Control.Monad
44import Control.Monad.Error.Class (MonadError(..))
45import Control.Monad.Error.Class (MonadError(..))
45import Control.Monad.Trans.Except
46import Control.Monad.Trans.Except
46import Control.Monad.Reader
47import Control.Monad.Reader
47import Control.Monad.Writer.Strict
48import Control.Monad.Writer.Strict
48import Control.Monad.Supply
49import Control.Monad.Supply
50+import Control.Monad.Base (MonadBase(..))
51+import Control.Monad.Trans.Control (MonadBaseControl(..))
49
52
50−import Data.Function (on)
53+import Control.Concurrent.Lifted as C
51−import Data.Either (partitionEithers)
54+
52−import Data.List (sortBy, groupBy, foldl')
55+import Data.List (foldl', sort)
53−import Data.Maybe (fromMaybe)
56+import Data.Maybe (fromMaybe, catMaybes)
54import Data.Time.Clock
57import Data.Time.Clock
55import Data.String (fromString)
58import Data.String (fromString)
56import Data.Foldable (for_)
59import Data.Foldable (for_)
57#if __GLASGOW_HASKELL__ < 710
60#if __GLASGOW_HASKELL__ < 710
58import Data.Traversable (traverse)
61import Data.Traversable (traverse)
59#endif
62#endif
63+import Data.Traversable (for)
60import Data.Version (showVersion)
64import Data.Version (showVersion)
61import Data.Aeson (encode, decode)
65import Data.Aeson (encode, decode)
62import qualified Data.ByteString.Lazy as B
66import qualified Data.ByteString.Lazy as B
63−import qualified Data.Map as M
64import qualified Data.Set as S
67import qualified Data.Set as S
68+import qualified Data.Map as M
65
69
66import System.Directory
70import System.Directory
67 (doesFileExist, getModificationTime, createDirectoryIfMissing)
71 (doesFileExist, getModificationTime, createDirectoryIfMissing)
@@ -150,65 +154,116 @@ data RebuildPolicy
150-- If timestamps have not changed, the externs file can be used to provide the module's types without
154-- If timestamps have not changed, the externs file can be used to provide the module's types without
151-- having to typecheck the module again.
155-- having to typecheck the module again.
152--
156--
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)
154 => MakeActions m
158 => MakeActions m
155 -> [Module]
159 -> [Module]
156 -> m Environment
160 -> m Environment
157make MakeActions{..} ms = do
161make MakeActions{..} ms = do
162+ checkModuleNamesAreUnique
163+
158− (sorted, graph) <- sortModules $ map importPrim ms
164+ (sorted, graph) <- sortModules ms
159− toRebuild <- foldM (\s (Module _ _ moduleName' _ _) -> do
165+
160− inputTimestamp <- getInputTimestamp moduleName'
166+ barriers <- zip (map getModuleName sorted) <$> replicateM (length ms) ((,) <$> C.newEmptyMVar <*> C.newEmptyMVar)
161− outputTimestamp <- getOutputTimestamp moduleName'
167+
162− return $ case (inputTimestamp, outputTimestamp) of
168+ for_ sorted $ \m -> fork $ do
163− (Right (Just t1), Just t2) | t1 < t2 -> s
169+ let deps = fromMaybe (error "make: module not found in dependency graph.") (lookup (getModuleName m) graph)
164− (Left RebuildNever, Just _) -> s
170+ buildModule barriers (importPrim m) (deps `inOrderOf` map getModuleName sorted)
165− _ -> S.insert moduleName' s) S.empty sorted
171+
166−
172+ -- Wait for all threads to complete, and collect errors.
167− (externs, toBuild) <- partitionEithers <$> rebuildIfNecessary (reverseDependencies graph) toRebuild sorted
173+ errors <- catMaybes <$> for barriers (takeMVar . snd . snd)
168− for_ toBuild lint
174+
169− (desugared, nextVar) <- runSupplyT 0 $ desugar externs toBuild
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)
170− let env = foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
181+ return $ foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
171− evalSupplyT nextVar $ go env desugared
172− where
173
182
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 ]
209 where
183 where
210− combine :: (Ord a) => [(a, b)] -> M.Map a [b]
184+ checkModuleNamesAreUnique :: m ()
211− combine = M.fromList . map ((fst . head) &&& map snd) . groupBy ((==) `on` fst) . sortBy (compare `on` fst)
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
212
267
213-- |
268-- |
214-- Add an import declaration for a module if it does not already explicitly import it.
269-- 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])
231newtype Make a = Make { unMake :: ReaderT Options (WriterT MultipleErrors (ExceptT MultipleErrors IO)) a }
286newtype Make a = Make { unMake :: ReaderT Options (WriterT MultipleErrors (ExceptT MultipleErrors IO)) a }
232 deriving (Functor, Applicative, Monad, MonadIO, MonadError MultipleErrors, MonadWriter MultipleErrors, MonadReader Options)
287 deriving (Functor, Applicative, Monad, MonadIO, MonadError MultipleErrors, MonadWriter MultipleErrors, MonadReader Options)
233
288
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+
234-- |
297-- |
235-- Execute a 'Make' monad, returning either errors, or the result of the compile plus any warnings.
298-- Execute a 'Make' monad, returning either errors, or the result of the compile plus any warnings.
236--
299--
@@ -305,15 +368,15 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
305 requiresForeign = not . null . CF.moduleForeign
368 requiresForeign = not . null . CF.moduleForeign
306
369
307 getTimestamp :: FilePath -> Make (Maybe UTCTime)
370 getTimestamp :: FilePath -> Make (Maybe UTCTime)
308− getTimestamp path = makeIO (const (SimpleErrorWrapper $ CannotGetFileInfo path)) $ do
371+ getTimestamp path = makeIO (const (ErrorMessage [] $ CannotGetFileInfo path)) $ do
309 exists <- doesFileExist path
372 exists <- doesFileExist path
310 traverse (const $ getModificationTime path) $ guard exists
373 traverse (const $ getModificationTime path) $ guard exists
311
374
312 readTextFile :: FilePath -> Make B.ByteString
375 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
314
377
315 writeTextFile :: FilePath -> B.ByteString -> Make ()
378 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
317 mkdirp path
380 mkdirp path
318 B.writeFile path text
381 B.writeFile path text
319 where
382 where
src/Language/PureScript/ModuleDependencies.hs+9−7
@@ -23,20 +23,17 @@ import Control.Monad.Error.Class (MonadError(..))
23
23
24import Data.Graph
24import Data.Graph
25import Data.List (nub)
25import Data.List (nub)
26−import Data.Maybe (mapMaybe)
26+import Data.Maybe (fromMaybe, mapMaybe)
27
27
28import Language.PureScript.AST
28import Language.PureScript.AST
29import Language.PureScript.Names
29import Language.PureScript.Names
30import Language.PureScript.Types
30import Language.PureScript.Types
31import Language.PureScript.Errors
31import Language.PureScript.Errors
32
32
33−-- |
34−-- A list of modules with their dependencies
33+-- | A list of modules with their transitive dependencies
35−--
36type ModuleGraph = [(ModuleName, [ModuleName])]
34type ModuleGraph = [(ModuleName, [ModuleName])]
37
35
38−-- |
39−-- Sort a collection of modules based on module dependencies.
36+-- | Sort a collection of modules based on module dependencies.
40--
37--
41-- Reports an error if the module graph contains a cycle.
38-- Reports an error if the module graph contains a cycle.
42--
39--
@@ -44,7 +41,12 @@ sortModules :: (MonadError MultipleErrors m) => [Module] -> m ([Module], ModuleG
44sortModules ms = do
41sortModules ms = do
45 let verts = map (\m@(Module _ _ _ ds _) -> (m, getModuleName m, nub (concatMap usedModules ds))) ms
42 let verts = map (\m@(Module _ _ _ ds _) -> (m, getModuleName m, nub (concatMap usedModules ds))) ms
46 ms' <- mapM toModule $ stronglyConnComp verts
43 ms' <- mapM toModule $ stronglyConnComp verts
44+ let (graph, fromVertex, toVertex) = graphFromEdges verts
47− let moduleGraph = map (\(_, mn, deps) -> (mn, deps)) 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))
48 return (ms', moduleGraph)
50 return (ms', moduleGraph)
49
51
50-- |
52-- |
src/Language/PureScript/Names.hs+4
@@ -104,6 +104,10 @@ qualify _ (Qualified (Just m) a) = (m, a)
104mkQualified :: a -> ModuleName -> Qualified a
104mkQualified :: a -> ModuleName -> Qualified a
105mkQualified name mn = Qualified (Just mn) name
105mkQualified name mn = Qualified (Just mn) name
106
106
107+-- | Remove the module name from a qualified name
108+disqualify :: Qualified a -> a
109+disqualify (Qualified _ a) = a
110+
107-- |
111-- |
108-- Checks whether a qualified value is actually qualified with a module reference
112-- Checks whether a qualified value is actually qualified with a module reference
109--
113--
src/Language/PureScript/Parser/Declarations.hs+18−18
@@ -176,9 +176,9 @@ parseImportDeclaration' = do
176
176
177parseDeclarationRef :: TokenParser DeclarationRef
177parseDeclarationRef :: TokenParser DeclarationRef
178parseDeclarationRef =
178parseDeclarationRef =
179− parseModuleRef <|> (
179+ parseModuleRef <|>
180− withSourceSpan PositionedDeclarationRef $
180+ withSourceSpan PositionedDeclarationRef
181− ValueRef <$> parseIdent
181+ (ValueRef <$> parseIdent
182 <|> do name <- properName
182 <|> do name <- properName
183 dctors <- P.optionMaybe $ parens (symbol' ".." *> pure Nothing <|> Just <$> commaSep properName)
183 dctors <- P.optionMaybe $ parens (symbol' ".." *> pure Nothing <|> Just <$> commaSep properName)
184 return $ maybe (TypeClassRef name) (TypeRef name) dctors
184 return $ maybe (TypeClassRef name) (TypeRef name) dctors
@@ -204,8 +204,8 @@ parseTypeClassDeclaration = do
204 mark (P.many (same *> positioned parseTypeDeclaration))
204 mark (P.many (same *> positioned parseTypeDeclaration))
205 return $ TypeClassDeclaration className idents implies members
205 return $ TypeClassDeclaration className idents implies members
206
206
207−parseTypeInstanceDeclaration :: TokenParser Declaration
207+parseInstanceDeclaration :: TokenParser (TypeInstanceBody -> Declaration)
208−parseTypeInstanceDeclaration = do
208+parseInstanceDeclaration = do
209 reserved "instance"
209 reserved "instance"
210 name <- parseIdent <* indented <* doubleColon
210 name <- parseIdent <* indented <* doubleColon
211 deps <- P.optionMaybe $ do
211 deps <- P.optionMaybe $ do
@@ -215,24 +215,21 @@ parseTypeInstanceDeclaration = do
215 return deps
215 return deps
216 className <- indented *> parseQualified properName
216 className <- indented *> parseQualified properName
217 ty <- P.many (indented *> noWildcards parseTypeAtom)
217 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
218 members <- P.option [] . P.try $ do
223 members <- P.option [] . P.try $ do
219 indented *> reserved "where"
224 indented *> reserved "where"
220 mark (P.many (same *> positioned parseValueDeclaration))
225 mark (P.many (same *> positioned parseValueDeclaration))
221− return $ TypeInstanceDeclaration name (fromMaybe [] deps) className ty (ExplicitInstance members)
226+ return $ instanceDecl (ExplicitInstance members)
222
227
223parseDerivingInstanceDeclaration :: TokenParser Declaration
228parseDerivingInstanceDeclaration :: TokenParser Declaration
224parseDerivingInstanceDeclaration = do
229parseDerivingInstanceDeclaration = do
225 reserved "derive"
230 reserved "derive"
226− reserved "instance"
231+ instanceDecl <- parseInstanceDeclaration
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
232+ return $ instanceDecl DerivedInstance
236
233
237positioned :: TokenParser Declaration -> TokenParser Declaration
234positioned :: TokenParser Declaration -> TokenParser Declaration
238positioned = withSourceSpan PositionedDeclaration
235positioned = withSourceSpan PositionedDeclaration
@@ -296,7 +293,7 @@ parseModulesFromFiles toFilePath input = do
296 collect vss = [ (k, v) | (k, vs) <- vss, v <- vs ]
293 collect vss = [ (k, v) | (k, vs) <- vss, v <- vs ]
297
294
298toPositionedError :: P.ParseError -> ErrorMessage
295toPositionedError :: 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)
300 where
297 where
301 name = (P.sourceName . P.errorPos) perr
298 name = (P.sourceName . P.errorPos) perr
302 start = (toSourcePos . P.errorPos) perr
299 start = (toSourcePos . P.errorPos) perr
@@ -526,10 +523,13 @@ parseIdentifierAndBinder = do
526-- Parse a binder
523-- Parse a binder
527--
524--
528parseBinder :: TokenParser Binder
525parseBinder :: TokenParser Binder
529−parseBinder = withSourceSpan PositionedBinder (P.buildExpressionParser operators parseBinderAtom)
526+parseBinder = withSourceSpan PositionedBinder (P.buildExpressionParser operators (buildPostfixParser postfixTable parseBinderAtom))
530 where
527 where
531 -- TODO: remove this deprecation warning in 0.8
528 -- TODO: remove this deprecation warning in 0.8
532 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 ] ]
529 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+ ]
533 parseBinderAtom :: TokenParser Binder
533 parseBinderAtom :: TokenParser Binder
534 parseBinderAtom = P.choice (map P.try
534 parseBinderAtom = P.choice (map P.try
535 [ parseNullBinder
535 [ parseNullBinder
src/Language/PureScript/Parser/Kinds.hs+1−1
@@ -46,4 +46,4 @@ parseKind :: TokenParser Kind
46parseKind = P.buildExpressionParser operators parseTypeAtom P.<?> "kind"
46parseKind = P.buildExpressionParser operators parseTypeAtom P.<?> "kind"
47 where
47 where
48 operators = [ [ P.Prefix (symbol' "#" >> return Row) ]
48 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"
479 go _ = Nothing
479 go _ = Nothing
480
480
481validModuleName :: String -> Bool
481validModuleName :: String -> Bool
482−validModuleName s = not ('_' `elem` s)
482+validModuleName s = '_' `notElem` s
483
483
484-- |
484-- |
485-- A list of purescript reserved identifiers
485-- A list of purescript reserved identifiers
src/Language/PureScript/Pretty/Common.hs+11
@@ -17,8 +17,11 @@ module Language.PureScript.Pretty.Common where
17
17
18import Control.Monad.State
18import Control.Monad.State
19import Data.List (intercalate)
19import Data.List (intercalate)
20+
20import Language.PureScript.Parser.Lexer (reservedPsNames, opChars)
21import Language.PureScript.Parser.Lexer (reservedPsNames, opChars)
21
22
23+import Text.PrettyPrint.Boxes
24+
22-- |
25-- |
23-- Wrap a string in parentheses
26-- Wrap a string in parentheses
24--
27--
@@ -67,3 +70,11 @@ prettyPrintObjectKey :: String -> String
67prettyPrintObjectKey s | s `elem` reservedPsNames = show s
70prettyPrintObjectKey s | s `elem` reservedPsNames = show s
68 | any (`elem` opChars) s = show s
71 | any (`elem` opChars) s = show s
69 | otherwise = s
72 | 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
45 match (JSStringLiteral s) = return $ string s
45 match (JSStringLiteral s) = return $ string s
46 match (JSBooleanLiteral True) = return "true"
46 match (JSBooleanLiteral True) = return "true"
47 match (JSBooleanLiteral False) = return "false"
47 match (JSBooleanLiteral False) = return "false"
48− match (JSArrayLiteral xs) = fmap concat $ sequence
48+ match (JSArrayLiteral xs) = concat <$> sequence
49 [ return "[ "
49 [ return "[ "
50− , fmap (intercalate ", ") $ forM xs prettyPrintJS'
50+ , intercalate ", " <$> forM xs prettyPrintJS'
51 , return " ]"
51 , return " ]"
52 ]
52 ]
53 match (JSObjectLiteral []) = return "{}"
53 match (JSObjectLiteral []) = return "{}"
54− match (JSObjectLiteral ps) = fmap concat $ sequence
54+ match (JSObjectLiteral ps) = concat <$> sequence
55 [ return "{\n"
55 [ return "{\n"
56 , withIndent $ do
56 , withIndent $ do
57 jss <- forM ps $ \(key, value) -> fmap ((objectPropertyToString key ++ ": ") ++) . prettyPrintJS' $ value
57 jss <- forM ps $ \(key, value) -> fmap ((objectPropertyToString key ++ ": ") ++) . prettyPrintJS' $ value
@@ -65,7 +65,7 @@ literals = mkPattern' match
65 objectPropertyToString :: String -> String
65 objectPropertyToString :: String -> String
66 objectPropertyToString s | identNeedsEscaping s = show s
66 objectPropertyToString s | identNeedsEscaping s = show s
67 | otherwise = s
67 | otherwise = s
68− match (JSBlock sts) = fmap concat $ sequence
68+ match (JSBlock sts) = concat <$> sequence
69 [ return "{\n"
69 [ return "{\n"
70 , withIndent $ prettyStatements sts
70 , withIndent $ prettyStatements sts
71 , return "\n"
71 , return "\n"
@@ -73,23 +73,23 @@ literals = mkPattern' match
73 , return "}"
73 , return "}"
74 ]
74 ]
75 match (JSVar ident) = return ident
75 match (JSVar ident) = return ident
76− match (JSVariableIntroduction ident value) = fmap concat $ sequence
76+ match (JSVariableIntroduction ident value) = concat <$> sequence
77 [ return "var "
77 [ return "var "
78 , return ident
78 , return ident
79 , maybe (return "") (fmap (" = " ++) . prettyPrintJS') value
79 , maybe (return "") (fmap (" = " ++) . prettyPrintJS') value
80 ]
80 ]
81− match (JSAssignment target value) = fmap concat $ sequence
81+ match (JSAssignment target value) = concat <$> sequence
82 [ prettyPrintJS' target
82 [ prettyPrintJS' target
83 , return " = "
83 , return " = "
84 , prettyPrintJS' value
84 , prettyPrintJS' value
85 ]
85 ]
86− match (JSWhile cond sts) = fmap concat $ sequence
86+ match (JSWhile cond sts) = concat <$> sequence
87 [ return "while ("
87 [ return "while ("
88 , prettyPrintJS' cond
88 , prettyPrintJS' cond
89 , return ") "
89 , return ") "
90 , prettyPrintJS' sts
90 , prettyPrintJS' sts
91 ]
91 ]
92− match (JSFor ident start end sts) = fmap concat $ sequence
92+ match (JSFor ident start end sts) = concat <$> sequence
93 [ return $ "for (var " ++ ident ++ " = "
93 [ return $ "for (var " ++ ident ++ " = "
94 , prettyPrintJS' start
94 , prettyPrintJS' start
95 , return $ "; " ++ ident ++ " < "
95 , return $ "; " ++ ident ++ " < "
@@ -97,30 +97,30 @@ literals = mkPattern' match
97 , return $ "; " ++ ident ++ "++) "
97 , return $ "; " ++ ident ++ "++) "
98 , prettyPrintJS' sts
98 , prettyPrintJS' sts
99 ]
99 ]
100− match (JSForIn ident obj sts) = fmap concat $ sequence
100+ match (JSForIn ident obj sts) = concat <$> sequence
101 [ return $ "for (var " ++ ident ++ " in "
101 [ return $ "for (var " ++ ident ++ " in "
102 , prettyPrintJS' obj
102 , prettyPrintJS' obj
103 , return ") "
103 , return ") "
104 , prettyPrintJS' sts
104 , prettyPrintJS' sts
105 ]
105 ]
106− match (JSIfElse cond thens elses) = fmap concat $ sequence
106+ match (JSIfElse cond thens elses) = concat <$> sequence
107 [ return "if ("
107 [ return "if ("
108 , prettyPrintJS' cond
108 , prettyPrintJS' cond
109 , return ") "
109 , return ") "
110 , prettyPrintJS' thens
110 , prettyPrintJS' thens
111 , maybe (return "") (fmap (" else " ++) . prettyPrintJS') elses
111 , maybe (return "") (fmap (" else " ++) . prettyPrintJS') elses
112 ]
112 ]
113− match (JSReturn value) = fmap concat $ sequence
113+ match (JSReturn value) = concat <$> sequence
114 [ return "return "
114 [ return "return "
115 , prettyPrintJS' value
115 , prettyPrintJS' value
116 ]
116 ]
117− match (JSThrow value) = fmap concat $ sequence
117+ match (JSThrow value) = concat <$> sequence
118 [ return "throw "
118 [ return "throw "
119 , prettyPrintJS' value
119 , prettyPrintJS' value
120 ]
120 ]
121 match (JSBreak lbl) = return $ "break " ++ lbl
121 match (JSBreak lbl) = return $ "break " ++ lbl
122 match (JSContinue lbl) = return $ "continue " ++ lbl
122 match (JSContinue lbl) = return $ "continue " ++ lbl
123− match (JSLabel lbl js) = fmap concat $ sequence
123+ match (JSLabel lbl js) = concat <$> sequence
124 [ return $ lbl ++ ": "
124 [ return $ lbl ++ ": "
125 , prettyPrintJS' js
125 , prettyPrintJS' js
126 ]
126 ]
src/Language/PureScript/Pretty/Kinds.hs+2−3
@@ -45,14 +45,13 @@ funKind = mkPattern match
45 match (FunKind arg ret) = Just (arg, ret)
45 match (FunKind arg ret) = Just (arg, ret)
46 match _ = Nothing
46 match _ = Nothing
47
47
48−-- |
49−-- Generate a pretty-printed string representing a Kind
48+-- | Generate a pretty-printed string representing a Kind
50−--
51prettyPrintKind :: Kind -> String
49prettyPrintKind :: Kind -> String
52prettyPrintKind = fromMaybe (error "Incomplete pattern") . pattern matchKind ()
50prettyPrintKind = fromMaybe (error "Incomplete pattern") . pattern matchKind ()
53 where
51 where
54 matchKind :: Pattern () Kind String
52 matchKind :: Pattern () Kind String
55 matchKind = buildPrettyPrinter operators (typeLiterals <+> fmap parens matchKind)
53 matchKind = buildPrettyPrinter operators (typeLiterals <+> fmap parens matchKind)
54+
56 operators :: OperatorTable () Kind String
55 operators :: OperatorTable () Kind String
57 operators =
56 operators =
58 OperatorTable [ [ Wrap matchRow $ \_ k -> "# " ++ k]
57 OperatorTable [ [ Wrap matchRow $ \_ k -> "# " ++ k]
src/Language/PureScript/Pretty/Types.hs+58−35
@@ -14,13 +14,15 @@
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16module Language.PureScript.Pretty.Types (
16module Language.PureScript.Pretty.Types (
17+ typeAsBox,
17 prettyPrintType,
18 prettyPrintType,
19+ typeAtomAsBox,
18 prettyPrintTypeAtom,
20 prettyPrintTypeAtom,
21+ prettyPrintRowWith,
19 prettyPrintRow
22 prettyPrintRow
20) where
23) where
21
24
22import Data.Maybe (fromMaybe)
25import Data.Maybe (fromMaybe)
23−import Data.List (intercalate)
24
26
25import Control.Arrow ((<+>))
27import Control.Arrow ((<+>))
26import Control.PatternArrows
28import Control.PatternArrows
@@ -32,36 +34,56 @@ import Language.PureScript.Pretty.Common
32import Language.PureScript.Pretty.Kinds
34import Language.PureScript.Pretty.Kinds
33import Language.PureScript.Environment
35import Language.PureScript.Environment
34
36
37+import Text.PrettyPrint.Boxes hiding ((<+>))
38+
35−typeLiterals :: Pattern () Type String
39+typeLiterals :: Pattern () Type Box
36typeLiterals = mkPattern match
40typeLiterals = mkPattern match
37 where
41 where
38− match TypeWildcard = Just "_"
42+ match TypeWildcard = Just $ text "_"
39− match (TypeVar var) = Just var
43+ match (TypeVar var) = Just $ text var
40− match (PrettyPrintObject row) = Just $ "{ " ++ prettyPrintRow row ++ " }"
44+ match (PrettyPrintObject row) = Just $ prettyPrintRowWith '{' '}' row
41− match (TypeConstructor ctor) = Just $ showQualified runProperName ctor
45+ match (TypeConstructor ctor) = Just $ text $ runProperName $ disqualify ctor
42− match (TUnknown u) = Just $ '_' : show u
46+ match (TUnknown u) = Just $ text $ '_' : show u
43− match (Skolem name s _) = Just $ name ++ show s
47+ match (Skolem name s _) = Just $ text $ name ++ show s
44− match (ConstrainedType deps ty) = Just $ "(" ++ intercalate ", " (map (\(pn, ty') -> showQualified runProperName pn ++ " " ++ unwords (map prettyPrintTypeAtom ty')) deps) ++ ") => " ++ prettyPrintType ty
48+ match (ConstrainedType deps ty) = Just $ constraintsAsBox deps ty
45− match (SaturatedTypeSynonym name args) = Just $ showQualified runProperName name ++ "<" ++ intercalate "," (map prettyPrintTypeAtom args) ++ ">"
46− match REmpty = Just "()"
49+ match REmpty = Just $ text "()"
47− match row@RCons{} = Just $ '(' : prettyPrintRow row ++ ")"
50+ match row@RCons{} = Just $ prettyPrintRowWith '(' ')' row
48 match _ = Nothing
51 match _ = Nothing
49
52
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+
50-- |
60-- |
51-- Generate a pretty-printed string representing a Row
61-- Generate a pretty-printed string representing a Row
52--
62--
53−prettyPrintRow :: Type -> String
63+prettyPrintRowWith :: Char -> Char -> Type -> Box
54−prettyPrintRow = (\(tys, rest) -> intercalate ", " (map (uncurry nameAndTypeToPs) tys) ++ tailToPs rest) . toList []
64+prettyPrintRowWith open close = uncurry listToBox . toList []
55 where
65 where
56− nameAndTypeToPs :: String -> Type -> String
66+ nameAndTypeToPs :: Char -> String -> Type -> Box
57− nameAndTypeToPs name ty = prettyPrintObjectKey name ++ " :: " ++ prettyPrintType ty
67+ nameAndTypeToPs start name ty = text (start : ' ' : prettyPrintObjectKey name ++ " :: ") <> typeAsBox ty
68+
58− tailToPs :: Type -> String
69+ tailToPs :: Type -> Box
59− tailToPs REmpty = ""
70+ tailToPs REmpty = nullBox
60− tailToPs other = " | " ++ prettyPrintType other
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+
61 toList :: [(String, Type)] -> Type -> ([(String, Type)], Type)
80 toList :: [(String, Type)] -> Type -> ([(String, Type)], Type)
62 toList tys (RCons name ty row) = toList ((name, ty):tys) row
81 toList tys (RCons name ty row) = toList ((name, ty):tys) row
63 toList tys r = (tys, r)
82 toList tys r = (tys, r)
64
83
84+prettyPrintRow :: Type -> String
85+prettyPrintRow = render . prettyPrintRowWith '(' ')'
86+
65typeApp :: Pattern () Type (Type, Type)
87typeApp :: Pattern () Type (Type, Type)
66typeApp = mkPattern match
88typeApp = mkPattern match
67 where
89 where
@@ -92,19 +114,19 @@ insertPlaceholders = everywhereOnTypesTopDown convertForAlls . everywhereOnTypes
92 go idents other = PrettyPrintForAll idents other
114 go idents other = PrettyPrintForAll idents other
93 convertForAlls other = other
115 convertForAlls other = other
94
116
95−matchTypeAtom :: Pattern () Type String
117+matchTypeAtom :: Pattern () Type Box
96−matchTypeAtom = typeLiterals <+> fmap parens matchType
118+matchTypeAtom = typeLiterals <+> fmap ((`before` text ")") . (text "(" <>)) matchType
97
119
98−matchType :: Pattern () Type String
120+matchType :: Pattern () Type Box
99matchType = buildPrettyPrinter operators matchTypeAtom
121matchType = buildPrettyPrinter operators matchTypeAtom
100 where
122 where
101− operators :: OperatorTable () Type String
123+ operators :: OperatorTable () Type Box
102 operators =
124 operators =
103− OperatorTable [ [ AssocL typeApp $ \f x -> f ++ " " ++ x ]
125+ OperatorTable [ [ AssocL typeApp $ \f x -> f `beforeWithSpace` x ]
104− , [ AssocR appliedFunction $ \arg ret -> arg ++ " -> " ++ ret
126+ , [ AssocR appliedFunction $ \arg ret -> (arg <> text " ") `before` (text "-> " <> ret)
105 ]
127 ]
106− , [ Wrap forall_ $ \idents ty -> "forall " ++ unwords idents ++ ". " ++ ty ]
128+ , [ Wrap forall_ $ \idents ty -> text ("forall " ++ unwords idents ++ ". ") <> ty ]
107− , [ Wrap kinded $ \k ty -> ty ++ " :: " ++ prettyPrintKind k ]
129+ , [ Wrap kinded $ \k ty -> ty `before` (text (" :: " ++ prettyPrintKind k)) ]
108 ]
130 ]
109
131
110forall_ :: Pattern () Type ([String], Type)
132forall_ :: Pattern () Type ([String], Type)
@@ -113,15 +135,16 @@ forall_ = mkPattern match
113 match (PrettyPrintForAll idents ty) = Just (idents, ty)
135 match (PrettyPrintForAll idents ty) = Just (idents, ty)
114 match _ = Nothing
136 match _ = Nothing
115
137
116−-- |
138+typeAtomAsBox :: Type -> Box
139+typeAtomAsBox = fromMaybe (error "Incomplete pattern") . pattern matchTypeAtom () . insertPlaceholders
140+
117−-- Generate a pretty-printed string representing a Type, as it should appear inside parentheses
141+-- | Generate a pretty-printed string representing a Type, as it should appear inside parentheses
118−--
119prettyPrintTypeAtom :: Type -> String
142prettyPrintTypeAtom :: Type -> String
120−prettyPrintTypeAtom = fromMaybe (error "Incomplete pattern") . pattern matchTypeAtom () . insertPlaceholders
143+prettyPrintTypeAtom = render . typeAtomAsBox
121
144
145+typeAsBox :: Type -> Box
146+typeAsBox = fromMaybe (error "Incomplete pattern") . pattern matchType () . insertPlaceholders
122
147
123−-- |
124−-- Generate a pretty-printed string representing a Type
148+-- | Generate a pretty-printed string representing a Type
125−--
126prettyPrintType :: Type -> String
149prettyPrintType :: 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 (
21 prettyPrintBinderAtom
21 prettyPrintBinderAtom
22) where
22) where
23
23
24−import Data.Maybe (fromMaybe)
25import Data.List (intercalate)
24import Data.List (intercalate)
26
25
27−import Control.Arrow ((<+>), runKleisli, second)
26+import Control.Arrow (second)
28−import Control.PatternArrows
29−import Control.Monad.State
30−#if __GLASGOW_HASKELL__ < 710
31−import Control.Applicative
32−#endif
33
27
34import Language.PureScript.AST
28import Language.PureScript.AST
35import Language.PureScript.Names
29import Language.PureScript.Names
36import Language.PureScript.Pretty.Common
30import Language.PureScript.Pretty.Common
37−import Language.PureScript.Pretty.Types (prettyPrintType, prettyPrintTypeAtom)
31+import Language.PureScript.Pretty.Types (typeAsBox, typeAtomAsBox)
38
32
39−literals :: Pattern PrinterState Expr String
33+import Text.PrettyPrint.Boxes
40−literals = mkPattern' match
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 ] ])
41 where
39 where
42− match :: Expr -> StateT PrinterState Maybe String
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
43− match (NumericLiteral n) = return $ either show show n
79+prettyPrintValueAtom (NumericLiteral n) = text $ either show show n
44− match (StringLiteral s) = return $ show s
80+prettyPrintValueAtom (StringLiteral s) = text $ show s
45− match (CharLiteral c) = return $ show c
81+prettyPrintValueAtom (CharLiteral c) = text $ show c
46− match (BooleanLiteral True) = return "true"
82+prettyPrintValueAtom (BooleanLiteral True) = text "true"
47− match (BooleanLiteral False) = return "false"
83+prettyPrintValueAtom (BooleanLiteral False) = text "false"
48− match (ArrayLiteral xs) = return $ "[" ++ intercalate ", " (map prettyPrintValue xs) ++ "]"
84+prettyPrintValueAtom (ArrayLiteral xs) = list '[' ']' prettyPrintValue xs
49− match (ObjectLiteral ps) = prettyPrintObject' $ second Just `map` ps
85+prettyPrintValueAtom (ObjectLiteral ps) = prettyPrintObject $ second Just `map` ps
50− match (ObjectConstructor ps) = prettyPrintObject' ps
86+prettyPrintValueAtom (ObjectConstructor ps) = prettyPrintObject ps
51− match (ObjectGetter prop) = return $ "(." ++ prop ++ ")"
87+prettyPrintValueAtom (ObjectGetter prop) = text $ "_." ++ show 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
88+prettyPrintValueAtom (Constructor name) = text $ runProperName (disqualify name)
58− match (Case values binders) = concat <$> sequence
89+prettyPrintValueAtom (Var ident) = text $ showIdent (disqualify ident)
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 ++ ")"
90+prettyPrintValueAtom (OperatorSection op (Right val)) = ((text "(" <> prettyPrintValue op) `beforeWithSpace` prettyPrintValue val) `before` text ")"
80− match (OperatorSection op (Left val)) = return $ "(" ++ prettyPrintValue val ++ " " ++ prettyPrintValue op ++ ")"
91+prettyPrintValueAtom (OperatorSection op (Left val)) = ((text "(" <> prettyPrintValue val) `beforeWithSpace` prettyPrintValue op) `before` text ")"
81− match (TypeClassDictionary (name, tys) _) = return $ "<<dict " ++ showQualified runProperName name ++ " " ++ unwords (map prettyPrintTypeAtom tys) ++ ">>"
92+prettyPrintValueAtom (TypedValue _ val _) = prettyPrintValueAtom val
82− match (SuperClassDictionary name _) = return $ "<<superclass dict " ++ showQualified runProperName name ++ ">>"
83− match (TypedValue _ val _) = prettyPrintValue' val
84− match (PositionedValue _ _ val) = prettyPrintValue' val
93+prettyPrintValueAtom (PositionedValue _ _ val) = prettyPrintValueAtom val
85− match _ = mzero
94+prettyPrintValueAtom expr = (text "(" <> prettyPrintValue expr) `before` text ")"
86−
95+
87−prettyPrintDeclaration :: Declaration -> StateT PrinterState Maybe String
96+prettyPrintDeclaration :: Declaration -> Box
88−prettyPrintDeclaration (TypeDeclaration ident ty) = return $ showIdent ident ++ " :: " ++ prettyPrintType ty
97+prettyPrintDeclaration (TypeDeclaration ident ty) =
98+ text (showIdent ident ++ " :: ") <> typeAsBox ty
89−prettyPrintDeclaration (ValueDeclaration ident _ [] (Right val)) = concat <$> sequence
99+prettyPrintDeclaration (ValueDeclaration ident _ [] (Right val)) =
90− [ return $ showIdent ident ++ " = "
100+ text (showIdent ident ++ " = ") <> prettyPrintValue val
91− , prettyPrintValue' val
101+prettyPrintDeclaration (BindingGroupDeclaration ds) =
92− ]
102+ vsep 1 left (map (prettyPrintDeclaration . toDecl) ds)
103+ where
104+ toDecl (nm, t, e) = ValueDeclaration nm t [] (Right e)
93prettyPrintDeclaration (PositionedDeclaration _ _ d) = prettyPrintDeclaration d
105prettyPrintDeclaration (PositionedDeclaration _ _ d) = prettyPrintDeclaration d
94prettyPrintDeclaration _ = error "Invalid argument to prettyPrintDeclaration"
106prettyPrintDeclaration _ = error "Invalid argument to prettyPrintDeclaration"
95
107
96−prettyPrintCaseAlternative :: CaseAlternative -> StateT PrinterState Maybe String
108+prettyPrintCaseAlternative :: CaseAlternative -> Box
97prettyPrintCaseAlternative (CaseAlternative binders result) =
109prettyPrintCaseAlternative (CaseAlternative binders result) =
98− concat <$> sequence
99− [ return (unwords (map prettyPrintBinderAtom binders))
110+ text (unwords (map prettyPrintBinderAtom binders)) <> prettyPrintResult result
100− , prettyPrintResult result
101− ]
102 where
111 where
103− prettyPrintResult (Left gs) = concat <$> sequence
112+ prettyPrintResult :: Either [(Guard, Expr)] Expr -> Box
104− [ return "\n"
113+ prettyPrintResult (Left gs) =
105− , withIndent $ prettyPrintMany prettyPrintGuardedValue gs
114+ vcat left (map prettyPrintGuardedValue gs)
106− ]
107− prettyPrintResult (Right v) = (" -> " ++) <$> prettyPrintValue' v
115+ prettyPrintResult (Right v) = text " -> " <> prettyPrintValue v
108−
116+
109− prettyPrintGuardedValue (grd, val) =
117+ prettyPrintGuardedValue :: (Guard, Expr) -> Box
110− concat <$> sequence
118+ prettyPrintGuardedValue (grd, val) = foldl1 before
111− [ return "| "
119+ [ text " | "
112− , prettyPrintValue' grd
120+ , prettyPrintValue grd
113− , return " -> "
121+ , text " -> "
114− , prettyPrintValue' val
122+ , prettyPrintValue val
115− ]
123+ ]
116−
124+
117−prettyPrintDoNotationElement :: DoNotationElement -> StateT PrinterState Maybe String
125+prettyPrintDoNotationElement :: DoNotationElement -> Box
118prettyPrintDoNotationElement (DoNotationValue val) =
126prettyPrintDoNotationElement (DoNotationValue val) =
119− prettyPrintValue' val
127+ prettyPrintValue val
120prettyPrintDoNotationElement (DoNotationBind binder val) =
128prettyPrintDoNotationElement (DoNotationBind binder val) =
121− concat <$> sequence
122− [ return (prettyPrintBinder binder)
129+ text (prettyPrintBinder binder ++ " <- ") <> prettyPrintValue val
123− , return " <- "
124− , prettyPrintValue' val
125− ]
126prettyPrintDoNotationElement (DoNotationLet ds) =
130prettyPrintDoNotationElement (DoNotationLet ds) =
127− concat <$> sequence
131+ text "let" //
128− [ return "let "
129− , withIndent $ prettyPrintMany prettyPrintDeclaration ds
132+ moveRight 2 (vcat left (map prettyPrintDeclaration ds))
130− ]
131prettyPrintDoNotationElement (PositionedDoNotationElement _ _ el) = prettyPrintDoNotationElement el
133prettyPrintDoNotationElement (PositionedDoNotationElement _ _ el) = prettyPrintDoNotationElement el
132
134
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−
191prettyPrintBinderAtom :: Binder -> String
135prettyPrintBinderAtom :: Binder -> String
136+
192prettyPrintBinderAtom NullBinder = "_"
137prettyPrintBinderAtom NullBinder = "_"
193prettyPrintBinderAtom (StringBinder str) = show str
138prettyPrintBinderAtom (StringBinder str) = show str
194prettyPrintBinderAtom (CharBinder c) = show c
139prettyPrintBinderAtom (CharBinder c) = show c
@@ -196,7 +141,7 @@ prettyPrintBinderAtom (NumberBinder num) = either show show num
196prettyPrintBinderAtom (BooleanBinder True) = "true"
141prettyPrintBinderAtom (BooleanBinder True) = "true"
197prettyPrintBinderAtom (BooleanBinder False) = "false"
142prettyPrintBinderAtom (BooleanBinder False) = "false"
198prettyPrintBinderAtom (VarBinder ident) = showIdent ident
143prettyPrintBinderAtom (VarBinder ident) = showIdent ident
199−prettyPrintBinderAtom (ConstructorBinder ctor []) = showQualified runProperName ctor
144+prettyPrintBinderAtom (ConstructorBinder ctor []) = runProperName (disqualify ctor)
200prettyPrintBinderAtom (ObjectBinder bs) =
145prettyPrintBinderAtom (ObjectBinder bs) =
201 "{ "
146 "{ "
202 ++ intercalate ", " (map prettyPrintObjectPropertyBinder bs)
147 ++ intercalate ", " (map prettyPrintObjectPropertyBinder bs)
@@ -216,7 +161,8 @@ prettyPrintBinderAtom b = parens (prettyPrintBinder b)
216-- Generate a pretty-printed string representing a Binder
161-- Generate a pretty-printed string representing a Binder
217--
162--
218prettyPrintBinder :: Binder -> String
163prettyPrintBinder :: Binder -> String
219−prettyPrintBinder (ConstructorBinder ctor []) = showQualified runProperName ctor
164+prettyPrintBinder (ConstructorBinder ctor []) = runProperName (disqualify ctor)
220−prettyPrintBinder (ConstructorBinder ctor args) = showQualified runProperName ctor ++ " " ++ unwords (map prettyPrintBinderAtom args)
165+prettyPrintBinder (ConstructorBinder ctor args) = runProperName (disqualify ctor) ++ " " ++ unwords (map prettyPrintBinderAtom args)
221prettyPrintBinder (PositionedBinder _ _ binder) = prettyPrintBinder binder
166prettyPrintBinder (PositionedBinder _ _ binder) = prettyPrintBinder binder
167+prettyPrintBinder (TypedBinder _ binder) = prettyPrintBinder binder
222prettyPrintBinder b = prettyPrintBinderAtom b
168prettyPrintBinder b = prettyPrintBinderAtom b
src/Language/PureScript/Publish.hs+1−1
@@ -153,7 +153,7 @@ getGitWorkingTreeStatus :: PrepareM TreeStatus
153getGitWorkingTreeStatus = do
153getGitWorkingTreeStatus = do
154 out <- readProcess' "git" ["status", "--porcelain"] ""
154 out <- readProcess' "git" ["status", "--porcelain"] ""
155 return $
155 return $
156− if null . filter (not . null) . lines $ out
156+ if all null . lines $ out
157 then Clean
157 then Clean
158 else Dirty
158 else Dirty
159
159
src/Language/PureScript/Publish/ErrorsWarnings.hs+14−15
@@ -98,10 +98,10 @@ renderError err =
98 case err of
98 case err of
99 UserError e ->
99 UserError e ->
100 vcat
100 vcat
101− [ para (concat
101+ [ para (
102− [ "There is a problem with your package, which meant that "
102+ "There is a problem with your package, which meant that " ++
103− , "it could not be published."
103+ "it could not be published."
104− ])
104+ )
105 , para "Details:"
105 , para "Details:"
106 , indented (displayUserError e)
106 , indented (displayUserError e)
107 ]
107 ]
@@ -123,10 +123,10 @@ renderError err =
123displayUserError :: UserError -> Box
123displayUserError :: UserError -> Box
124displayUserError e = case e of
124displayUserError e = case e of
125 BowerJSONNotFound ->
125 BowerJSONNotFound ->
126− para (concat
126+ para (
127− [ "The bower.json file was not found. Please create one, or run "
127+ "The bower.json file was not found. Please create one, or run " ++
128− , "`pulp init`."
128+ "`pulp init`."
129− ])
129+ )
130 BowerExecutableNotFound names ->
130 BowerExecutableNotFound names ->
131 para (concat
131 para (concat
132 [ "The Bower executable was not found (tried: ", format names, "). Please"
132 [ "The Bower executable was not found (tried: ", format names, "). Please"
@@ -217,10 +217,10 @@ displayUserError e = case e of
217 , indented (P.prettyPrintMultipleErrorsBox False err)
217 , indented (P.prettyPrintMultipleErrorsBox False err)
218 ]
218 ]
219 DirtyWorkingTree ->
219 DirtyWorkingTree ->
220− para (concat
220+ para (
221− [ "Your git working tree is dirty. Please commit, discard, or stash "
221+ "Your git working tree is dirty. Please commit, discard, or stash " ++
222− , "your changes first."
222+ "your changes first."
223− ])
223+ )
224
224
225displayRepositoryError :: RepositoryFieldError -> Box
225displayRepositoryError :: RepositoryFieldError -> Box
226displayRepositoryError err = case err of
226displayRepositoryError err = case err of
@@ -356,12 +356,11 @@ warnUndeclaredDependencies pkgNames =
356 are = pl "are" "is"
356 are = pl "are" "is"
357 dependencies = pl "dependencies" "a dependency"
357 dependencies = pl "dependencies" "a dependency"
358 in vcat $
358 in vcat $
359− [ para (concat
359+ para (concat
360 [ "The following Bower ", packages, " ", are, " installed, but not "
360 [ "The following Bower ", packages, " ", are, " installed, but not "
361 , "declared as ", dependencies, " in your bower.json file:"
361 , "declared as ", dependencies, " in your bower.json file:"
362 ])
362 ])
363− ] ++
364− bulletedList runPackageName (NonEmpty.toList pkgNames)
363+ : bulletedList runPackageName (NonEmpty.toList pkgNames)
365
364
366warnUnacceptableVersions :: NonEmpty (PackageName, String) -> Box
365warnUnacceptableVersions :: NonEmpty (PackageName, String) -> Box
367warnUnacceptableVersions pkgs =
366warnUnacceptableVersions pkgs =
src/Language/PureScript/Renamer.hs+3−3
@@ -80,12 +80,12 @@ updateScope :: Ident -> Rename Ident
80updateScope i@(Ident name) | name == C.__unused = return i
80updateScope i@(Ident name) | name == C.__unused = return i
81updateScope name = do
81updateScope name = do
82 scope <- get
82 scope <- get
83− name' <- case name `S.member` rsUsedNames scope of
83+ name' <- if name `S.member` rsUsedNames scope
84− True -> do
84+ then do
85 let newNames = [ Ident (runIdent name ++ "_" ++ show (i :: Int)) | i <- [1..] ]
85 let newNames = [ Ident (runIdent name ++ "_" ++ show (i :: Int)) | i <- [1..] ]
86 Just newName = find (`S.notMember` rsUsedNames scope) newNames
86 Just newName = find (`S.notMember` rsUsedNames scope) newNames
87 return newName
87 return newName
88− False -> return name
88+ else return name
89 modify $ \s -> s { rsBoundNames = M.insert name name' (rsBoundNames s)
89 modify $ \s -> s { rsBoundNames = M.insert name name' (rsBoundNames s)
90 , rsUsedNames = S.insert name' (rsUsedNames s)
90 , rsUsedNames = S.insert name' (rsUsedNames s)
91 }
91 }
src/Language/PureScript/Sugar/BindingGroups.hs+1−1
@@ -184,7 +184,7 @@ toBindingGroup moduleName (CyclicSCC ds') =
184 cycleError :: (MonadError MultipleErrors m) => Declaration -> [Declaration] -> m a
184 cycleError :: (MonadError MultipleErrors m) => Declaration -> [Declaration] -> m a
185 cycleError (PositionedDeclaration p _ d) ds = rethrowWithPosition p $ cycleError d ds
185 cycleError (PositionedDeclaration p _ d) ds = rethrowWithPosition p $ cycleError d ds
186 cycleError (ValueDeclaration n _ _ (Right _)) [] = throwError . errorMessage $ CycleInDeclaration n
186 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 []
188 cycleError _ _ = error "Expected ValueDeclaration"
188 cycleError _ _ = error "Expected ValueDeclaration"
189
189
190toDataBindingGroup :: (MonadError MultipleErrors m) => SCC Declaration -> m Declaration
190toDataBindingGroup :: (MonadError MultipleErrors m) => SCC Declaration -> m Declaration
src/Language/PureScript/Sugar/CaseDeclarations.hs+3−1
@@ -50,7 +50,7 @@ isLeft (Right _) = False
50--
50--
51desugarCasesModule :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => [Module] -> m [Module]
51desugarCasesModule :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => [Module] -> m [Module]
52desugarCasesModule ms = forM ms $ \(Module ss coms name ds exps) ->
52desugarCasesModule ms = forM ms $ \(Module ss coms name ds exps) ->
53− rethrow (onErrorMessages (ErrorInModule name)) $
53+ rethrow (addHint (ErrorInModule name)) $
54 Module ss coms name <$> (desugarCases <=< desugarAbs $ ds) <*> pure exps
54 Module ss coms name <$> (desugarCases <=< desugarAbs $ ds) <*> pure exps
55
55
56desugarAbs :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => [Declaration] -> m [Declaration]
56desugarAbs :: (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 =
104 isVarBinder NullBinder = True
104 isVarBinder NullBinder = True
105 isVarBinder (VarBinder _) = True
105 isVarBinder (VarBinder _) = True
106 isVarBinder (PositionedBinder _ _ b) = isVarBinder b
106 isVarBinder (PositionedBinder _ _ b) = isVarBinder b
107+ isVarBinder (TypedBinder _ b) = isVarBinder b
107 isVarBinder _ = False
108 isVarBinder _ = False
108
109
109 fromVarBinder :: Binder -> m Ident
110 fromVarBinder :: Binder -> m Ident
110 fromVarBinder NullBinder = Ident <$> freshName
111 fromVarBinder NullBinder = Ident <$> freshName
111 fromVarBinder (VarBinder name) = return name
112 fromVarBinder (VarBinder name) = return name
112 fromVarBinder (PositionedBinder _ _ b) = fromVarBinder b
113 fromVarBinder (PositionedBinder _ _ b) = fromVarBinder b
114+ fromVarBinder (TypedBinder _ b) = fromVarBinder b
113 fromVarBinder _ = error "fromVarBinder: Invalid argument"
115 fromVarBinder _ = error "fromVarBinder: Invalid argument"
114toDecls ds@(ValueDeclaration ident _ bs result : _) = do
116toDecls ds@(ValueDeclaration ident _ bs result : _) = do
115 let tuples = map toTuple ds
117 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
42desugarDoModule (Module ss coms mn ds exts) = Module ss coms mn <$> parU ds desugarDo <*> pure exts
42desugarDoModule (Module ss coms mn ds exts) = Module ss coms mn <$> parU ds desugarDo <*> pure exts
43
43
44desugarDo :: forall m. (Applicative m, MonadSupply m, MonadError MultipleErrors m) => Declaration -> m Declaration
44desugarDo :: 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)
46desugarDo d =
46desugarDo d =
47 let (f, _, _) = everywhereOnValuesM return replace return
47 let (f, _, _) = everywhereOnValuesM return replace return
48 in f d
48 in f d
49 where
49 where
50 bind :: Expr
50 bind :: Expr
51− bind = Var (Qualified Nothing (Ident (C.bind)))
51+ bind = Var (Qualified Nothing (Ident C.bind))
52
52
53 replace :: Expr -> m Expr
53 replace :: Expr -> m Expr
54 replace (Do els) = go els
54 replace (Do els) = go els
src/Language/PureScript/Sugar/Names.hs+6−3
@@ -98,7 +98,7 @@ desugarImports externs modules = do
98
98
99 renameInModule' :: Env -> Module -> m Module
99 renameInModule' :: Env -> Module -> m Module
100 renameInModule' env m@(Module _ _ mn _ _) =
100 renameInModule' env m@(Module _ _ mn _ _) =
101− rethrow (onErrorMessages (ErrorInModule mn)) $ do
101+ rethrow (addHint (ErrorInModule mn)) $ do
102 let (_, imps, exps) = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn env
102 let (_, imps, exps) = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn env
103 elaborateImports imps <$> renameInModule env imps (elaborateExports exps m)
103 elaborateImports imps <$> renameInModule env imps (elaborateExports exps m)
104
104
@@ -132,7 +132,7 @@ elaborateImports imps (Module ss coms mn decls exps) = Module ss coms mn decls'
132 let (f, _, _, _, _) = everythingOnValues (++) (const []) fqValues (const []) (const []) (const [])
132 let (f, _, _, _, _) = everythingOnValues (++) (const []) fqValues (const []) (const []) (const [])
133 in mkImport `map` nub (f `concatMap` decls) ++ decls
133 in mkImport `map` nub (f `concatMap` decls) ++ decls
134 fqValues :: Expr -> [ModuleName]
134 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']
136 fqValues _ = []
136 fqValues _ = []
137 mkImport :: ModuleName -> Declaration
137 mkImport :: ModuleName -> Declaration
138 mkImport mn' = ImportDeclaration mn' (Explicit []) Nothing
138 mkImport mn' = ImportDeclaration mn' (Explicit []) Nothing
@@ -190,6 +190,10 @@ renameInModule env imports (Module ss coms mn decls exps) =
190 return ((Just pos, bound), v)
190 return ((Just pos, bound), v)
191 updateBinder s@(pos, _) (ConstructorBinder name b) =
191 updateBinder s@(pos, _) (ConstructorBinder name b) =
192 (,) s <$> (ConstructorBinder <$> updateDataConstructorName name pos <*> pure b)
192 (,) 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')
193 updateBinder s v =
197 updateBinder s v =
194 return (s, v)
198 return (s, v)
195
199
@@ -207,7 +211,6 @@ renameInModule env imports (Module ss coms mn decls exps) =
207 where
211 where
208 updateType :: Type -> m Type
212 updateType :: Type -> m Type
209 updateType (TypeConstructor name) = TypeConstructor <$> updateTypeName name pos
213 updateType (TypeConstructor name) = TypeConstructor <$> updateTypeName name pos
210− updateType (SaturatedTypeSynonym name tys) = SaturatedTypeSynonym <$> updateTypeName name pos <*> pure tys
211 updateType (ConstrainedType cs t) = ConstrainedType <$> updateConstraints pos cs <*> pure t
214 updateType (ConstrainedType cs t) = ConstrainedType <$> updateConstraints pos cs <*> pure t
212 updateType t = return t
215 updateType t = return t
213
216
src/Language/PureScript/Sugar/Names/Exports.hs+4−5
@@ -43,7 +43,7 @@ import Language.PureScript.Sugar.Names.Env
43--
43--
44findExportable :: forall m. (Applicative m, MonadError MultipleErrors m) => Module -> m Exports
44findExportable :: forall m. (Applicative m, MonadError MultipleErrors m) => Module -> m Exports
45findExportable (Module _ _ mn ds _) =
45findExportable (Module _ _ mn ds _) =
46− rethrow (onErrorMessages (ErrorInModule mn)) $ foldM updateExports nullExports ds
46+ rethrow (addHint (ErrorInModule mn)) $ foldM updateExports nullExports ds
47 where
47 where
48 updateExports :: Exports -> Declaration -> m Exports
48 updateExports :: Exports -> Declaration -> m Exports
49 updateExports exps (TypeClassDeclaration tcn _ _ ds') = do
49 updateExports exps (TypeClassDeclaration tcn _ _ ds') = do
@@ -67,7 +67,7 @@ findExportable (Module _ _ mn ds _) =
67--
67--
68resolveExports :: forall m. (Applicative m, MonadError MultipleErrors m) => Env -> ModuleName -> Imports -> Exports -> [DeclarationRef] -> m Exports
68resolveExports :: forall m. (Applicative m, MonadError MultipleErrors m) => Env -> ModuleName -> Imports -> Exports -> [DeclarationRef] -> m Exports
69resolveExports env mn imps exps refs =
69resolveExports env mn imps exps refs =
70− rethrow (onErrorMessages (ErrorInModule mn)) $ do
70+ rethrow (addHint (ErrorInModule mn)) $ do
71 filtered <- filterModule mn exps refs
71 filtered <- filterModule mn exps refs
72 foldM elaborateModuleExports filtered refs
72 foldM elaborateModuleExports filtered refs
73
73
@@ -205,9 +205,8 @@ filterModule mn exps refs = do
205 -- the data constructor to check.
205 -- the data constructor to check.
206 checkDcon :: ProperName -> [ProperName] -> ProperName -> m ()
206 checkDcon :: ProperName -> [ProperName] -> ProperName -> m ()
207 checkDcon tcon exps' name =
207 checkDcon tcon exps' name =
208− if name `elem` exps'
208+ unless (name `elem` exps') $
209− then return ()
210− else throwError . errorMessage $ UnknownExportDataConstructor tcon name
209+ throwError . errorMessage $ UnknownExportDataConstructor tcon name
211
210
212 -- Takes a list of all the exportable classes, the accumulated list of
211 -- Takes a list of all the exportable classes, the accumulated list of
213 -- filtered exports, and a `DeclarationRef` for an explicit export. When the
212 -- 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
64--
64--
65resolveImports :: (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => Env -> Module -> m Imports
65resolveImports :: (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => Env -> Module -> m Imports
66resolveImports env (Module _ _ currentModule decls _) =
66resolveImports env (Module _ _ currentModule decls _) =
67− censor (onErrorMessages (ErrorInModule currentModule)) $ do
67+ censor (addHint (ErrorInModule currentModule)) $ do
68 scope <- M.insert currentModule [(Nothing, Implicit, Nothing)] <$> findImports decls
68 scope <- M.insert currentModule [(Nothing, Implicit, Nothing)] <$> findImports decls
69 foldM (resolveModuleImport currentModule env) nullImports (M.toList scope)
69 foldM (resolveModuleImport currentModule env) nullImports (M.toList scope)
70
70
src/Language/PureScript/Sugar/Operators.hs+1−1
@@ -102,7 +102,7 @@ ensureNoDuplicates m = go $ sortBy (compare `on` fst) m
102 go [] = return ()
102 go [] = return ()
103 go [_] = return ()
103 go [_] = return ()
104 go ((x@(Qualified (Just mn) name), _) : (y, pos) : _) | x == y =
104 go ((x@(Qualified (Just mn) name), _) : (y, pos) : _) | x == y =
105− rethrow (onErrorMessages (ErrorInModule mn)) $
105+ rethrow (addHint (ErrorInModule mn)) $
106 rethrowWithPosition pos $
106 rethrowWithPosition pos $
107 throwError . errorMessage $ MultipleFixities name
107 throwError . errorMessage $ MultipleFixities name
108 go (_ : rest) = go rest
108 go (_ : rest) = go rest
src/Language/PureScript/Sugar/TypeClasses.hs+1−1
@@ -243,7 +243,7 @@ unit = TypeApp tyObject REmpty
243
243
244typeInstanceDictionaryDeclaration :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => Ident -> ModuleName -> [Constraint] -> Qualified ProperName -> [Type] -> [Declaration] -> Desugar m Declaration
244typeInstanceDictionaryDeclaration :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => Ident -> ModuleName -> [Constraint] -> Qualified ProperName -> [Type] -> [Declaration] -> Desugar m Declaration
245typeInstanceDictionaryDeclaration name mn deps className tys decls =
245typeInstanceDictionaryDeclaration name mn deps className tys decls =
246− rethrow (onErrorMessages (ErrorInInstance className tys)) $ do
246+ rethrow (addHint (ErrorInInstance className tys)) $ do
247 m <- get
247 m <- get
248
248
249 -- Lookup the type arguments and member types for the type class
249 -- Lookup the type arguments and member types for the type class
src/Language/PureScript/Sugar/TypeDeclarations.hs+37−33
@@ -15,18 +15,19 @@
15-----------------------------------------------------------------------------
15-----------------------------------------------------------------------------
16
16
17{-# LANGUAGE FlexibleContexts #-}
17{-# LANGUAGE FlexibleContexts #-}
18+{-# LANGUAGE ScopedTypeVariables #-}
18{-# LANGUAGE CPP #-}
19{-# LANGUAGE CPP #-}
19
20
20module Language.PureScript.Sugar.TypeDeclarations (
21module Language.PureScript.Sugar.TypeDeclarations (
21− desugarTypeDeclarations,
22 desugarTypeDeclarationsModule
22 desugarTypeDeclarationsModule
23) where
23) where
24
24
25#if __GLASGOW_HASKELL__ < 710
25#if __GLASGOW_HASKELL__ < 710
26import Control.Applicative
26import Control.Applicative
27#endif
27#endif
28−import Control.Monad (forM)
28+import Control.Monad (forM, when)
29import Control.Monad.Error.Class (MonadError(..))
29import Control.Monad.Error.Class (MonadError(..))
30+import Control.Monad.Writer.Class (MonadWriter(tell))
30
31
31import Language.PureScript.AST
32import Language.PureScript.AST
32import Language.PureScript.Names
33import Language.PureScript.Names
@@ -37,36 +38,39 @@ import Language.PureScript.Traversals
37-- |
38-- |
38-- Replace all top level type declarations in a module with type annotations
39-- Replace all top level type declarations in a module with type annotations
39--
40--
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]
41desugarTypeDeclarationsModule ms = forM ms $ \(Module ss coms name ds exps) ->
42desugarTypeDeclarationsModule ms = forM ms $ \(Module ss coms name ds exps) ->
42− rethrow (onErrorMessages (ErrorInModule name)) $
43+ rethrow (addHint (ErrorInModule name)) $
43− Module ss coms name <$> desugarTypeDeclarations ds <*> pure exps
44+ Module ss coms name <$> desugarTypeDeclarations True 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)
55 where
45 where
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
56− fromValueDeclaration :: (Functor m, Applicative m, MonadError MultipleErrors m) => Declaration -> m (Ident, NameKind, Expr)
55+ fromValueDeclaration :: Declaration -> m (Ident, NameKind, Expr)
57− fromValueDeclaration (ValueDeclaration name' nameKind [] (Right val)) | name == name' = return (name', nameKind, val)
56+ fromValueDeclaration (ValueDeclaration name' nameKind [] (Right val)) | name == name' = return (name', nameKind, val)
58− fromValueDeclaration (PositionedDeclaration pos com d') = do
57+ fromValueDeclaration (PositionedDeclaration pos com d') = do
59− (ident, nameKind, val) <- rethrowWithPosition pos $ fromValueDeclaration d'
58+ (ident, nameKind, val) <- rethrowWithPosition pos $ fromValueDeclaration d'
60− return (ident, nameKind, PositionedValue pos com val)
59+ return (ident, nameKind, PositionedValue pos com val)
61− fromValueDeclaration _ = throwError . errorMessage $ OrphanTypeDeclaration name
60+ fromValueDeclaration _ = throwError . errorMessage $ OrphanTypeDeclaration name
62−desugarTypeDeclarations (TypeDeclaration name _ : []) = throwError . errorMessage $ OrphanTypeDeclaration name
61+ desugarTypeDeclarations _ [TypeDeclaration name _] = throwError . errorMessage $ OrphanTypeDeclaration name
63−desugarTypeDeclarations (ValueDeclaration name nameKind bs val : rest) = do
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)
64− let (_, f, _) = everywhereOnValuesTopDownM return go return
68+ let (_, f, _) = everywhereOnValuesTopDownM return go return
65− f' (Left gs) = Left <$> mapM (pairM return f) gs
69+ f' (Left gs) = Left <$> mapM (pairM return f) gs
66− f' (Right v) = Right <$> f v
70+ f' (Right v) = Right <$> f v
67− (:) <$> (ValueDeclaration name nameKind bs <$> f' val) <*> desugarTypeDeclarations rest
71+ (:) <$> (ValueDeclaration name nameKind bs <$> f' val) <*> desugarTypeDeclarations reqd rest
68− where
72+ where
69− go (Let ds val') = Let <$> desugarTypeDeclarations ds <*> pure val'
73+ go (Let ds val') = Let <$> desugarTypeDeclarations False ds <*> pure val'
70− go other = return other
74+ go other = return other
71−desugarTypeDeclarations (d:ds) = (:) d <$> desugarTypeDeclarations ds
75+ desugarTypeDeclarations reqd (d:ds) = (:) d <$> desugarTypeDeclarations reqd ds
72−desugarTypeDeclarations [] = return []
76+ desugarTypeDeclarations _ [] = return []
src/Language/PureScript/TypeChecker.hs+78−50
@@ -27,7 +27,7 @@ import Language.PureScript.TypeChecker.Types as T
27import Language.PureScript.TypeChecker.Synonyms as T
27import Language.PureScript.TypeChecker.Synonyms as T
28
28
29import Data.Maybe
29import Data.Maybe
30−import Data.List (nub, (\\))
30+import Data.List (nub, (\\), sort, group)
31import Data.Foldable (for_)
31import Data.Foldable (for_)
32
32
33import qualified Data.Map as M
33import qualified Data.Map as M
@@ -51,7 +51,7 @@ addDataType moduleName dtype name args dctors ctorKind = do
51 env <- getEnv
51 env <- getEnv
52 putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (ctorKind, DataType args dctors) (types env) }
52 putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (ctorKind, DataType args dctors) (types env) }
53 forM_ dctors $ \(dctor, tys) ->
53 forM_ dctors $ \(dctor, tys) ->
54− warnAndRethrow (onErrorMessages (ErrorInDataConstructor dctor)) $
54+ warnAndRethrow (addHint (ErrorInDataConstructor dctor)) $
55 addDataConstructor moduleName dtype name (map fst args) dctor tys
55 addDataConstructor moduleName dtype name (map fst args) dctor tys
56
56
57addDataConstructor :: ModuleName -> DataDeclType -> ProperName -> [String] -> ProperName -> [Type] -> Check ()
57addDataConstructor :: ModuleName -> DataDeclType -> ProperName -> [String] -> ProperName -> [Type] -> Check ()
@@ -132,12 +132,12 @@ checkTypeSynonyms = void . replaceAllTypeSynonyms
132--
132--
133-- * Process module imports
133-- * Process module imports
134--
134--
135−typeCheckAll :: Maybe ModuleName -> ModuleName -> [DeclarationRef] -> [Declaration] -> Check [Declaration]
135+typeCheckAll :: ModuleName -> [DeclarationRef] -> [Declaration] -> Check [Declaration]
136−typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFixities ds
136+typeCheckAll moduleName _ ds = mapM go ds <* mapM_ checkOrphanFixities ds
137 where
137 where
138 go :: Declaration -> Check Declaration
138 go :: Declaration -> Check Declaration
139 go (DataDeclaration dtype name args dctors) = do
139 go (DataDeclaration dtype name args dctors) = do
140− warnAndRethrow (onErrorMessages (ErrorInTypeConstructor name)) $ do
140+ warnAndRethrow (addHint (ErrorInTypeConstructor name)) $ do
141 when (dtype == Newtype) $ checkNewtype dctors
141 when (dtype == Newtype) $ checkNewtype dctors
142 checkDuplicateTypeArguments $ map fst args
142 checkDuplicateTypeArguments $ map fst args
143 ctorKind <- kindsOf True moduleName name args (concatMap snd dctors)
143 ctorKind <- kindsOf True moduleName name args (concatMap snd dctors)
@@ -150,7 +150,7 @@ typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFix
150 checkNewtype [(_, _)] = throwError . errorMessage $ InvalidNewtype
150 checkNewtype [(_, _)] = throwError . errorMessage $ InvalidNewtype
151 checkNewtype _ = throwError . errorMessage $ InvalidNewtype
151 checkNewtype _ = throwError . errorMessage $ InvalidNewtype
152 go (d@(DataBindingGroupDeclaration tys)) = do
152 go (d@(DataBindingGroupDeclaration tys)) = do
153− warnAndRethrow (onErrorMessages ErrorInDataBindingGroup) $ do
153+ warnAndRethrow (addHint ErrorInDataBindingGroup) $ do
154 let syns = mapMaybe toTypeSynonym tys
154 let syns = mapMaybe toTypeSynonym tys
155 let dataDecls = mapMaybe toDataDecl tys
155 let dataDecls = mapMaybe toDataDecl tys
156 (syn_ks, data_ks) <- kindsOfAll moduleName syns (map (\(_, name, args, dctors) -> (name, args, concatMap snd dctors)) dataDecls)
156 (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
171 toDataDecl (PositionedDeclaration _ _ d') = toDataDecl d'
171 toDataDecl (PositionedDeclaration _ _ d') = toDataDecl d'
172 toDataDecl _ = Nothing
172 toDataDecl _ = Nothing
173 go (TypeSynonymDeclaration name args ty) = do
173 go (TypeSynonymDeclaration name args ty) = do
174− warnAndRethrow (onErrorMessages (ErrorInTypeSynonym name)) $ do
174+ warnAndRethrow (addHint (ErrorInTypeSynonym name)) $ do
175 checkDuplicateTypeArguments $ map fst args
175 checkDuplicateTypeArguments $ map fst args
176 kind <- kindsOf False moduleName name args [ty]
176 kind <- kindsOf False moduleName name args [ty]
177 let args' = args `withKinds` kind
177 let args' = args `withKinds` kind
@@ -179,17 +179,17 @@ typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFix
179 return $ TypeSynonymDeclaration name args ty
179 return $ TypeSynonymDeclaration name args ty
180 go (TypeDeclaration{}) = error "Type declarations should have been removed"
180 go (TypeDeclaration{}) = error "Type declarations should have been removed"
181 go (ValueDeclaration name nameKind [] (Right val)) =
181 go (ValueDeclaration name nameKind [] (Right val)) =
182− warnAndRethrow (onErrorMessages (ErrorInValueDeclaration name)) $ do
182+ warnAndRethrow (addHint (ErrorInValueDeclaration name)) $ do
183 valueIsNotDefined moduleName name
183 valueIsNotDefined moduleName name
184− [(_, (val', ty))] <- typesOf mainModuleName moduleName [(name, val)]
184+ [(_, (val', ty))] <- typesOf moduleName [(name, val)]
185 addValue moduleName name ty nameKind
185 addValue moduleName name ty nameKind
186 return $ ValueDeclaration name nameKind [] $ Right val'
186 return $ ValueDeclaration name nameKind [] $ Right val'
187 go (ValueDeclaration{}) = error "Binders were not desugared"
187 go (ValueDeclaration{}) = error "Binders were not desugared"
188 go (BindingGroupDeclaration vals) =
188 go (BindingGroupDeclaration vals) =
189− warnAndRethrow (onErrorMessages (ErrorInBindingGroup (map (\(ident, _, _) -> ident) vals))) $ do
189+ warnAndRethrow (addHint (ErrorInBindingGroup (map (\(ident, _, _) -> ident) vals))) $ do
190 forM_ (map (\(ident, _, _) -> ident) vals) $ \name ->
190 forM_ (map (\(ident, _, _) -> ident) vals) $ \name ->
191 valueIsNotDefined moduleName name
191 valueIsNotDefined moduleName name
192− tys <- typesOf mainModuleName moduleName $ map (\(ident, _, ty) -> (ident, ty)) vals
192+ tys <- typesOf moduleName $ map (\(ident, _, ty) -> (ident, ty)) vals
193 vals' <- forM [ (name, val, nameKind, ty)
193 vals' <- forM [ (name, val, nameKind, ty)
194 | (name, nameKind, _) <- vals
194 | (name, nameKind, _) <- vals
195 , (name', (val, ty)) <- tys
195 , (name', (val, ty)) <- tys
@@ -203,7 +203,7 @@ typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFix
203 putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (kind, ExternData) (types env) }
203 putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (kind, ExternData) (types env) }
204 return d
204 return d
205 go (d@(ExternDeclaration name ty)) = do
205 go (d@(ExternDeclaration name ty)) = do
206− warnAndRethrow (onErrorMessages (ErrorInForeignImport name)) $ do
206+ warnAndRethrow (addHint (ErrorInForeignImport name)) $ do
207 env <- getEnv
207 env <- getEnv
208 kind <- kindOf moduleName ty
208 kind <- kindOf moduleName ty
209 guardWith (errorMessage (ExpectedType ty kind)) $ kind == Star
209 guardWith (errorMessage (ExpectedType ty kind)) $ kind == Star
@@ -216,8 +216,14 @@ typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFix
216 go (d@(TypeClassDeclaration pn args implies tys)) = do
216 go (d@(TypeClassDeclaration pn args implies tys)) = do
217 addTypeClass moduleName pn args implies tys
217 addTypeClass moduleName pn args implies tys
218 return d
218 return d
219− go (d@(TypeInstanceDeclaration dictName deps className tys _)) =
219+ go (d@(TypeInstanceDeclaration dictName deps className tys body)) = rethrow (addHint (ErrorInInstance className tys)) $ do
220− goInstance d dictName deps className tys
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
221 go (PositionedDeclaration pos com d) =
227 go (PositionedDeclaration pos com d) =
222 warnAndRethrowWithPosition pos $ PositionedDeclaration pos com <$> go d
228 warnAndRethrowWithPosition pos $ PositionedDeclaration pos com <$> go d
223
229
@@ -229,29 +235,36 @@ typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFix
229 warnAndRethrowWithPosition pos $ checkOrphanFixities d
235 warnAndRethrowWithPosition pos $ checkOrphanFixities d
230 checkOrphanFixities _ = return ()
236 checkOrphanFixities _ = return ()
231
237
232− goInstance :: Declaration -> Ident -> [Constraint] -> Qualified ProperName -> [Type] -> Check Declaration
238+ checkInstanceMembers :: [Declaration] -> Check [Declaration]
233− goInstance d dictName deps className tys = do
239+ checkInstanceMembers instDecls = do
234− mapM_ (checkTypeClassInstance moduleName) tys
240+ let idents = sort . map head . group . map memberName $ instDecls
235− forM_ deps $ mapM_ (checkTypeClassInstance moduleName) . snd
241+ for_ (firstDuplicate idents) $ \ident ->
236− checkOrphanInstance moduleName className tys
242+ throwError . errorMessage $ DuplicateValueDeclaration ident
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
243+ return instDecls
240−
241 where
244 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"
242
249
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+
243− checkOrphanInstance :: ModuleName -> Qualified ProperName -> [Type] -> Check ()
256+ checkOrphanInstance :: Ident -> Qualified ProperName -> [Type] -> Check ()
244− checkOrphanInstance mn (Qualified (Just mn') _) tys'
257+ checkOrphanInstance dictName className@(Qualified (Just mn') _) tys'
245− | mn == mn' || any checkType tys' = return ()
258+ | moduleName == mn' || any checkType tys' = return ()
246− | otherwise = throwError . errorMessage $ OrphanInstance dictName className tys'
259+ | otherwise = throwError . errorMessage $ OrphanInstance dictName className tys'
247− where
260+ where
248− checkType :: Type -> Bool
261+ checkType :: Type -> Bool
249− checkType (TypeVar _) = False
262+ checkType (TypeVar _) = False
250− checkType (TypeConstructor (Qualified (Just mn'') _)) = mn == mn''
263+ checkType (TypeConstructor (Qualified (Just mn'') _)) = moduleName == mn''
251− checkType (TypeConstructor (Qualified Nothing _)) = error "Unqualified type name in checkOrphanInstance"
264+ checkType (TypeConstructor (Qualified Nothing _)) = error "Unqualified type name in checkOrphanInstance"
252− checkType (TypeApp t1 _) = checkType t1
265+ checkType (TypeApp t1 _) = checkType t1
253− checkType _ = error "Invalid type in instance in checkOrphanInstance"
266+ checkType _ = error "Invalid type in instance in checkOrphanInstance"
254− checkOrphanInstance _ _ _ = error "Unqualified class name in checkOrphanInstance"
267+ checkOrphanInstance _ _ _ = error "Unqualified class name in checkOrphanInstance"
255
268
256 -- |
269 -- |
257 -- This function adds the argument kinds for a type constructor so that they may appear in the externs file,
270 -- 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
267-- Type check an entire module and ensure all types and classes defined within the module that are
280-- Type check an entire module and ensure all types and classes defined within the module that are
268-- required by exported members are also exported.
281-- required by exported members are also exported.
269--
282--
270−typeCheckModule :: Maybe ModuleName -> Module -> Check Module
283+typeCheckModule :: Module -> Check Module
271−typeCheckModule _ (Module _ _ _ _ Nothing) = error "exports should have been elaborated"
284+typeCheckModule (Module _ _ _ _ Nothing) = error "exports should have been elaborated"
272−typeCheckModule mainModuleName (Module ss coms mn decls (Just exps)) = warnAndRethrow (onErrorMessages (ErrorInModule mn)) $ do
285+typeCheckModule (Module ss coms mn decls (Just exps)) = warnAndRethrow (addHint (ErrorInModule mn)) $ do
273 modify (\s -> s { checkCurrentModule = Just mn })
286 modify (\s -> s { checkCurrentModule = Just mn })
274− decls' <- typeCheckAll mainModuleName mn exps decls
287+ decls' <- typeCheckAll mn exps decls
275 forM_ exps $ \e -> do
288 forM_ exps $ \e -> do
276 checkTypesAreExported e
289 checkTypesAreExported e
277 checkClassMembersAreExported e
290 checkClassMembersAreExported e
@@ -280,21 +293,36 @@ typeCheckModule mainModuleName (Module ss coms mn decls (Just exps)) = warnAndRe
280 where
293 where
281
294
282 checkMemberExport :: (Type -> [DeclarationRef]) -> DeclarationRef -> Check ()
295 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 ()
283 checkMemberExport extract dr@(ValueRef name) = do
308 checkMemberExport extract dr@(ValueRef name) = do
284 ty <- lookupVariable mn (Qualified (Just mn) name)
309 ty <- lookupVariable mn (Qualified (Just mn) name)
285− case filter (not . exported) (extract ty) of
310+ checkExport dr extract ty
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
296 checkMemberExport _ _ = return ()
311 checkMemberExport _ _ = return ()
297
312
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+
298 -- Check that all the type constructors defined in the current module that appear in member types
326 -- Check that all the type constructors defined in the current module that appear in member types
299 -- have also been exported from the module
327 -- have also been exported from the module
300 checkTypesAreExported :: DeclarationRef -> Check ()
328 checkTypesAreExported :: DeclarationRef -> Check ()
src/Language/PureScript/TypeChecker/Entailment.hs+15−25
@@ -13,7 +13,6 @@
13--
13--
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
17{-# LANGUAGE CPP #-}
16{-# LANGUAGE CPP #-}
18
17
19module Language.PureScript.TypeChecker.Entailment (
18module Language.PureScript.TypeChecker.Entailment (
@@ -38,10 +37,8 @@ import Control.Monad.Writer.Class (tell)
38
37
39import Language.PureScript.AST
38import Language.PureScript.AST
40import Language.PureScript.Errors
39import Language.PureScript.Errors
41−import Language.PureScript.Environment
42import Language.PureScript.Names
40import Language.PureScript.Names
43import Language.PureScript.TypeChecker.Monad
41import Language.PureScript.TypeChecker.Monad
44−import Language.PureScript.TypeChecker.Synonyms
45import Language.PureScript.TypeChecker.Unify
42import Language.PureScript.TypeChecker.Unify
46import Language.PureScript.TypeClassDictionaries
43import Language.PureScript.TypeClassDictionaries
47import Language.PureScript.Types
44import Language.PureScript.Types
@@ -51,8 +48,8 @@ import qualified Language.PureScript.Constants as C
51-- Check that the current set of type class dictionaries entail the specified type class goal, and, if so,
48-- Check that the current set of type class dictionaries entail the specified type class goal, and, if so,
52-- return a type class dictionary reference.
49-- return a type class dictionary reference.
53--
50--
54−entails :: Environment -> ModuleName -> M.Map (Maybe ModuleName) (M.Map (Qualified ProperName) (M.Map (Qualified Ident) TypeClassDictionaryInScope)) -> Constraint -> Check Expr
51+entails :: ModuleName -> M.Map (Maybe ModuleName) (M.Map (Qualified ProperName) (M.Map (Qualified Ident) TypeClassDictionaryInScope)) -> Constraint -> Check Expr
55−entails env moduleName context = solve
52+entails moduleName context = solve
56 where
53 where
57 forClassName :: Qualified ProperName -> [Type] -> [TypeClassDictionaryInScope]
54 forClassName :: Qualified ProperName -> [Type] -> [TypeClassDictionaryInScope]
58 forClassName cn@(Qualified (Just mn) _) tys = concatMap (findDicts cn) (Nothing : Just mn : map Just (mapMaybe ctorModules tys))
55 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
75 go :: Int -> Qualified ProperName -> [Type] -> Check DictionaryValue
72 go :: Int -> Qualified ProperName -> [Type] -> Check DictionaryValue
76 go work className' tys' | work > 1000 = throwError . errorMessage $ PossiblyInfiniteInstance className' tys'
73 go work className' tys' | work > 1000 = throwError . errorMessage $ PossiblyInfiniteInstance className' tys'
77 go work className' tys' = do
74 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'
82 let instances = do
75 let instances = do
83− tcd <- forClassName className' tys''
76+ tcd <- forClassName className' tys'
84 -- Make sure the type unifies with the type in the type instance definition
77 -- 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)
86 return (subst, tcd)
79 return (subst, tcd)
87 (subst, tcd) <- unique instances
80 (subst, tcd) <- unique instances
88 -- Solve any necessary subgoals
81 -- Solve any necessary subgoals
@@ -140,7 +133,7 @@ entails env moduleName context = solve
140 verifySubstitution :: [(String, Type)] -> Maybe [(String, Type)]
133 verifySubstitution :: [(String, Type)] -> Maybe [(String, Type)]
141 verifySubstitution subst = do
134 verifySubstitution subst = do
142 let grps = groupBy ((==) `on` fst) . sortBy (compare `on` fst) $ subst
135 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)
144 return $ map head grps
137 return $ map head grps
145
138
146 valUndefined :: Expr
139 valUndefined :: Expr
@@ -150,24 +143,21 @@ entails env moduleName context = solve
150-- Check whether the type heads of two types are equal (for the purposes of type class dictionary lookup),
143-- Check whether the type heads of two types are equal (for the purposes of type class dictionary lookup),
151-- and return a substitution from type variables to types which makes the type heads unify.
144-- and return a substitution from type variables to types which makes the type heads unify.
152--
145--
153−typeHeadsAreEqual :: ModuleName -> Environment -> Type -> Type -> Maybe [(String, Type)]
146+typeHeadsAreEqual :: ModuleName -> Type -> Type -> Maybe [(String, Type)]
154−typeHeadsAreEqual _ _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []
147+typeHeadsAreEqual _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []
155−typeHeadsAreEqual _ _ t (TypeVar v) = Just [(v, t)]
148+typeHeadsAreEqual _ t (TypeVar v) = Just [(v, t)]
156−typeHeadsAreEqual _ _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []
149+typeHeadsAreEqual _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []
157−typeHeadsAreEqual m e (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m e h1 h2
150+typeHeadsAreEqual m (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m h1 h2
158− <*> typeHeadsAreEqual m e t1 t2
151+ <*> typeHeadsAreEqual m 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 []
152+typeHeadsAreEqual _ REmpty REmpty = Just []
163−typeHeadsAreEqual m e r1@(RCons _ _ _) r2@(RCons _ _ _) =
153+typeHeadsAreEqual m r1@RCons{} r2@RCons{} =
164 let (s1, r1') = rowToList r1
154 let (s1, r1') = rowToList r1
165 (s2, r2') = rowToList r2
155 (s2, r2') = rowToList r2
166
156
167 int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
157 int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
168 sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
158 sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
169 sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]
159 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
171 <*> go sd1 r1' sd2 r2'
161 <*> go sd1 r1' sd2 r2'
172 where
162 where
173 go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Maybe [(String, Type)]
163 go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Maybe [(String, Type)]
@@ -177,7 +167,7 @@ typeHeadsAreEqual m e r1@(RCons _ _ _) r2@(RCons _ _ _) =
177 go [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = Just []
167 go [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = Just []
178 go sd r [] (TypeVar v) = Just [(v, rowFromList (sd, r))]
168 go sd r [] (TypeVar v) = Just [(v, rowFromList (sd, r))]
179 go _ _ _ _ = Nothing
169 go _ _ _ _ = Nothing
180−typeHeadsAreEqual _ _ _ _ = Nothing
170+typeHeadsAreEqual _ _ _ = Nothing
181
171
182-- |
172-- |
183-- Check all values in a list pairwise match a predicate
173-- 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
83--
83--
84kindOfWithScopedVars :: Type -> Check (Kind, [(String, Kind)])
84kindOfWithScopedVars :: Type -> Check (Kind, [(String, Kind)])
85kindOfWithScopedVars ty =
85kindOfWithScopedVars ty =
86− rethrow (onErrorMessages (ErrorCheckingKind ty)) $
86+ rethrow (addHint (ErrorCheckingKind ty)) $
87 fmap tidyUp . liftUnify $ infer ty
87 fmap tidyUp . liftUnify $ infer ty
88 where
88 where
89 tidyUp ((k, args), sub) = ( starIfUnknown (sub $? k)
89 tidyUp ((k, args), sub) = ( starIfUnknown (sub $? k)
@@ -161,7 +161,7 @@ starIfUnknown k = k
161-- Infer a kind for a type
161-- Infer a kind for a type
162--
162--
163infer :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
163infer :: 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
165
165
166infer' :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
166infer' :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
167infer' (ForAll ident ty _) = do
167infer' (ForAll ident ty _) = do
@@ -215,8 +215,8 @@ infer' other = (, []) <$> go other
215 return $ Row k1
215 return $ Row k1
216 go (ConstrainedType deps ty) = do
216 go (ConstrainedType deps ty) = do
217 forM_ deps $ \(className, tys) -> do
217 forM_ deps $ \(className, tys) -> do
218− _ <- go $ foldl TypeApp (TypeConstructor className) tys
218+ k <- go $ foldl TypeApp (TypeConstructor className) tys
219− return ()
219+ k =?= Star
220 k <- go ty
220 k <- go ty
221 k =?= Star
221 k =?= Star
222 return Star
222 return Star
src/Language/PureScript/TypeChecker/Rows.hs−1
@@ -46,7 +46,6 @@ checkDuplicateLabels =
46 where
46 where
47 checkDups :: Type -> Check ()
47 checkDups :: Type -> Check ()
48 checkDups (TypeApp t1 t2) = checkDups t1 >> checkDups t2
48 checkDups (TypeApp t1 t2) = checkDups t1 >> checkDups t2
49− checkDups (SaturatedTypeSynonym _ ts) = mapM_ checkDups ts
50 checkDups (ForAll _ t _) = checkDups t
49 checkDups (ForAll _ t _) = checkDups t
51 checkDups (ConstrainedType args t) = do
50 checkDups (ConstrainedType args t) = do
52 mapM_ checkDups $ concatMap snd args
51 mapM_ checkDups $ concatMap snd args
src/Language/PureScript/TypeChecker/Skolems.hs+1−1
@@ -92,7 +92,7 @@ skolemEscapeCheck root@TypedValue{} =
92 let (_, f, _, _, _) = everythingWithContextOnValues [] [] (++) def go def def def
92 let (_, f, _, _, _) = everythingWithContextOnValues [] [] (++) def go def def def
93 in case f root of
93 in case f root of
94 [] -> return ()
94 [] -> return ()
95− ((binding, val) : _) -> throwError . singleError $ ErrorInExpression val $ SimpleErrorWrapper $ EscapedSkolem binding
95+ ((binding, val) : _) -> throwError . singleError $ ErrorMessage [ ErrorInExpression val ] $ EscapedSkolem binding
96 where
96 where
97 def s _ = (s, [])
97 def s _ = (s, [])
98
98
src/Language/PureScript/TypeChecker/Subsumption.hs+1−9
@@ -20,7 +20,6 @@ module Language.PureScript.TypeChecker.Subsumption (
20import Data.List (sortBy)
20import Data.List (sortBy)
21import Data.Ord (comparing)
21import Data.Ord (comparing)
22
22
23−import Control.Monad
24import Control.Monad.Error.Class (MonadError(..))
23import Control.Monad.Error.Class (MonadError(..))
25import Control.Monad.Unify
24import Control.Monad.Unify
26
25
@@ -29,7 +28,6 @@ import Language.PureScript.Environment
29import Language.PureScript.Errors
28import Language.PureScript.Errors
30import Language.PureScript.TypeChecker.Monad
29import Language.PureScript.TypeChecker.Monad
31import Language.PureScript.TypeChecker.Skolems
30import Language.PureScript.TypeChecker.Skolems
32−import Language.PureScript.TypeChecker.Synonyms
33import Language.PureScript.TypeChecker.Unify
31import Language.PureScript.TypeChecker.Unify
34import Language.PureScript.Types
32import Language.PureScript.Types
35
33
@@ -37,7 +35,7 @@ import Language.PureScript.Types
37-- Check whether one type subsumes another, rethrowing errors to provide a better error message
35-- Check whether one type subsumes another, rethrowing errors to provide a better error message
38--
36--
39subsumes :: Maybe Expr -> Type -> Type -> UnifyT Type Check (Maybe Expr)
37subsumes :: 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
41
39
42-- |
40-- |
43-- Check whether one type subsumes another
41-- Check whether one type subsumes another
@@ -57,12 +55,6 @@ subsumes' val (TypeApp (TypeApp f1 arg1) ret1) (TypeApp (TypeApp f2 arg2) ret2)
57 _ <- subsumes Nothing arg2 arg1
55 _ <- subsumes Nothing arg2 arg1
58 _ <- subsumes Nothing ret1 ret2
56 _ <- subsumes Nothing ret1 ret2
59 return val
57 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
66subsumes' val (KindedType ty1 _) ty2 =
58subsumes' val (KindedType ty1 _) ty2 =
67 subsumes val ty1 ty2
59 subsumes val ty1 ty2
68subsumes' val ty1 (KindedType ty2 _) =
60subsumes' val ty1 (KindedType ty2 _) =
src/Language/PureScript/TypeChecker/Synonyms.hs+20−66
@@ -9,22 +9,18 @@
9-- Portability :
9-- Portability :
10--
10--
11-- |
11-- |
12−-- Functions for replacing fully applied type synonyms with the @SaturatedTypeSynonym@ data constructor
12+-- Functions for replacing fully applied type synonyms
13--
13--
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16{-# LANGUAGE FlexibleContexts #-}
16{-# LANGUAGE FlexibleContexts #-}
17{-# LANGUAGE MultiParamTypeClasses #-}
17{-# LANGUAGE MultiParamTypeClasses #-}
18+{-# LANGUAGE PatternGuards #-}
18{-# LANGUAGE GADTs #-}
19{-# LANGUAGE GADTs #-}
19{-# LANGUAGE CPP #-}
20{-# LANGUAGE CPP #-}
20
21
21module Language.PureScript.TypeChecker.Synonyms (
22module Language.PureScript.TypeChecker.Synonyms (
22− saturateAllTypeSynonyms,
23− desaturateAllTypeSynonyms,
24− replaceAllTypeSynonyms,
23+ replaceAllTypeSynonyms
25− expandAllTypeSynonyms,
26− expandTypeSynonym,
27− expandTypeSynonym'
28) where
24) where
29
25
30import Data.Maybe (fromMaybe)
26import Data.Maybe (fromMaybe)
@@ -38,73 +34,31 @@ import Control.Monad.State
38
34
39import Language.PureScript.Environment
35import Language.PureScript.Environment
40import Language.PureScript.Errors
36import Language.PureScript.Errors
41−import Language.PureScript.Names
42import Language.PureScript.TypeChecker.Monad
37import Language.PureScript.TypeChecker.Monad
43import Language.PureScript.Types
38import Language.PureScript.Types
44
39
45-- |
40-- |
46−-- Build a type substitution for a type synonym
41+-- Replace fully applied type synonyms.
47--
42--
48−buildTypeSubstitution :: M.Map (Qualified ProperName) Int -> Type -> Either ErrorMessage (Maybe Type)
43+replaceAllTypeSynonyms' :: Environment -> Type -> Either MultipleErrors Type
49−buildTypeSubstitution m = go 0 []
44+replaceAllTypeSynonyms' env = everywhereOnTypesTopDownM try
50 where
45 where
51− go :: Int -> [Type] -> Type -> Either ErrorMessage (Maybe Type)
46+ try :: Type -> Either MultipleErrors Type
52− go c args (TypeConstructor ctor) | M.lookup ctor m == Just c = return (Just $ SaturatedTypeSynonym ctor args)
47+ try t = fromMaybe t <$> go 0 [] t
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
64
48
65−-- |
49+ go :: Int -> [Type] -> Type -> Either MultipleErrors (Maybe Type)
66−-- \"Desaturate\" @SaturatedTypeSynonym@s
50+ go c args (TypeConstructor ctor)
67−--
51+ | Just (synArgs, body) <- M.lookup ctor (typeSynonyms env)
68−desaturateAllTypeSynonyms :: Type -> Type
52+ , c == length synArgs
69−desaturateAllTypeSynonyms = everywhereOnTypes replaceSaturatedTypeSynonym
53+ = let repl = replaceAllTypeVars (zip (map fst synArgs) args) body
70− where
54+ in Just <$> try repl
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
55+ | Just (synArgs, _) <- M.lookup ctor (typeSynonyms env)
82− in
56+ , length synArgs > c
83− saturateAllTypeSynonyms syns d
57+ = throwError . errorMessage $ PartiallyAppliedSynonym ctor
58+ go c args (TypeApp f arg) = go (c + 1) (arg : args) f
59+ go _ _ _ = return Nothing
84
60
85replaceAllTypeSynonyms :: (e ~ MultipleErrors, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
61replaceAllTypeSynonyms :: (e ~ MultipleErrors, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
86replaceAllTypeSynonyms d = do
62replaceAllTypeSynonyms d = do
87 env <- getEnv
63 env <- getEnv
88− either (throwError . singleError) return $ replaceAllTypeSynonyms' env d
64+ either throwError 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
src/Language/PureScript/TypeChecker/Types.hs+18−58
@@ -67,24 +67,17 @@ import Language.PureScript.TypeChecker.Synonyms
67import Language.PureScript.TypeChecker.Unify
67import Language.PureScript.TypeChecker.Unify
68import Language.PureScript.TypeClassDictionaries
68import Language.PureScript.TypeClassDictionaries
69import Language.PureScript.Types
69import Language.PureScript.Types
70−import qualified Language.PureScript.Constants as C
71
70
72-- |
71-- |
73-- Infer the types of multiple mutually-recursive values, and return elaborated values including
72-- Infer the types of multiple mutually-recursive values, and return elaborated values including
74-- type class dictionaries and type annotations.
73-- type class dictionaries and type annotations.
75--
74--
76−typesOf :: Maybe ModuleName -> ModuleName -> [(Ident, Expr)] -> Check [(Ident, (Expr, Type))]
75+typesOf :: ModuleName -> [(Ident, Expr)] -> Check [(Ident, (Expr, Type))]
77−typesOf mainModuleName moduleName vals = do
76+typesOf moduleName vals = do
78 tys <- fmap tidyUp . liftUnifyWarnings replace $ do
77 tys <- fmap tidyUp . liftUnifyWarnings replace $ do
79 (untyped, typed, dict, untypedDict) <- typeDictionaryForBindingGroup moduleName vals
78 (untyped, typed, dict, untypedDict) <- typeDictionaryForBindingGroup moduleName vals
80− ds1 <- parU typed $ \e -> do
81− triple@(_, (_, ty)) <- checkTypedBindingGroupElement moduleName e dict
79+ ds1 <- parU typed $ \e -> 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
80+ ds2 <- forM untyped $ \e -> typeForBindingGroupElement e dict untypedDict
86− checkMain (fst e) ty
87− return triple
88 return $ ds1 ++ ds2
81 return $ ds1 ++ ds2
89
82
90 forM tys $ \(ident, (val, ty)) -> do
83 forM tys $ \(ident, (val, ty)) -> do
@@ -94,21 +87,13 @@ typesOf mainModuleName moduleName vals = do
94 skolemEscapeCheck val'
87 skolemEscapeCheck val'
95 -- Check rows do not contain duplicate labels
88 -- Check rows do not contain duplicate labels
96 checkDuplicateLabels val'
89 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))
102 where
91 where
103 -- Apply the substitution that was returned from runUnify to both types and (type-annotated) values
92 -- Apply the substitution that was returned from runUnify to both types and (type-annotated) values
104 tidyUp (ts, sub) = map (\(i, (val, ty)) -> (i, (overTypes (sub $?) val, sub $? ty))) ts
93 tidyUp (ts, sub) = map (\(i, (val, ty)) -> (i, (overTypes (sub $?) val, sub $? ty))) ts
105 -- Replace all the wildcards types with their inferred types
94 -- 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)
107 replace _ em = em
96 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
112
97
113type TypeData = M.Map (ModuleName, Ident) (Type, NameKind, NameVisibility)
98type TypeData = M.Map (ModuleName, Ident) (Type, NameKind, NameVisibility)
114
99
@@ -182,9 +167,7 @@ replaceTypeClassDictionaries mn =
182 let (_, f, _) = everywhereOnValuesTopDownM return go return
167 let (_, f, _) = everywhereOnValuesTopDownM return go return
183 in f
168 in f
184 where
169 where
185− go (TypeClassDictionary constraint dicts) = do
170+ go (TypeClassDictionary constraint dicts) = entails mn dicts constraint
186− env <- getEnv
187− entails env mn dicts constraint
188 go other = return other
171 go other = return other
189
172
190-- |
173-- |
@@ -214,7 +197,7 @@ instantiatePolyTypeWithUnknowns val ty = return (val, ty)
214-- Infer a type for a value, rethrowing any error to provide a more useful error message
197-- Infer a type for a value, rethrowing any error to provide a more useful error message
215--
198--
216infer :: Expr -> UnifyT Type Check Expr
199infer :: Expr -> UnifyT Type Check Expr
217−infer val = rethrow (onErrorMessages (ErrorInferringType val)) $ infer' val
200+infer val = rethrow (addHint (ErrorInferringType val)) $ infer' val
218
201
219-- |
202-- |
220-- Infer a type for a value
203-- Infer a type for a value
@@ -246,15 +229,10 @@ infer' (ObjectUpdate o ps) = do
246 o' <- TypedValue True <$> check o oldTy <*> pure oldTy
229 o' <- TypedValue True <$> check o oldTy <*> pure oldTy
247 return $ TypedValue True (ObjectUpdate o' newVals) $ TypeApp tyObject $ rowFromList (newTys, row)
230 return $ TypedValue True (ObjectUpdate o' newVals) $ TypeApp tyObject $ rowFromList (newTys, row)
248infer' (Accessor prop val) = do
231infer' (Accessor prop val) = do
249− typed@(TypedValue _ _ objTy) <- infer val
232+ field <- fresh
250− propTy <- inferProperty objTy prop
233+ rest <- fresh
251− case propTy of
252− Nothing -> do
253− field <- fresh
254− rest <- fresh
255− _ <- subsumes Nothing objTy (TypeApp tyObject (RCons prop field rest))
234+ typed <- check val (TypeApp tyObject (RCons prop field rest))
256− return $ TypedValue True (Accessor prop typed) field
235+ return $ TypedValue True (Accessor prop typed) field
257− Just ty -> return $ TypedValue True (Accessor prop typed) ty
258infer' (Abs (Left arg) ret) = do
236infer' (Abs (Left arg) ret) = do
259 ty <- fresh
237 ty <- fresh
260 Just moduleName <- checkCurrentModule <$> get
238 Just moduleName <- checkCurrentModule <$> get
@@ -339,21 +317,6 @@ inferLetBinding seen (PositionedDeclaration pos com d : ds) ret j = warnAndRethr
339 return (PositionedDeclaration pos com d' : ds', val')
317 return (PositionedDeclaration pos com d' : ds', val')
340inferLetBinding _ _ _ _ = error "Invalid argument to inferLetBinding"
318inferLetBinding _ _ _ _ = error "Invalid argument to inferLetBinding"
341
319
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−
357-- |
320-- |
358-- Infer the types of variables brought into scope by a binder
321-- Infer the types of variables brought into scope by a binder
359--
322--
@@ -407,6 +370,9 @@ inferBinder val (NamedBinder name binder) = do
407 return $ M.insert name val m
370 return $ M.insert name val m
408inferBinder val (PositionedBinder pos _ binder) =
371inferBinder val (PositionedBinder pos _ binder) =
409 warnAndRethrowWithPosition pos $ inferBinder val binder
372 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
410
376
411-- | Returns true if a binder requires its argument type to be a monotype.
377-- | Returns true if a binder requires its argument type to be a monotype.
412-- | If this is the case, we need to instantiate any polymorphic types before checking binders.
378-- | If this is the case, we need to instantiate any polymorphic types before checking binders.
@@ -419,7 +385,7 @@ binderRequiresMonotype _ = True
419
385
420-- | Instantiate polytypes only when necessitated by a binder.
386-- | Instantiate polytypes only when necessitated by a binder.
421instantiateForBinders :: [Expr] -> [CaseAlternative] -> UnifyT Type Check ([Expr], [Type])
387instantiateForBinders :: [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
423 TypedValue _ val' ty <- infer val
389 TypedValue _ val' ty <- infer val
424 if inst
390 if inst
425 then instantiatePolyTypeWithUnknowns val' ty
391 then instantiatePolyTypeWithUnknowns val' ty
@@ -457,7 +423,7 @@ checkBinders nvals ret (CaseAlternative binders result : bs) = do
457-- Check the type of a value, rethrowing errors to provide a better error message
423-- Check the type of a value, rethrowing errors to provide a better error message
458--
424--
459check :: Expr -> Type -> UnifyT Type Check Expr
425check :: 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
461
427
462-- |
428-- |
463-- Check the type of a value
429-- Check the type of a value
@@ -493,9 +459,6 @@ check' val t@(ConstrainedType constraints ty) = do
493
459
494 instantiateSuperclass :: [String] -> [Type] -> [Type] -> [Type]
460 instantiateSuperclass :: [String] -> [Type] -> [Type] -> [Type]
495 instantiateSuperclass args supArgs tys = map (replaceAllTypeVars (zip args tys)) supArgs
461 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
499check' val u@(TUnknown _) = do
462check' val u@(TUnknown _) = do
500 val'@(TypedValue _ _ ty) <- infer val
463 val'@(TypedValue _ _ ty) <- infer val
501 -- Don't unify an unknown with an inferred polytype
464 -- 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
646-- Check the type of a function application, rethrowing errors to provide a better error message
609-- Check the type of a function application, rethrowing errors to provide a better error message
647--
610--
648checkFunctionApplication :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
611checkFunctionApplication :: 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
650 subst <- unifyCurrentSubstitution <$> UnifyT get
613 subst <- unifyCurrentSubstitution <$> UnifyT get
651 checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
614 checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
652
615
@@ -674,9 +637,6 @@ checkFunctionApplication' fn u@(TUnknown _) arg ret = do
674 ret' <- maybe fresh return ret
637 ret' <- maybe fresh return ret
675 u =?= function ty ret'
638 u =?= function ty ret'
676 return (ret', App fn arg')
639 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
680checkFunctionApplication' fn (KindedType ty _) arg ret =
640checkFunctionApplication' fn (KindedType ty _) arg ret =
681 checkFunctionApplication fn ty arg ret
641 checkFunctionApplication fn ty arg ret
682checkFunctionApplication' fn (ConstrainedType constraints fnTy) arg ret = do
642checkFunctionApplication' fn (ConstrainedType constraints fnTy) arg ret = do
src/Language/PureScript/TypeChecker/Unify.hs+11−26
@@ -36,11 +36,9 @@ import Control.Monad.Unify
36import Control.Monad.Writer
36import Control.Monad.Writer
37import Control.Monad.Error.Class (MonadError(..))
37import Control.Monad.Error.Class (MonadError(..))
38
38
39−import Language.PureScript.Environment
40import Language.PureScript.Errors
39import Language.PureScript.Errors
41import Language.PureScript.TypeChecker.Monad
40import Language.PureScript.TypeChecker.Monad
42import Language.PureScript.TypeChecker.Skolems
41import Language.PureScript.TypeChecker.Skolems
43−import Language.PureScript.TypeChecker.Synonyms
44import Language.PureScript.Types
42import Language.PureScript.Types
45
43
46instance Partial Type where
44instance Partial Type where
@@ -63,16 +61,12 @@ instance Unifiable Check Type where
63-- Unify two types, updating the current substitution
61-- Unify two types, updating the current substitution
64--
62--
65unifyTypes :: Type -> Type -> UnifyT Type Check ()
63unifyTypes :: Type -> Type -> UnifyT Type Check ()
66−unifyTypes t1 t2 = rethrow (onErrorMessages (ErrorUnifyingTypes t1 t2)) $
64+unifyTypes t1 t2 = rethrow (addHint (ErrorUnifyingTypes t1 t2)) $
67 unifyTypes' t1 t2
65 unifyTypes' t1 t2
68 where
66 where
69 unifyTypes' (TUnknown u1) (TUnknown u2) | u1 == u2 = return ()
67 unifyTypes' (TUnknown u1) (TUnknown u2) | u1 == u2 = return ()
70 unifyTypes' (TUnknown u) t = u =:= t
68 unifyTypes' (TUnknown u) t = u =:= t
71 unifyTypes' t (TUnknown u) = u =:= t
69 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
76 unifyTypes' (ForAll ident1 ty1 sc1) (ForAll ident2 ty2 sc2) =
70 unifyTypes' (ForAll ident1 ty1 sc1) (ForAll ident2 ty2 sc2) =
77 case (sc1, sc2) of
71 case (sc1, sc2) of
78 (Just sc1', Just sc2') -> do
72 (Just sc1', Just sc2') -> do
@@ -132,10 +126,6 @@ unifyRows r1 r2 =
132 rest <- fresh
126 rest <- fresh
133 u1 =:= rowFromList (sd2, rest)
127 u1 =:= rowFromList (sd2, rest)
134 u2 =:= rowFromList (sd1, rest)
128 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'
139 unifyRows' [] REmpty [] REmpty = return ()
129 unifyRows' [] REmpty [] REmpty = return ()
140 unifyRows' [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = return ()
130 unifyRows' [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = return ()
141 unifyRows' [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = return ()
131 unifyRows' [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = return ()
@@ -144,26 +134,21 @@ unifyRows r1 r2 =
144-- |
134-- |
145-- Check that two types unify
135-- Check that two types unify
146--
136--
147−unifiesWith :: Environment -> Type -> Type -> Bool
137+unifiesWith :: Type -> Type -> Bool
148−unifiesWith _ (TUnknown u1) (TUnknown u2) | u1 == u2 = True
138+unifiesWith (TUnknown u1) (TUnknown u2) | u1 == u2 = True
149−unifiesWith _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = True
139+unifiesWith (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = True
150−unifiesWith _ (TypeVar v1) (TypeVar v2) | v1 == v2 = True
140+unifiesWith (TypeVar v1) (TypeVar v2) | v1 == v2 = True
151−unifiesWith _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = True
141+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
142+unifiesWith (TypeApp h1 t1) (TypeApp h2 t2) = h1 `unifiesWith` h2 && t1 `unifiesWith` 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
143+unifiesWith REmpty REmpty = True
159−unifiesWith e r1@(RCons _ _ _) r2@(RCons _ _ _) =
144+unifiesWith r1@RCons{} r2@RCons{} =
160 let (s1, r1') = rowToList r1
145 let (s1, r1') = rowToList r1
161 (s2, r2') = rowToList r2
146 (s2, r2') = rowToList r2
162
147
163 int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
148 int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
164 sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
149 sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
165 sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]
150 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'
167 where
152 where
168 go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Bool
153 go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Bool
169 go [] REmpty [] REmpty = True
154 go [] REmpty [] REmpty = True
@@ -173,7 +158,7 @@ unifiesWith e r1@(RCons _ _ _) r2@(RCons _ _ _) =
173 go _ _ [] (TUnknown _) = True
158 go _ _ [] (TUnknown _) = True
174 go _ (TUnknown _) _ (TUnknown _) = True
159 go _ (TUnknown _) _ (TUnknown _) = True
175 go _ _ _ _ = False
160 go _ _ _ _ = False
176−unifiesWith _ _ _ = False
161+unifiesWith _ _ = False
177
162
178-- |
163-- |
179-- Replace a single type variable with a new unification variable
164-- 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
22
22
23import Data.Data
23import Data.Data
24import Data.List (nub)
24import Data.List (nub)
25+import Data.Maybe (fromMaybe)
25import qualified Data.Aeson as A
26import qualified Data.Aeson as A
26import qualified Data.Aeson.TH as A
27import qualified Data.Aeson.TH as A
27
28
@@ -66,10 +67,6 @@ data Type
66 --
67 --
67 | TypeApp Type Type
68 | TypeApp Type Type
68 -- |
69 -- |
69− -- A type synonym which is \"saturated\", i.e. fully applied
70− --
71− | SaturatedTypeSynonym (Qualified ProperName) [Type]
72− -- |
73 -- Forall quantifier
70 -- Forall quantifier
74 --
71 --
75 | ForAll String Type (Maybe SkolemScope)
72 | ForAll String Type (Maybe SkolemScope)
@@ -156,12 +153,8 @@ replaceAllTypeVars = go []
156 where
153 where
157
154
158 go :: [String] -> [(String, Type)] -> Type -> Type
155 go :: [String] -> [(String, Type)] -> Type -> Type
159− go _ m (TypeVar v) =
156+ go _ m (TypeVar v) = fromMaybe (TypeVar v) (v `lookup` m)
160− case v `lookup` m of
161− Just r -> r
162− Nothing -> TypeVar v
163 go bs m (TypeApp t1 t2) = TypeApp (go bs m t1) (go bs m t2)
157 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
165 go bs m f@(ForAll v t sco) | v `elem` keys = go bs (filter ((/= v) . fst) m) f
158 go bs m f@(ForAll v t sco) | v `elem` keys = go bs (filter ((/= v) . fst) m) f
166 | v `elem` usedVars =
159 | v `elem` usedVars =
167 let v' = genName v (keys ++ bs ++ usedVars)
160 let v' = genName v (keys ++ bs ++ usedVars)
@@ -200,7 +193,6 @@ freeTypeVariables = nub . go []
200 go :: [String] -> Type -> [String]
193 go :: [String] -> Type -> [String]
201 go bound (TypeVar v) | v `notElem` bound = [v]
194 go bound (TypeVar v) | v `notElem` bound = [v]
202 go bound (TypeApp t1 t2) = go bound t1 ++ go bound t2
195 go bound (TypeApp t1 t2) = go bound t1 ++ go bound t2
203− go bound (SaturatedTypeSynonym _ ts) = concatMap (go bound) ts
204 go bound (ForAll v t _) = go (v : bound) t
196 go bound (ForAll v t _) = go (v : bound) t
205 go bound (ConstrainedType cs t) = concatMap (concatMap (go bound) . snd) cs ++ go bound t
197 go bound (ConstrainedType cs t) = concatMap (concatMap (go bound) . snd) cs ++ go bound t
206 go bound (RCons _ t r) = go bound t ++ go bound r
198 go bound (RCons _ t r) = go bound t ++ go bound r
@@ -247,7 +239,6 @@ everywhereOnTypes :: (Type -> Type) -> Type -> Type
247everywhereOnTypes f = go
239everywhereOnTypes f = go
248 where
240 where
249 go (TypeApp t1 t2) = f (TypeApp (go t1) (go t2))
241 go (TypeApp t1 t2) = f (TypeApp (go t1) (go t2))
250− go (SaturatedTypeSynonym name tys) = f (SaturatedTypeSynonym name (map go tys))
251 go (ForAll arg ty sco) = f (ForAll arg (go ty) sco)
242 go (ForAll arg ty sco) = f (ForAll arg (go ty) sco)
252 go (ConstrainedType cs ty) = f (ConstrainedType (map (fmap (map go)) cs) (go ty))
243 go (ConstrainedType cs ty) = f (ConstrainedType (map (fmap (map go)) cs) (go ty))
253 go (RCons name ty rest) = f (RCons name (go ty) (go rest))
244 go (RCons name ty rest) = f (RCons name (go ty) (go rest))
@@ -261,7 +252,6 @@ everywhereOnTypesTopDown :: (Type -> Type) -> Type -> Type
261everywhereOnTypesTopDown f = go . f
252everywhereOnTypesTopDown f = go . f
262 where
253 where
263 go (TypeApp t1 t2) = TypeApp (go (f t1)) (go (f t2))
254 go (TypeApp t1 t2) = TypeApp (go (f t1)) (go (f t2))
264− go (SaturatedTypeSynonym name tys) = SaturatedTypeSynonym name (map (go . f) tys)
265 go (ForAll arg ty sco) = ForAll arg (go (f ty)) sco
255 go (ForAll arg ty sco) = ForAll arg (go (f ty)) sco
266 go (ConstrainedType cs ty) = ConstrainedType (map (fmap (map (go . f))) cs) (go (f ty))
256 go (ConstrainedType cs ty) = ConstrainedType (map (fmap (map (go . f))) cs) (go (f ty))
267 go (RCons name ty rest) = RCons name (go (f ty)) (go (f rest))
257 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) ->
275everywhereOnTypesM f = go
265everywhereOnTypesM f = go
276 where
266 where
277 go (TypeApp t1 t2) = (TypeApp <$> go t1 <*> go t2) >>= f
267 go (TypeApp t1 t2) = (TypeApp <$> go t1 <*> go t2) >>= f
278− go (SaturatedTypeSynonym name tys) = (SaturatedTypeSynonym name <$> mapM go tys) >>= f
279 go (ForAll arg ty sco) = (ForAll arg <$> go ty <*> pure sco) >>= f
268 go (ForAll arg ty sco) = (ForAll arg <$> go ty <*> pure sco) >>= f
280 go (ConstrainedType cs ty) = (ConstrainedType <$> mapM (sndM (mapM go)) cs <*> go ty) >>= f
269 go (ConstrainedType cs ty) = (ConstrainedType <$> mapM (sndM (mapM go)) cs <*> go ty) >>= f
281 go (RCons name ty rest) = (RCons name <$> go ty <*> go rest) >>= f
270 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
289everywhereOnTypesTopDownM f = go <=< f
278everywhereOnTypesTopDownM f = go <=< f
290 where
279 where
291 go (TypeApp t1 t2) = TypeApp <$> (f t1 >>= go) <*> (f t2 >>= go)
280 go (TypeApp t1 t2) = TypeApp <$> (f t1 >>= go) <*> (f t2 >>= go)
292− go (SaturatedTypeSynonym name tys) = SaturatedTypeSynonym name <$> mapM (go <=< f) tys
293 go (ForAll arg ty sco) = ForAll arg <$> (f ty >>= go) <*> pure sco
281 go (ForAll arg ty sco) = ForAll arg <$> (f ty >>= go) <*> pure sco
294 go (ConstrainedType cs ty) = ConstrainedType <$> mapM (sndM (mapM (go <=< f))) cs <*> (f ty >>= go)
282 go (ConstrainedType cs ty) = ConstrainedType <$> mapM (sndM (mapM (go <=< f))) cs <*> (f ty >>= go)
295 go (RCons name ty rest) = RCons name <$> (f ty >>= go) <*> (f rest >>= go)
283 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
303everythingOnTypes (<>) f = go
291everythingOnTypes (<>) f = go
304 where
292 where
305 go t@(TypeApp t1 t2) = f t <> go t1 <> go t2
293 go t@(TypeApp t1 t2) = f t <> go t1 <> go t2
306− go t@(SaturatedTypeSynonym _ tys) = foldl (<>) (f t) (map go tys)
307 go t@(ForAll _ ty _) = f t <> go ty
294 go t@(ForAll _ ty _) = f t <> go ty
308 go t@(ConstrainedType cs ty) = foldl (<>) (f t) (map go $ concatMap snd cs) <> go ty
295 go t@(ConstrainedType cs ty) = foldl (<>) (f t) (map go $ concatMap snd cs) <> go ty
309 go t@(RCons _ ty rest) = f t <> go ty <> go rest
296 go t@(RCons _ ty rest) = f t <> go ty <> go rest
@@ -318,7 +305,6 @@ everythingWithContextOnTypes s0 r0 (<>) f = go' s0
318 where
305 where
319 go' s t = let (s', r) = f s t in r <> go s' t
306 go' s t = let (s', r) = f s t in r <> go s' t
320 go s (TypeApp t1 t2) = go' s t1 <> go' s t2
307 go s (TypeApp t1 t2) = go' s t1 <> go' s t2
321− go s (SaturatedTypeSynonym _ tys) = foldl (<>) r0 (map (go' s) tys)
322 go s (ForAll _ ty _) = go' s ty
308 go s (ForAll _ ty _) = go' s ty
323 go s (ConstrainedType cs ty) = foldl (<>) r0 (map (go' s) $ concatMap snd cs) <> go' s ty
309 go s (ConstrainedType cs ty) = foldl (<>) r0 (map (go' s) $ concatMap snd cs) <> go' s ty
324 go s (RCons _ ty rest) = go' s ty <> go' s rest
310 go s (RCons _ ty rest) = go' s ty <> go' s rest