git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge branch 'master' of https://github.com/purescript/purescript
4dd8c87Benjamin Kovach
.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+6−6
@@ -9,8 +9,8 @@ matrix:
9 - env: GHCVER=7.8.4 COVERAGE_SUITE=psci-tests
9 - env: GHCVER=7.8.4 COVERAGE_SUITE=psci-tests
10 compiler: ": #GHC 7.8.4 - psci-tests"
10 compiler: ": #GHC 7.8.4 - psci-tests"
11 addons: {apt: {packages: [cabal-install-1.22,ghc-7.8.4,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
11 addons: {apt: {packages: [cabal-install-1.22,ghc-7.8.4,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
12− - env: GHCVER=7.8.4 STACKAGE=lts-22
12+ - env: GHCVER=7.8.4 STACKAGE=lts-2.22
13− compiler: ": #GHC 7.8.4 - lts-2.22"
13+ compiler: ": #GHC 7.8.4 - lts-2.22-1"
14 addons: {apt: {packages: [cabal-install-1.22,ghc-7.8.4,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
14 addons: {apt: {packages: [cabal-install-1.22,ghc-7.8.4,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
15 - env: GHCVER=7.6.3
15 - env: GHCVER=7.6.3
16 compiler: ": #GHC 7.6.3"
16 compiler: ": #GHC 7.6.3"
@@ -18,11 +18,11 @@ matrix:
18 - env: GHCVER=7.10.1
18 - env: GHCVER=7.10.1
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.4 RUNSDISTTESTS=YES
21+ - env: GHCVER=7.10.2 STACKAGE=lts=3.6 RUNSDISTTESTS=YES
22− compiler: ": #GHC 7.10.2 lts-3.4"
22+ compiler: ": #GHC 7.10.2 lts-3.6"
23 addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
23 addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
24− - env: GHCVER=7.10.2 STACKAGE=nightly-2015-08-24
24+ - env: GHCVER=7.10.2 STACKAGE=nightly-2015-09-29
25− compiler: ": #GHC 7.10.2 nightly-2015-09-09"
25+ compiler: ": #GHC 7.10.2 nightly-2015-09-29"
26 addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
26 addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
27before_install:
27before_install:
28 - unset CC
28 - unset CC
CONTRIBUTORS.md+1
@@ -53,6 +53,7 @@ This file lists the contributors to the PureScript compiler project, and the ter
53- [@utkarshkukreti](https://github.com/utkarshkukreti) (Utkarsh Kukreti) My existing contributions and all future contributions until further notice are Copyright Utkarsh Kukreti, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
53- [@utkarshkukreti](https://github.com/utkarshkukreti) (Utkarsh Kukreti) My existing contributions and all future contributions until further notice are Copyright Utkarsh Kukreti, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
54- [@vkorablin](https://github.com/vkorablin) (Vladimir Korablin) - My existing contributions and all future contributions until further notice are Copyright Vladimir Korablin, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
54- [@vkorablin](https://github.com/vkorablin) (Vladimir Korablin) - My existing contributions and all future contributions until further notice are Copyright Vladimir Korablin, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
55- [@zudov](https://github.com/zudov) (Konstantin Zudov) My existing contributions and all future contributions until further notice are Copyright Konstantin Zudov, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
55- [@zudov](https://github.com/zudov) (Konstantin Zudov) My existing contributions and all future contributions until further notice are Copyright Konstantin Zudov, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
56+- [@senju](https://github.com/senju) - My existing contributions and all future contributions until further notice are Copyright senju, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
56<http://opensource.org/licenses/MIT>.
57<http://opensource.org/licenses/MIT>.
57
58
58### Companies
59### Companies
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
bundle/READMEmode 100755 → 100644

Only the mode changed.

examples/passing/LargeSumType.pursnew file+33
@@ -0,0 +1,33 @@
1+module Main where
2+
3+data Large = A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
4+
5+explode A A = "A"
6+explode B B = "B"
7+explode C C = "C"
8+explode D D = "D"
9+explode E E = "E"
10+explode F F = "F"
11+explode G G = "G"
12+explode H H = "H"
13+explode I I = "I"
14+explode J J = "J"
15+explode K K = "K"
16+explode L L = "L"
17+explode M M = "M"
18+explode N N = "N"
19+explode O O = "O"
20+explode P P = "P"
21+explode Q Q = "Q"
22+explode R R = "R"
23+explode S S = "S"
24+explode T T = "T"
25+explode U U = "U"
26+explode V V = "V"
27+explode W W = "W"
28+explode X X = "X"
29+explode Y Y = "Y"
30+explode Z Z = "Z"
31+explode _ _ = ""
32+
33+main = Control.Monad.Eff.Console.log "Done"
examples/passing/OptionalQualified.pursnew file+13
@@ -0,0 +1,13 @@
1+module Main where
2+
3+-- qualified import with the "qualified" keyword
4+import qualified Prelude as P
5+
6+-- qualified import without the "qualified" keyword
7+import Control.Monad.Eff.Console as Console
8+
9+bind = P.bind
10+
11+main = do
12+ message <- P.return "success!"
13+ Console.log message
examples/passing/QualifiedQualifiedImports.pursnew file+6
@@ -0,0 +1,6 @@
1+module Main where
2+
3+-- qualified import with qualified imported names
4+import qualified Control.Monad.Eff.Console (log) as Console
5+
6+main = Console.log "Success!"
examples/passing/UTF8Sourcefile.pursnew file+10
@@ -0,0 +1,10 @@
1+module Main where
2+
3+import Control.Monad.Eff.Console
4+
5+-- '→' is multibyte sequence \u2192.
6+utf8multibyte = "Hello λ→ world!!"
7+
8+main = do
9+ log "done"
10+
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
psc/Main.hs+4−2
@@ -32,6 +32,7 @@ import Options.Applicative as Opts
32
32
33import System.Exit (exitSuccess, exitFailure)
33import System.Exit (exitSuccess, exitFailure)
34import System.IO (hPutStrLn, stderr)
34import System.IO (hPutStrLn, stderr)
35+import System.IO.UTF8
35import System.FilePath.Glob (glob)
36import System.FilePath.Glob (glob)
36
37
37import qualified Language.PureScript as P
38import qualified Language.PureScript as P
@@ -60,7 +61,7 @@ compile (PSCMakeOptions inputGlob inputForeignGlob outputDir opts usePrefix) = d
60 let (jsFiles, pursFiles) = partition (isSuffixOf ".js") input
61 let (jsFiles, pursFiles) = partition (isSuffixOf ".js") input
61 moduleFiles <- readInput (InputOptions pursFiles)
62 moduleFiles <- readInput (InputOptions pursFiles)
62 inputForeign <- globWarningOnMisses warnFileTypeNotFound inputForeignGlob
63 inputForeign <- globWarningOnMisses warnFileTypeNotFound inputForeignGlob
63− foreignFiles <- forM (inputForeign ++ jsFiles) (\inFile -> (inFile,) <$> readFile inFile)
64+ foreignFiles <- forM (inputForeign ++ jsFiles) (\inFile -> (inFile,) <$> readUTF8File inFile)
64 case runWriterT (parseInputs moduleFiles foreignFiles) of
65 case runWriterT (parseInputs moduleFiles foreignFiles) of
65 Left errs -> do
66 Left errs -> do
66 hPutStrLn stderr (P.prettyPrintMultipleErrors (P.optionsVerboseErrors opts) errs)
67 hPutStrLn stderr (P.prettyPrintMultipleErrors (P.optionsVerboseErrors opts) errs)
@@ -93,7 +94,7 @@ globWarningOnMisses warn = concatMapM globWithWarning
93 concatMapM f = liftM concat . mapM f
94 concatMapM f = liftM concat . mapM f
94
95
95readInput :: InputOptions -> IO [(Either P.RebuildPolicy FilePath, String)]
96readInput :: InputOptions -> IO [(Either P.RebuildPolicy FilePath, String)]
96−readInput InputOptions{..} = forM ioInputFiles $ \inFile -> (Right inFile, ) <$> readFile inFile
97+readInput InputOptions{..} = forM ioInputFiles $ \inFile -> (Right inFile, ) <$> readUTF8File inFile
97
98
98parseInputs :: (Functor m, Applicative m, MonadError P.MultipleErrors m, MonadWriter P.MultipleErrors m)
99parseInputs :: (Functor m, Applicative m, MonadError P.MultipleErrors m, MonadWriter P.MultipleErrors m)
99 => [(Either P.RebuildPolicy FilePath, String)]
100 => [(Either P.RebuildPolicy FilePath, String)]
@@ -178,6 +179,7 @@ pscMakeOptions = PSCMakeOptions <$> many inputFile
178 <*> options
179 <*> options
179 <*> (not <$> noPrefix)
180 <*> (not <$> noPrefix)
180
181
182+
181main :: IO ()
183main :: IO ()
182main = execParser opts >>= compile
184main = execParser opts >>= compile
183 where
185 where
psci/PSCi.hs+13−10
@@ -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.
@@ -437,10 +437,10 @@ handleKindOf typ = do
437-- Parses the input and returns either a Metacommand, or an error as a string.
437-- Parses the input and returns either a Metacommand, or an error as a string.
438--
438--
439getCommand :: Bool -> InputT (StateT PSCiState IO) (Either String (Maybe Command))
439getCommand :: Bool -> InputT (StateT PSCiState IO) (Either String (Maybe Command))
440−getCommand singleLineMode = do
440+getCommand singleLineMode = handleInterrupt (return (Right Nothing)) $ do
441− firstLine <- getInputLine "> "
441+ firstLine <- withInterrupt $ getInputLine "> "
442 case firstLine of
442 case firstLine of
443− Nothing -> return (Right Nothing)
443+ Nothing -> return (Right (Just QuitPSCi)) -- Ctrl-D when input is empty
444 Just "" -> return (Right Nothing)
444 Just "" -> return (Right Nothing)
445 Just s | singleLineMode || head s == ':' -> return . either Left (Right . Just) $ parseCommand s
445 Just s | singleLineMode || head s == ':' -> return . either Left (Right . Just) $ parseCommand s
446 Just s -> either Left (Right . Just) . parseCommand <$> go [s]
446 Just s -> either Left (Right . Just) . parseCommand <$> go [s]
@@ -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
@@ -555,7 +555,10 @@ loop PSCiOptions{..} = do
555 Left err -> outputStrLn err >> go
555 Left err -> outputStrLn err >> go
556 Right Nothing -> go
556 Right Nothing -> go
557 Right (Just QuitPSCi) -> outputStrLn quitMessage
557 Right (Just QuitPSCi) -> outputStrLn quitMessage
558+ Right (Just c') -> do
559+ handleInterrupt (outputStrLn "Interrupted.")
558− Right (Just c') -> runPSCI (loadAllImportedModules >> handleCommand c') >> go
560+ (withInterrupt (runPSCI (loadAllImportedModules >> handleCommand c')))
561+ go
559
562
560multiLineMode :: Parser Bool
563multiLineMode :: Parser Bool
561multiLineMode = switch $
564multiLineMode = switch $
purescript.cabal+6−2
@@ -32,6 +32,9 @@ source-repository head
32
32
33library
33library
34 build-depends: base >=4.6 && <5,
34 build-depends: base >=4.6 && <5,
35+ lifted-base >= 0.2.3 && < 0.2.4,
36+ monad-control >= 1.0.0.0 && < 1.1,
37+ transformers-base >= 0.4.0 && < 0.5,
35 containers -any,
38 containers -any,
36 unordered-containers -any,
39 unordered-containers -any,
37 dlist -any,
40 dlist -any,
@@ -55,7 +58,7 @@ library
55 language-javascript == 0.5.*,
58 language-javascript == 0.5.*,
56 syb -any,
59 syb -any,
57 Glob >= 0.7 && < 0.8,
60 Glob >= 0.7 && < 0.8,
58− process >= 1.2.0 && < 1.3,
61+ process >= 1.2.0 && < 1.4,
59 safe >= 0.3.9 && < 0.4,
62 safe >= 0.3.9 && < 0.4,
60 semigroups >= 0.16.2 && < 0.18
63 semigroups >= 0.16.2 && < 0.18
61
64
@@ -162,6 +165,7 @@ library
162 Control.Monad.Supply
165 Control.Monad.Supply
163 Control.Monad.Supply.Class
166 Control.Monad.Supply.Class
164
167
168+ System.IO.UTF8
165 exposed: True
169 exposed: True
166 buildable: True
170 buildable: True
167 hs-source-dirs: src
171 hs-source-dirs: src
@@ -175,7 +179,7 @@ executable psc
175 main-is: Main.hs
179 main-is: Main.hs
176 buildable: True
180 buildable: True
177 hs-source-dirs: psc
181 hs-source-dirs: psc
178− ghc-options: -Wall -O2 -fno-warn-unused-do-bind
182+ ghc-options: -Wall -O2 -fno-warn-unused-do-bind -threaded -rtsopts "-with-rtsopts=-N"
179
183
180executable psci
184executable psci
181 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
185 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
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+3−3
@@ -216,10 +216,10 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
216 f' d = f d
216 f' d = f d
217
217
218 g' v@(UnaryMinus v1) = g v <> g' v1
218 g' v@(UnaryMinus v1) = g v <> g' v1
219− g' v@(BinaryNoParens op v1 v2) = g v <> g op <> g' v1 <> g' v2
219+ g' v@(BinaryNoParens op v1 v2) = g v <> g' op <> g' v1 <> g' v2
220 g' v@(Parens v1) = g v <> g' v1
220 g' v@(Parens v1) = g v <> g' v1
221− g' v@(OperatorSection op (Left v1)) = g v <> g op <> g' v1
221+ g' v@(OperatorSection op (Left v1)) = g v <> g' op <> g' v1
222− g' v@(OperatorSection op (Right v1)) = g v <> g op <> g' v1
222+ g' v@(OperatorSection op (Right v1)) = g v <> g' op <> g' v1
223 g' v@(ArrayLiteral vs) = foldl (<>) (g v) (map g' vs)
223 g' v@(ArrayLiteral vs) = foldl (<>) (g v) (map g' vs)
224 g' v@(ObjectLiteral vs) = foldl (<>) (g v) (map (g' . snd) vs)
224 g' v@(ObjectLiteral vs) = foldl (<>) (g v) (map (g' . snd) vs)
225 g' v@(ObjectConstructor vs) = foldl (<>) (g v) (map g' (mapMaybe snd vs))
225 g' v@(ObjectConstructor vs) = foldl (<>) (g v) (map g' (mapMaybe snd vs))
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/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+345−342
@@ -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,44 +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 | ClassOperator ProperName Ident
149 | ClassOperator ProperName Ident
149 | MisleadingEmptyTypeImport ModuleName ProperName
150 | MisleadingEmptyTypeImport ModuleName ProperName
150 | ImportHidingModule ModuleName
151 | ImportHidingModule ModuleName
151− deriving (Show)
152+ deriving Show
152−
153+
153−-- |
154+-- | Error message hints, providing more detailed information about failure.
154−-- Wrapper of simpler errors
155+data ErrorMessageHint
155−--
156−data ErrorMessage
157− = NotYetDefined [Ident] ErrorMessage
156+ = NotYetDefined [Ident]
158− | ErrorUnifyingTypes Type Type ErrorMessage
157+ | ErrorUnifyingTypes Type Type
159− | ErrorInExpression Expr ErrorMessage
158+ | ErrorInExpression Expr
160− | ErrorInModule ModuleName ErrorMessage
159+ | ErrorInModule ModuleName
161− | ErrorInInstance (Qualified ProperName) [Type] ErrorMessage
160+ | ErrorInInstance (Qualified ProperName) [Type]
162− | ErrorInSubsumption Type Type ErrorMessage
161+ | ErrorInSubsumption Type Type
163− | ErrorCheckingType Expr Type ErrorMessage
162+ | ErrorCheckingType Expr Type
164− | ErrorCheckingKind Type ErrorMessage
163+ | ErrorCheckingKind Type
165− | ErrorInferringType Expr ErrorMessage
164+ | ErrorInferringType Expr
166− | ErrorInApplication Expr Type Expr ErrorMessage
165+ | ErrorInApplication Expr Type Expr
167− | ErrorInDataConstructor ProperName ErrorMessage
166+ | ErrorInDataConstructor ProperName
168− | ErrorInTypeConstructor ProperName ErrorMessage
167+ | ErrorInTypeConstructor ProperName
169− | ErrorInBindingGroup [Ident] ErrorMessage
168+ | ErrorInBindingGroup [Ident]
170− | ErrorInDataBindingGroup ErrorMessage
169+ | ErrorInDataBindingGroup
171− | ErrorInTypeSynonym ProperName ErrorMessage
170+ | ErrorInTypeSynonym ProperName
172− | ErrorInValueDeclaration Ident ErrorMessage
171+ | ErrorInValueDeclaration Ident
173− | ErrorInTypeDeclaration Ident ErrorMessage
172+ | ErrorInTypeDeclaration Ident
174− | ErrorInForeignImport Ident ErrorMessage
173+ | ErrorInForeignImport Ident
175− | PositionedError SourceSpan ErrorMessage
174+ | PositionedError SourceSpan
176− | SimpleErrorWrapper SimpleErrorMessage
175+ deriving Show
177− 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)
178
187
179instance UnificationError Type ErrorMessage where
188instance UnificationError Type ErrorMessage where
180− occursCheckFailed t = SimpleErrorWrapper $ InfiniteType t
189+ occursCheckFailed t = ErrorMessage [] $ InfiniteType t
181
190
182instance UnificationError Kind ErrorMessage where
191instance UnificationError Kind ErrorMessage where
183− occursCheckFailed k = SimpleErrorWrapper $ InfiniteKind k
192+ occursCheckFailed k = ErrorMessage [] $ InfiniteKind k
184
193
185-- |
194-- |
186-- Get the error code for a particular error type
195-- Get the error code for a particular error type
@@ -229,6 +238,7 @@ errorCode em = case unwrapErrorMessage em of
229 CtorConflictsWithClass{} -> "CtorConflictsWithClass"
238 CtorConflictsWithClass{} -> "CtorConflictsWithClass"
230 ClassConflictsWithType{} -> "ClassConflictsWithType"
239 ClassConflictsWithType{} -> "ClassConflictsWithType"
231 ClassConflictsWithCtor{} -> "ClassConflictsWithCtor"
240 ClassConflictsWithCtor{} -> "ClassConflictsWithCtor"
241+ DuplicateModuleName{} -> "DuplicateModuleName"
232 DuplicateClassExport{} -> "DuplicateClassExport"
242 DuplicateClassExport{} -> "DuplicateClassExport"
233 DuplicateValueExport{} -> "DuplicateValueExport"
243 DuplicateValueExport{} -> "DuplicateValueExport"
234 DuplicateTypeArgument{} -> "DuplicateTypeArgument"
244 DuplicateTypeArgument{} -> "DuplicateTypeArgument"
@@ -272,8 +282,10 @@ errorCode em = case unwrapErrorMessage em of
272 ShadowedTypeVar{} -> "ShadowedTypeVar"
282 ShadowedTypeVar{} -> "ShadowedTypeVar"
273 UnusedTypeVar{} -> "UnusedTypeVar"
283 UnusedTypeVar{} -> "UnusedTypeVar"
274 WildcardInferredType{} -> "WildcardInferredType"
284 WildcardInferredType{} -> "WildcardInferredType"
285+ MissingTypeDeclaration{} -> "MissingTypeDeclaration"
275 NotExhaustivePattern{} -> "NotExhaustivePattern"
286 NotExhaustivePattern{} -> "NotExhaustivePattern"
276 OverlappingPattern{} -> "OverlappingPattern"
287 OverlappingPattern{} -> "OverlappingPattern"
288+ IncompleteExhaustivityCheck{} -> "IncompleteExhaustivityCheck"
277 ClassOperator{} -> "ClassOperator"
289 ClassOperator{} -> "ClassOperator"
278 MisleadingEmptyTypeImport{} -> "MisleadingEmptyTypeImport"
290 MisleadingEmptyTypeImport{} -> "MisleadingEmptyTypeImport"
279 ImportHidingModule{} -> "ImportHidingModule"
291 ImportHidingModule{} -> "ImportHidingModule"
@@ -298,7 +310,7 @@ nonEmpty = not . null . runMultipleErrors
298-- Create an error set from a single simple error message
310-- Create an error set from a single simple error message
299--
311--
300errorMessage :: SimpleErrorMessage -> MultipleErrors
312errorMessage :: SimpleErrorMessage -> MultipleErrors
301−errorMessage err = MultipleErrors [SimpleErrorWrapper err]
313+errorMessage err = MultipleErrors [ErrorMessage [] err]
302
314
303
315
304-- |
316-- |
@@ -307,12 +319,14 @@ errorMessage err = MultipleErrors [SimpleErrorWrapper err]
307singleError :: ErrorMessage -> MultipleErrors
319singleError :: ErrorMessage -> MultipleErrors
308singleError = MultipleErrors . pure
320singleError = MultipleErrors . pure
309
321
310−-- |
311−-- Lift a function on ErrorMessage to a function on MultipleErrors
322+-- | Lift a function on ErrorMessage to a function on MultipleErrors
312−--
313onErrorMessages :: (ErrorMessage -> ErrorMessage) -> MultipleErrors -> MultipleErrors
323onErrorMessages :: (ErrorMessage -> ErrorMessage) -> MultipleErrors -> MultipleErrors
314onErrorMessages f = MultipleErrors . map f . runMultipleErrors
324onErrorMessages f = MultipleErrors . map f . runMultipleErrors
315
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+
316-- | 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.
317data LabelType = TypeLabel | SkolemLabel String deriving (Show, Read, Eq, Ord)
331data LabelType = TypeLabel | SkolemLabel String deriving (Show, Read, Eq, Ord)
318
332
@@ -326,27 +340,7 @@ data Level = Error | Warning deriving Show
326-- Extract nested error messages from wrapper errors
340-- Extract nested error messages from wrapper errors
327--
341--
328unwrapErrorMessage :: ErrorMessage -> SimpleErrorMessage
342unwrapErrorMessage :: ErrorMessage -> SimpleErrorMessage
329−unwrapErrorMessage em = case em of
343+unwrapErrorMessage (ErrorMessage _ se) = se
330− (ErrorCheckingKind _ err) -> unwrapErrorMessage err
331− (ErrorCheckingType _ _ err) -> unwrapErrorMessage err
332− (ErrorInApplication _ _ _ err) -> unwrapErrorMessage err
333− (ErrorInBindingGroup _ err) -> unwrapErrorMessage err
334− (ErrorInDataBindingGroup err) -> unwrapErrorMessage err
335− (ErrorInDataConstructor _ err) -> unwrapErrorMessage err
336− (ErrorInExpression _ err) -> unwrapErrorMessage err
337− (ErrorInForeignImport _ err) -> unwrapErrorMessage err
338− (ErrorInInstance _ _ err) -> unwrapErrorMessage err
339− (ErrorInModule _ err) -> unwrapErrorMessage err
340− (ErrorInSubsumption _ _ err) -> unwrapErrorMessage err
341− (ErrorInTypeConstructor _ err) -> unwrapErrorMessage err
342− (ErrorInTypeSynonym _ err) -> unwrapErrorMessage err
343− (ErrorInValueDeclaration _ err) -> unwrapErrorMessage err
344− (ErrorInTypeDeclaration _ err) -> unwrapErrorMessage err
345− (ErrorInferringType _ err) -> unwrapErrorMessage err
346− (ErrorUnifyingTypes _ _ err) -> unwrapErrorMessage err
347− (NotYetDefined _ err) -> unwrapErrorMessage err
348− (PositionedError _ err) -> unwrapErrorMessage err
349− (SimpleErrorWrapper sem) -> sem
350
344
351replaceUnknowns :: Type -> State UnknownMap Type
345replaceUnknowns :: Type -> State UnknownMap Type
352replaceUnknowns = everywhereOnTypesM replaceTypes
346replaceUnknowns = everywhereOnTypesM replaceTypes
@@ -362,400 +356,406 @@ replaceUnknowns = everywhereOnTypesM replaceTypes
362 replaceTypes other = return other
356 replaceTypes other = return other
363
357
364onTypesInErrorMessageM :: (Applicative m) => (Type -> m Type) -> ErrorMessage -> m ErrorMessage
358onTypesInErrorMessageM :: (Applicative m) => (Type -> m Type) -> ErrorMessage -> m ErrorMessage
365−onTypesInErrorMessageM f = g
359+onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse gHint hints <*> gSimple simple
366 where
360 where
367− gSimple (InfiniteType t) = InfiniteType <$> (f t)
361+ gSimple (InfiniteType t) = InfiniteType <$> f t
368− gSimple (TypesDoNotUnify t1 t2) = TypesDoNotUnify <$> (f t1) <*> (f t2)
362+ gSimple (TypesDoNotUnify t1 t2) = TypesDoNotUnify <$> f t1 <*> f t2
369− gSimple (ConstrainedTypeUnified t1 t2) = ConstrainedTypeUnified <$> (f t1) <*> (f t2)
363+ gSimple (ConstrainedTypeUnified t1 t2) = ConstrainedTypeUnified <$> f t1 <*> f t2
370− gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> (f t)
364+ gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> f t
371− gSimple (PropertyIsMissing s t) = PropertyIsMissing s <$> (f t)
365+ gSimple (PropertyIsMissing s t) = PropertyIsMissing s <$> f t
372− gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> (pure e)
366+ gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> pure e
373 gSimple (InvalidInstanceHead t) = InvalidInstanceHead <$> f t
367 gSimple (InvalidInstanceHead t) = InvalidInstanceHead <$> f t
374 gSimple other = pure other
368 gSimple other = pure other
375− g (ErrorInSubsumption t1 t2 em) = ErrorInSubsumption <$> (f t1) <*> (f t2) <*> (g em)
369+ gHint (ErrorInSubsumption t1 t2) = ErrorInSubsumption <$> f t1 <*> f t2
376− g (ErrorUnifyingTypes t1 t2 e) = ErrorUnifyingTypes <$> (f t1) <*> (f t2) <*> (g e)
370+ gHint (ErrorUnifyingTypes t1 t2) = ErrorUnifyingTypes <$> f t1 <*> f t2
377− g (ErrorCheckingType e t em) = ErrorCheckingType e <$> (f t) <*> (g em)
371+ gHint (ErrorCheckingType e t) = ErrorCheckingType e <$> f t
378− g (ErrorCheckingKind t em) = ErrorCheckingKind <$> (f t) <*> g em
372+ gHint (ErrorCheckingKind t) = ErrorCheckingKind <$> f t
379− 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
380− g (NotYetDefined x e) = NotYetDefined x <$> (g e)
374+ gHint other = pure other
381− g (ErrorInExpression x e) = ErrorInExpression x <$> (g e)
382− g (ErrorInModule x e) = ErrorInModule x <$> (g e)
383− g (ErrorInInstance x y e) = ErrorInInstance x y <$> (g e)
384− g (ErrorInferringType x e) = ErrorInferringType x <$> (g e)
385− g (ErrorInDataConstructor x e) = ErrorInDataConstructor x <$> (g e)
386− g (ErrorInTypeConstructor x e) = ErrorInTypeConstructor x <$> (g e)
387− g (ErrorInBindingGroup x e) = ErrorInBindingGroup x <$> (g e)
388− g (ErrorInDataBindingGroup e) = ErrorInDataBindingGroup <$> (g e)
389− g (ErrorInTypeSynonym x e) = ErrorInTypeSynonym x <$> (g e)
390− g (ErrorInValueDeclaration x e) = ErrorInValueDeclaration x <$> (g e)
391− g (ErrorInTypeDeclaration x e) = ErrorInTypeDeclaration x <$> (g e)
392− g (ErrorInForeignImport x e) = ErrorInForeignImport x <$> (g e)
393− g (PositionedError x e) = PositionedError x <$> (g e)
394− g (SimpleErrorWrapper sem) = SimpleErrorWrapper <$> gSimple sem
395
375
396-- |
376-- |
397-- Pretty print a single error, simplifying if necessary
377-- Pretty print a single error, simplifying if necessary
398--
378--
399prettyPrintSingleError :: Bool -> Level -> ErrorMessage -> State UnknownMap Box.Box
379prettyPrintSingleError :: Bool -> Level -> ErrorMessage -> State UnknownMap Box.Box
400−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)
401 where
381 where
402− -- |
382+
403 -- Pretty print an ErrorMessage
383 -- Pretty print an ErrorMessage
404− --
405 prettyPrintErrorMessage :: ErrorMessage -> Box.Box
384 prettyPrintErrorMessage :: ErrorMessage -> Box.Box
406− prettyPrintErrorMessage em =
385+ prettyPrintErrorMessage (ErrorMessage hints simple) =
407 paras $
386 paras $
387+ map renderHint hints ++
388+ renderSimpleErrorMessage simple :
408− go em:suggestions em ++
389+ suggestions simple ++
409 [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 ++ "."]
410 where
391 where
411 wikiUri :: String
392 wikiUri :: String
412 wikiUri = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
393 wikiUri = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
413
394
414− go :: ErrorMessage -> Box.Box
395+ renderSimpleErrorMessage :: SimpleErrorMessage -> Box.Box
415− goSimple (CannotGetFileInfo path) =
396+ renderSimpleErrorMessage (CannotGetFileInfo path) =
416 paras [ line "Unable to read file info: "
397 paras [ line "Unable to read file info: "
417 , indent . line $ path
398 , indent . line $ path
418 ]
399 ]
419− goSimple (CannotReadFile path) =
400+ renderSimpleErrorMessage (CannotReadFile path) =
420 paras [ line "Unable to read file: "
401 paras [ line "Unable to read file: "
421 , indent . line $ path
402 , indent . line $ path
422 ]
403 ]
423− goSimple (CannotWriteFile path) =
404+ renderSimpleErrorMessage (CannotWriteFile path) =
424 paras [ line "Unable to write file: "
405 paras [ line "Unable to write file: "
425 , indent . line $ path
406 , indent . line $ path
426 ]
407 ]
427− goSimple (ErrorParsingExterns err) =
408+ renderSimpleErrorMessage (ErrorParsingExterns err) =
428 paras [ lineWithLevel "parsing externs files: "
409 paras [ lineWithLevel "parsing externs files: "
429− , indent . prettyPrintParseError $ err
410+ , prettyPrintParseError err
430 ]
411 ]
431− goSimple (ErrorParsingFFIModule path) =
412+ renderSimpleErrorMessage (ErrorParsingFFIModule path) =
432 paras [ line "Unable to parse module from FFI file: "
413 paras [ line "Unable to parse module from FFI file: "
433 , indent . line $ path
414 , indent . line $ path
434 ]
415 ]
435− goSimple (ErrorParsingModule err) =
416+ renderSimpleErrorMessage (ErrorParsingModule err) =
436 paras [ line "Unable to parse module: "
417 paras [ line "Unable to parse module: "
437− , indent . prettyPrintParseError $ err
418+ , prettyPrintParseError err
438 ]
419 ]
439− goSimple (MissingFFIModule mn) =
420+ renderSimpleErrorMessage (MissingFFIModule mn) =
440 line $ "Missing FFI implementations for module " ++ runModuleName mn
421 line $ "Missing FFI implementations for module " ++ runModuleName mn
441− goSimple (UnnecessaryFFIModule mn path) =
422+ renderSimpleErrorMessage (UnnecessaryFFIModule mn path) =
442 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 ++ ": "
443 , indent . line $ path
424 , indent . line $ path
444 ]
425 ]
445− goSimple (MultipleFFIModules mn paths) =
426+ renderSimpleErrorMessage (MultipleFFIModules mn paths) =
446− 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 ++ ": "
447− ++ map (indent . line) paths
428+ , indent . paras $ map line paths
429+ ]
448− goSimple (InvalidExternsFile path) =
430+ renderSimpleErrorMessage (InvalidExternsFile path) =
449 paras [ line "Externs file is invalid: "
431 paras [ line "Externs file is invalid: "
450 , indent . line $ path
432 , indent . line $ path
451 ]
433 ]
452− goSimple InvalidDoBind =
434+ renderSimpleErrorMessage InvalidDoBind =
453 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."
454− goSimple InvalidDoLet =
436+ renderSimpleErrorMessage InvalidDoLet =
455 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."
456− goSimple CannotReorderOperators =
438+ renderSimpleErrorMessage CannotReorderOperators =
457 line "Unable to reorder operators"
439 line "Unable to reorder operators"
458− goSimple UnspecifiedSkolemScope =
440+ renderSimpleErrorMessage UnspecifiedSkolemScope =
459 line "Skolem variable scope is unspecified"
441 line "Skolem variable scope is unspecified"
460− goSimple OverlappingNamesInLet =
442+ renderSimpleErrorMessage OverlappingNamesInLet =
461 line "Overlapping names in let binding."
443 line "Overlapping names in let binding."
462− goSimple (InfiniteType ty) =
444+ renderSimpleErrorMessage (InfiniteType ty) =
463 paras [ line "An infinite type was inferred for an expression: "
445 paras [ line "An infinite type was inferred for an expression: "
464− , indent $ line $ prettyPrintType ty
446+ , indent $ typeAsBox ty
465 ]
447 ]
466− goSimple (InfiniteKind ki) =
448+ renderSimpleErrorMessage (InfiniteKind ki) =
467 paras [ line "An infinite kind was inferred for a type: "
449 paras [ line "An infinite kind was inferred for a type: "
468− , indent $ line $ prettyPrintKind ki
450+ , indent $ kindAsBox ki
469 ]
451 ]
470− goSimple (MultipleFixities name) =
452+ renderSimpleErrorMessage (MultipleFixities name) =
471 line $ "Multiple fixity declarations for " ++ showIdent name
453 line $ "Multiple fixity declarations for " ++ showIdent name
472− goSimple (OrphanTypeDeclaration nm) =
454+ renderSimpleErrorMessage (OrphanTypeDeclaration nm) =
473 line $ "Orphan type declaration for " ++ showIdent nm
455 line $ "Orphan type declaration for " ++ showIdent nm
474− goSimple (OrphanFixityDeclaration op) =
456+ renderSimpleErrorMessage (OrphanFixityDeclaration op) =
475 line $ "Orphan fixity declaration for " ++ show op
457 line $ "Orphan fixity declaration for " ++ show op
476− goSimple (RedefinedModule name filenames) =
458+ renderSimpleErrorMessage (RedefinedModule name filenames) =
477− paras $ line ("Module " ++ runModuleName name ++ " has been defined multiple times:")
459+ paras [ line ("Module " ++ runModuleName name ++ " has been defined multiple times:")
478− : map (indent . line . displaySourceSpan) filenames
460+ , indent . paras $ map (line . displaySourceSpan) filenames
461+ ]
479− goSimple (RedefinedIdent name) =
462+ renderSimpleErrorMessage (RedefinedIdent name) =
480 line $ "Name " ++ showIdent name ++ " has been defined multiple times"
463 line $ "Name " ++ showIdent name ++ " has been defined multiple times"
481− goSimple (UnknownModule mn) =
464+ renderSimpleErrorMessage (UnknownModule mn) =
482 line $ "Unknown module " ++ runModuleName mn
465 line $ "Unknown module " ++ runModuleName mn
483− goSimple (UnknownType name) =
466+ renderSimpleErrorMessage (UnknownType name) =
484 line $ "Unknown type " ++ showQualified runProperName name
467 line $ "Unknown type " ++ showQualified runProperName name
485− goSimple (UnknownTypeClass name) =
468+ renderSimpleErrorMessage (UnknownTypeClass name) =
486 line $ "Unknown type class " ++ showQualified runProperName name
469 line $ "Unknown type class " ++ showQualified runProperName name
487− goSimple (UnknownValue name) =
470+ renderSimpleErrorMessage (UnknownValue name) =
488 line $ "Unknown value " ++ showQualified showIdent name
471 line $ "Unknown value " ++ showQualified showIdent name
489− goSimple (UnknownTypeConstructor name) =
472+ renderSimpleErrorMessage (UnknownTypeConstructor name) =
490 line $ "Unknown type constructor " ++ showQualified runProperName name
473 line $ "Unknown type constructor " ++ showQualified runProperName name
491− goSimple (UnknownDataConstructor dc tc) =
474+ renderSimpleErrorMessage (UnknownDataConstructor dc tc) =
492 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
493− goSimple (UnknownImportType mn name) =
476+ renderSimpleErrorMessage (UnknownImportType mn name) =
494 line $ "Module " ++ runModuleName mn ++ " does not export type " ++ runProperName name
477 line $ "Module " ++ runModuleName mn ++ " does not export type " ++ runProperName name
495− goSimple (UnknownExportType name) =
478+ renderSimpleErrorMessage (UnknownExportType name) =
496 line $ "Cannot export unknown type " ++ runProperName name
479 line $ "Cannot export unknown type " ++ runProperName name
497− goSimple (UnknownImportTypeClass mn name) =
480+ renderSimpleErrorMessage (UnknownImportTypeClass mn name) =
498 line $ "Module " ++ runModuleName mn ++ " does not export type class " ++ runProperName name
481 line $ "Module " ++ runModuleName mn ++ " does not export type class " ++ runProperName name
499− goSimple (UnknownExportTypeClass name) =
482+ renderSimpleErrorMessage (UnknownExportTypeClass name) =
500 line $ "Cannot export unknown type class " ++ runProperName name
483 line $ "Cannot export unknown type class " ++ runProperName name
501− goSimple (UnknownImportValue mn name) =
484+ renderSimpleErrorMessage (UnknownImportValue mn name) =
502 line $ "Module " ++ runModuleName mn ++ " does not export value " ++ showIdent name
485 line $ "Module " ++ runModuleName mn ++ " does not export value " ++ showIdent name
503− goSimple (UnknownExportValue name) =
486+ renderSimpleErrorMessage (UnknownExportValue name) =
504 line $ "Cannot export unknown value " ++ showIdent name
487 line $ "Cannot export unknown value " ++ showIdent name
505− goSimple (UnknownExportModule name) =
488+ renderSimpleErrorMessage (UnknownExportModule name) =
506 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"
507− goSimple (UnknownImportDataConstructor mn tcon dcon) =
490+ renderSimpleErrorMessage (UnknownImportDataConstructor mn tcon dcon) =
508 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
509− goSimple (UnknownExportDataConstructor tcon dcon) =
492+ renderSimpleErrorMessage (UnknownExportDataConstructor tcon dcon) =
510 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"
511− goSimple (ConflictingImport nm mn) =
494+ renderSimpleErrorMessage (ConflictingImport nm mn) =
512 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
513− goSimple (ConflictingImports nm m1 m2) =
496+ renderSimpleErrorMessage (ConflictingImports nm m1 m2) =
514 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
515− goSimple (ConflictingTypeDecls nm) =
498+ renderSimpleErrorMessage (ConflictingTypeDecls nm) =
516 line $ "Conflicting type declarations for " ++ runProperName nm
499 line $ "Conflicting type declarations for " ++ runProperName nm
517− goSimple (ConflictingCtorDecls nm) =
500+ renderSimpleErrorMessage (ConflictingCtorDecls nm) =
518 line $ "Conflicting data constructor declarations for " ++ runProperName nm
501 line $ "Conflicting data constructor declarations for " ++ runProperName nm
519− goSimple (TypeConflictsWithClass nm) =
502+ renderSimpleErrorMessage (TypeConflictsWithClass nm) =
520 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"
521− goSimple (CtorConflictsWithClass nm) =
504+ renderSimpleErrorMessage (CtorConflictsWithClass nm) =
522 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"
523− goSimple (ClassConflictsWithType nm) =
506+ renderSimpleErrorMessage (ClassConflictsWithType nm) =
524 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"
525− goSimple (ClassConflictsWithCtor nm) =
508+ renderSimpleErrorMessage (ClassConflictsWithCtor nm) =
526 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."
527− goSimple (DuplicateClassExport nm) =
512+ renderSimpleErrorMessage (DuplicateClassExport nm) =
528 line $ "Duplicate export declaration for type class " ++ runProperName nm
513 line $ "Duplicate export declaration for type class " ++ runProperName nm
529− goSimple (DuplicateValueExport nm) =
514+ renderSimpleErrorMessage (DuplicateValueExport nm) =
530 line $ "Duplicate export declaration for value " ++ showIdent nm
515 line $ "Duplicate export declaration for value " ++ showIdent nm
531− goSimple (CycleInDeclaration nm) =
516+ renderSimpleErrorMessage (CycleInDeclaration nm) =
532 line $ "Cycle in declaration of " ++ showIdent nm
517 line $ "Cycle in declaration of " ++ showIdent nm
533− goSimple (CycleInModules mns) =
518+ renderSimpleErrorMessage (CycleInModules mns) =
534 line $ "Cycle in module dependencies: " ++ intercalate ", " (map runModuleName mns)
519 line $ "Cycle in module dependencies: " ++ intercalate ", " (map runModuleName mns)
535− goSimple (CycleInTypeSynonym pn) =
520+ renderSimpleErrorMessage (CycleInTypeSynonym pn) =
536 line $ "Cycle in type synonym" ++ foldMap ((" " ++) . runProperName) pn
521 line $ "Cycle in type synonym" ++ foldMap ((" " ++) . runProperName) pn
537− goSimple (NameIsUndefined ident) =
522+ renderSimpleErrorMessage (NameIsUndefined ident) =
538 line $ showIdent ident ++ " is undefined"
523 line $ showIdent ident ++ " is undefined"
539− goSimple (NameNotInScope ident) =
524+ renderSimpleErrorMessage (NameNotInScope ident) =
540 line $ showIdent ident ++ " may not be defined in the current scope"
525 line $ showIdent ident ++ " may not be defined in the current scope"
541− goSimple (UndefinedTypeVariable name) =
526+ renderSimpleErrorMessage (UndefinedTypeVariable name) =
542 line $ "Type variable " ++ runProperName name ++ " is undefined"
527 line $ "Type variable " ++ runProperName name ++ " is undefined"
543− goSimple (PartiallyAppliedSynonym name) =
528+ renderSimpleErrorMessage (PartiallyAppliedSynonym name) =
544 paras [ line $ "Partially applied type synonym " ++ showQualified runProperName name
529 paras [ line $ "Partially applied type synonym " ++ showQualified runProperName name
545 , 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."
546 ]
531 ]
547− goSimple (EscapedSkolem binding) =
532+ renderSimpleErrorMessage (EscapedSkolem binding) =
548 paras $ [ line "A type variable has escaped its scope." ]
533 paras $ [ line "A type variable has escaped its scope." ]
549 <> foldMap (\expr -> [ line "Relevant expression: "
534 <> foldMap (\expr -> [ line "Relevant expression: "
550− , indent $ line $ prettyPrintValue expr
535+ , indent $ prettyPrintValue expr
551 ]) binding
536 ]) binding
552− goSimple (TypesDoNotUnify t1 t2)
537+ renderSimpleErrorMessage (TypesDoNotUnify t1 t2)
553 = paras [ line "Cannot unify type"
538 = paras [ line "Cannot unify type"
554− , indent $ line $ prettyPrintType t1
539+ , indent $ typeAsBox t1
555 , line "with type"
540 , line "with type"
556− , indent $ line $ prettyPrintType t2
541+ , indent $ typeAsBox t2
557 ]
542 ]
558− goSimple (KindsDoNotUnify k1 k2) =
543+ renderSimpleErrorMessage (KindsDoNotUnify k1 k2) =
559 paras [ line "Cannot unify kind"
544 paras [ line "Cannot unify kind"
560− , indent $ line $ prettyPrintKind k1
545+ , indent $ kindAsBox k1
561 , line "with kind"
546 , line "with kind"
562− , indent $ line $ prettyPrintKind k2
547+ , indent $ kindAsBox k2
563 ]
548 ]
564− goSimple (ConstrainedTypeUnified t1 t2) =
549+ renderSimpleErrorMessage (ConstrainedTypeUnified t1 t2) =
565 paras [ line "Cannot unify constrained type"
550 paras [ line "Cannot unify constrained type"
566− , indent $ line $ prettyPrintType t1
551+ , indent $ typeAsBox t1
567 , line "with type"
552 , line "with type"
568− , indent $ line $ prettyPrintType t2
553+ , indent $ typeAsBox t2
569− ]
554+ ]
570− goSimple (OverlappingInstances nm ts (d : ds)) =
555+ renderSimpleErrorMessage (OverlappingInstances nm ts (d : ds)) =
571− 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:"
572 , 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)
573 ]
562 ]
574− goSimple OverlappingInstances{} = error "OverlappingInstances: empty instance list"
563+ renderSimpleErrorMessage OverlappingInstances{} = error "OverlappingInstances: empty instance list"
575− goSimple (NoInstanceFound nm ts) =
564+ renderSimpleErrorMessage (NoInstanceFound nm ts) =
576− 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+ ]
577− goSimple (PossiblyInfiniteInstance nm ts) =
570+ renderSimpleErrorMessage (PossiblyInfiniteInstance nm ts) =
578− 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+ ]
579− goSimple (CannotDerive nm ts) =
577+ renderSimpleErrorMessage (CannotDerive nm ts) =
580− 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+ ]
581− goSimple (CannotFindDerivingType nm) =
583+ renderSimpleErrorMessage (CannotFindDerivingType nm) =
582 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."
583− goSimple (DuplicateLabel l expr) =
585+ renderSimpleErrorMessage (DuplicateLabel l expr) =
584 paras $ [ line $ "Duplicate label " ++ show l ++ " in row." ]
586 paras $ [ line $ "Duplicate label " ++ show l ++ " in row." ]
585 <> foldMap (\expr' -> [ line "Relevant expression: "
587 <> foldMap (\expr' -> [ line "Relevant expression: "
586− , indent $ line $ prettyPrintValue expr'
588+ , indent $ prettyPrintValue expr'
587 ]) expr
589 ]) expr
588− goSimple (DuplicateTypeArgument name) =
590+ renderSimpleErrorMessage (DuplicateTypeArgument name) =
589 line $ "Duplicate type argument " ++ show name
591 line $ "Duplicate type argument " ++ show name
590− goSimple (DuplicateValueDeclaration nm) =
592+ renderSimpleErrorMessage (DuplicateValueDeclaration nm) =
591 line $ "Duplicate value declaration for " ++ showIdent nm
593 line $ "Duplicate value declaration for " ++ showIdent nm
592− goSimple (ArgListLengthsDiffer ident) =
594+ renderSimpleErrorMessage (ArgListLengthsDiffer ident) =
593 line $ "Argument list lengths differ in declaration " ++ showIdent ident
595 line $ "Argument list lengths differ in declaration " ++ showIdent ident
594− goSimple (OverlappingArgNames ident) =
596+ renderSimpleErrorMessage (OverlappingArgNames ident) =
595 line $ "Overlapping names in function/binder" ++ foldMap ((" in declaration" ++) . showIdent) ident
597 line $ "Overlapping names in function/binder" ++ foldMap ((" in declaration" ++) . showIdent) ident
596− goSimple (MissingClassMember ident) =
598+ renderSimpleErrorMessage (MissingClassMember ident) =
597 line $ "Member " ++ showIdent ident ++ " has not been implemented"
599 line $ "Member " ++ showIdent ident ++ " has not been implemented"
598− goSimple (ExtraneousClassMember ident) =
600+ renderSimpleErrorMessage (ExtraneousClassMember ident) =
599 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"
600− goSimple (ExpectedType ty kind) =
602+ renderSimpleErrorMessage (ExpectedType ty kind) =
601 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 *."
602− , 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 $ kindAsBox kind
608+ , line "instead."
603 ]
609 ]
604− goSimple (IncorrectConstructorArity nm) =
610+ renderSimpleErrorMessage (IncorrectConstructorArity nm) =
605 line $ "Wrong number of arguments to constructor " ++ showQualified runProperName nm
611 line $ "Wrong number of arguments to constructor " ++ showQualified runProperName nm
606− goSimple SubsumptionCheckFailed = line "Unable to check type subsumption"
612+ renderSimpleErrorMessage SubsumptionCheckFailed = line "Unable to check type subsumption"
607− goSimple (ExprDoesNotHaveType expr ty) =
613+ renderSimpleErrorMessage (ExprDoesNotHaveType expr ty) =
608 paras [ line "Expression"
614 paras [ line "Expression"
609− , indent $ line $ prettyPrintValue expr
615+ , indent $ prettyPrintValue expr
610 , line "does not have type"
616 , line "does not have type"
611− , indent $ line $ prettyPrintType ty
617+ , indent $ typeAsBox ty
612 ]
618 ]
613− goSimple (PropertyIsMissing prop row) =
619+ renderSimpleErrorMessage (PropertyIsMissing prop row) =
620+ paras [ line "Row"
621+ , indent $ prettyPrintRowWith '(' ')' row
614− line $ "Row " ++ prettyPrintRow row ++ " lacks required property " ++ show prop
622+ , line $ "lacks required property " ++ show prop
623+ ]
615− goSimple (CannotApplyFunction fn arg) =
624+ renderSimpleErrorMessage (CannotApplyFunction fn arg) =
616 paras [ line "Cannot apply function of type"
625 paras [ line "Cannot apply function of type"
617− , indent $ line $ prettyPrintType fn
626+ , indent $ typeAsBox fn
618 , line "to argument"
627 , line "to argument"
619− , indent $ line $ prettyPrintValue arg
628+ , indent $ prettyPrintValue arg
620 ]
629 ]
621− goSimple TypeSynonymInstance =
630+ renderSimpleErrorMessage TypeSynonymInstance =
622 line "Type synonym instances are disallowed"
631 line "Type synonym instances are disallowed"
623− goSimple (OrphanInstance nm cnm ts) =
632+ renderSimpleErrorMessage (OrphanInstance nm cnm ts) =
624− 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."
625 , 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."
626 , 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."
627 ]
640 ]
628− goSimple InvalidNewtype =
641+ renderSimpleErrorMessage InvalidNewtype =
629 line "Newtypes must define a single constructor with a single argument"
642 line "Newtypes must define a single constructor with a single argument"
630− goSimple (InvalidInstanceHead ty) =
643+ renderSimpleErrorMessage (InvalidInstanceHead ty) =
631 paras [ line "Invalid type in class instance head:"
644 paras [ line "Invalid type in class instance head:"
632− , indent $ line $ prettyPrintType ty
645+ , indent $ typeAsBox ty
633 ]
646 ]
634− goSimple (TransitiveExportError x ys) =
647+ renderSimpleErrorMessage (TransitiveExportError x ys) =
635 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: ")
636 : map (line . prettyPrintExport) ys
649 : map (line . prettyPrintExport) ys
637− goSimple (ShadowedName nm) =
650+ renderSimpleErrorMessage (ShadowedName nm) =
638 line $ "Name '" ++ showIdent nm ++ "' was shadowed"
651 line $ "Name '" ++ showIdent nm ++ "' was shadowed"
639− goSimple (ShadowedTypeVar tv) =
652+ renderSimpleErrorMessage (ShadowedTypeVar tv) =
640 line $ "Type variable '" ++ tv ++ "' was shadowed"
653 line $ "Type variable '" ++ tv ++ "' was shadowed"
641− goSimple (UnusedTypeVar tv) =
654+ renderSimpleErrorMessage (UnusedTypeVar tv) =
642 line $ "Type variable '" ++ tv ++ "' was declared but not used"
655 line $ "Type variable '" ++ tv ++ "' was declared but not used"
643− goSimple (ClassOperator className opName) =
656+ renderSimpleErrorMessage (ClassOperator className opName) =
644 paras [ line $ "Class '" ++ runProperName className ++ "' declares operator " ++ showIdent opName ++ "."
657 paras [ line $ "Class '" ++ runProperName className ++ "' declares operator " ++ showIdent opName ++ "."
645− , 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:"
646− , indent $ line $ showIdent opName ++ " = someMember"
659+ , indent . line $ showIdent opName ++ " = someMember"
647 ]
660 ]
648− goSimple (MisleadingEmptyTypeImport mn name) =
661+ renderSimpleErrorMessage (MisleadingEmptyTypeImport mn name) =
649 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"
650− goSimple (ImportHidingModule name) =
663+ renderSimpleErrorMessage (ImportHidingModule name) =
651 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"
652− goSimple (WildcardInferredType ty) =
665+ renderSimpleErrorMessage (WildcardInferredType ty) =
653− 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+ ]
654− goSimple (NotExhaustivePattern bs b) =
675+ renderSimpleErrorMessage (NotExhaustivePattern bs b) =
655 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."
656 , 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"
657 , 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))
658 ] ++
679 ] ++
659 [ line "..." | not b ]
680 [ line "..." | not b ]
660− goSimple (OverlappingPattern bs b) =
681+ renderSimpleErrorMessage (OverlappingPattern bs b) =
661 paras $ [ line "A case expression contains unreachable cases:\n"
682 paras $ [ line "A case expression contains unreachable cases:\n"
662 , 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))
663 ] ++
684 ] ++
664 [ line "..." | not b ]
685 [ line "..." | not b ]
665− go (NotYetDefined names err) =
686+ renderSimpleErrorMessage IncompleteExhaustivityCheck =
666− paras [ line $ "The following are not yet defined here: " ++ intercalate ", " (map showIdent names) ++ ":"
687+ paras [ line "An exhaustivity check was abandoned due to too many possible cases."
667− , indent $ go err
688+ , line "You may want to decomposing your data types into smaller types."
668 ]
689 ]
690+
691+ renderHint :: ErrorMessageHint -> Box.Box
692+ renderHint (NotYetDefined names) =
693+ line $ "The following are not yet defined here: " ++ intercalate ", " (map showIdent names) ++ ":"
669− go (ErrorUnifyingTypes t1 t2 err) =
694+ renderHint (ErrorUnifyingTypes t1 t2) =
670 paras [ lineWithLevel "unifying type "
695 paras [ lineWithLevel "unifying type "
671− , indent $ line $ prettyPrintType t1
696+ , indent $ typeAsBox t1
672 , line "with type"
697 , line "with type"
673− , indent $ line $ prettyPrintType t2
698+ , indent $ typeAsBox t2
674− , go err
675 ]
699 ]
676− go (ErrorInExpression expr err) =
700+ renderHint (ErrorInExpression expr) =
677 paras [ lineWithLevel "in expression:"
701 paras [ lineWithLevel "in expression:"
678− , indent $ line $ prettyPrintValue expr
702+ , indent $ prettyPrintValue expr
679− , go err
680 ]
703 ]
681− go (ErrorInModule mn err) =
704+ renderHint (ErrorInModule mn) =
682 paras [ lineWithLevel $ "in module " ++ runModuleName mn ++ ":"
705 paras [ lineWithLevel $ "in module " ++ runModuleName mn ++ ":"
683− , go err
684 ]
706 ]
685− go (ErrorInSubsumption t1 t2 err) =
707+ renderHint (ErrorInSubsumption t1 t2) =
686 paras [ lineWithLevel "checking that type "
708 paras [ lineWithLevel "checking that type "
687− , indent $ line $ prettyPrintType t1
709+ , indent $ typeAsBox t1
688 , line "subsumes type"
710 , line "subsumes type"
689− , indent $ line $ prettyPrintType t2
711+ , indent $ typeAsBox t2
690− , go err
691 ]
712 ]
692− go (ErrorInInstance name ts err) =
713+ renderHint (ErrorInInstance nm ts) =
693− paras [ lineWithLevel $ "in type class instance " ++ showQualified runProperName name ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ ":"
714+ paras [ lineWithLevel "in type class instance"
694− , go err
715+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
716+ , Box.vcat Box.left (map typeAtomAsBox ts)
717+ ]
695 ]
718 ]
696− go (ErrorCheckingKind ty err) =
719+ renderHint (ErrorCheckingKind ty) =
697 paras [ lineWithLevel "checking kind of type "
720 paras [ lineWithLevel "checking kind of type "
698− , indent $ line $ prettyPrintType ty
721+ , indent $ typeAsBox ty
699− , go err
700 ]
722 ]
701− go (ErrorInferringType expr err) =
723+ renderHint (ErrorInferringType expr) =
702 paras [ lineWithLevel "inferring type of value "
724 paras [ lineWithLevel "inferring type of value "
703− , indent $ line $ prettyPrintValue expr
725+ , indent $ prettyPrintValue expr
704− , go err
705 ]
726 ]
706− go (ErrorCheckingType expr ty err) =
727+ renderHint (ErrorCheckingType expr ty) =
707 paras [ lineWithLevel "checking that value "
728 paras [ lineWithLevel "checking that value "
708− , indent $ line $ prettyPrintValue expr
729+ , indent $ prettyPrintValue expr
709 , line "has type"
730 , line "has type"
710− , indent $ line $ prettyPrintType ty
731+ , indent $ typeAsBox ty
711− , go err
712 ]
732 ]
713− go (ErrorInApplication f t a err) =
733+ renderHint (ErrorInApplication f t a) =
714 paras [ lineWithLevel "applying function"
734 paras [ lineWithLevel "applying function"
715− , indent $ line $ prettyPrintValue f
735+ , indent $ prettyPrintValue f
716 , line "of type"
736 , line "of type"
717− , indent $ line $ prettyPrintType t
737+ , indent $ typeAsBox t
718 , line "to argument"
738 , line "to argument"
719− , indent $ line $ prettyPrintValue a
739+ , indent $ prettyPrintValue a
720− , go err
721− ]
740+ ]
722− go (ErrorInDataConstructor nm err) =
741+ renderHint (ErrorInDataConstructor nm) =
723− paras [ lineWithLevel $ "in data constructor " ++ runProperName nm ++ ":"
742+ lineWithLevel $ "in data constructor " ++ runProperName nm ++ ":"
724− , go err
725− ]
726− go (ErrorInTypeConstructor nm err) =
743+ renderHint (ErrorInTypeConstructor nm) =
727− paras [ lineWithLevel $ "in type constructor " ++ runProperName nm ++ ":"
744+ lineWithLevel $ "in type constructor " ++ runProperName nm ++ ":"
728− , go err
729− ]
730− go (ErrorInBindingGroup nms err) =
745+ renderHint (ErrorInBindingGroup nms) =
731− paras [ lineWithLevel $ "in binding group " ++ intercalate ", " (map showIdent nms) ++ ":"
746+ lineWithLevel $ "in binding group " ++ intercalate ", " (map showIdent nms) ++ ":"
732− , go err
733− ]
734− go (ErrorInDataBindingGroup err) =
747+ renderHint ErrorInDataBindingGroup =
735− paras [ lineWithLevel $ "in data binding group:"
748+ lineWithLevel "in data binding group:"
736− , go err
737− ]
738− go (ErrorInTypeSynonym name err) =
749+ renderHint (ErrorInTypeSynonym name) =
739− paras [ lineWithLevel $ "in type synonym " ++ runProperName name ++ ":"
750+ lineWithLevel $ "in type synonym " ++ runProperName name ++ ":"
740− , go err
741− ]
742− go (ErrorInValueDeclaration n err) =
751+ renderHint (ErrorInValueDeclaration n) =
743− paras [ lineWithLevel $ "in value declaration " ++ showIdent n ++ ":"
752+ lineWithLevel $ "in value declaration " ++ showIdent n ++ ":"
744− , go err
745− ]
746− go (ErrorInTypeDeclaration n err) =
753+ renderHint (ErrorInTypeDeclaration n) =
747− paras [ lineWithLevel $ "in type declaration for " ++ showIdent n ++ ":"
754+ lineWithLevel $ "in type declaration for " ++ showIdent n ++ ":"
748− , go err
749− ]
750− go (ErrorInForeignImport nm err) =
755+ renderHint (ErrorInForeignImport nm) =
751− paras [ lineWithLevel $ "in foreign import " ++ showIdent nm ++ ":"
756+ lineWithLevel $ "in foreign import " ++ showIdent nm ++ ":"
752− , go err
753− ]
754− go (PositionedError srcSpan err) =
757+ renderHint (PositionedError srcSpan) =
755− paras [ lineWithLevel $ "at " ++ displaySourceSpan srcSpan ++ ":"
758+ lineWithLevel $ "at " ++ displaySourceSpan srcSpan ++ ":"
756− , indent $ go err
757− ]
758− go (SimpleErrorWrapper sem) = goSimple sem
759
759
760 lineWithLevel :: String -> Box.Box
760 lineWithLevel :: String -> Box.Box
761 lineWithLevel text = line $ show level ++ " " ++ text
761 lineWithLevel text = line $ show level ++ " " ++ text
@@ -765,23 +765,19 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
765 Error -> "error"
765 Error -> "error"
766 Warning -> "warning"
766 Warning -> "warning"
767
767
768− suggestions :: ErrorMessage -> [Box.Box]
768+ suggestions :: SimpleErrorMessage -> [Box.Box]
769− suggestions = suggestions' . unwrapErrorMessage
770− where
771− 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 ++ ":"
772 , indent . line $ "import " ++ runModuleName im ++ " hiding (" ++ nm ++ ")"
770 , indent . line $ "import " ++ runModuleName im ++ " hiding (" ++ nm ++ ")"
773 ]
771 ]
774− suggestions' (TypesDoNotUnify t1 t2)
772+ suggestions (TypesDoNotUnify t1 t2)
775− | 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 (<<<)"]
776− | otherwise = []
774+ | otherwise = []
777− suggestions' _ = []
775+ suggestions _ = []
778
776
779 paras :: [Box.Box] -> Box.Box
777 paras :: [Box.Box] -> Box.Box
780 paras = Box.vcat Box.left
778 paras = Box.vcat Box.left
781
779
782− -- |
783 -- Pretty print and export declaration
780 -- Pretty print and export declaration
784− --
785 prettyPrintExport :: DeclarationRef -> String
781 prettyPrintExport :: DeclarationRef -> String
786 prettyPrintExport (TypeRef pn _) = runProperName pn
782 prettyPrintExport (TypeRef pn _) = runProperName pn
787 prettyPrintExport (ValueRef ident) = showIdent ident
783 prettyPrintExport (ValueRef ident) = showIdent ident
@@ -790,38 +786,44 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
790 prettyPrintExport (ModuleRef name) = "module " ++ runModuleName name
786 prettyPrintExport (ModuleRef name) = "module " ++ runModuleName name
791 prettyPrintExport (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
787 prettyPrintExport (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
792
788
793− -- |
789+ -- Hints get added at the front, so we need to reverse them before rendering
794− -- Simplify an error message
790+ reverseHints :: ErrorMessage -> ErrorMessage
795− --
791+ reverseHints (ErrorMessage hints simple) = ErrorMessage (reverse hints) simple
792+
793+ -- | Put positional hints at the front of the list
796− simplifyErrorMessage :: ErrorMessage -> ErrorMessage
794+ positionHintsFirst :: ErrorMessage -> ErrorMessage
797− simplifyErrorMessage = unwrap Nothing
795+ positionHintsFirst (ErrorMessage hints simple) = ErrorMessage (uncurry (++) $ partition (isPositionHint . hintCategory) hints) simple
798 where
796 where
799− unwrap :: Maybe SourceSpan -> ErrorMessage -> ErrorMessage
797+ isPositionHint :: HintCategory -> Bool
800− unwrap pos (ErrorInExpression _ err) = unwrap pos err
798+ isPositionHint PositionHint = True
801− unwrap pos (ErrorInInstance name ts err) = ErrorInInstance name ts (unwrap pos err)
799+ isPositionHint OtherHint = True
802− unwrap pos (ErrorInSubsumption t1 t2 err) = ErrorInSubsumption t1 t2 (unwrap pos err)
800+ isPositionHint _ = False
803− unwrap pos (ErrorUnifyingTypes _ _ err) = unwrap pos err
804− unwrap pos (ErrorInferringType _ err) = unwrap pos err
805− unwrap pos (ErrorCheckingType _ _ err) = unwrap pos err
806− unwrap pos (ErrorCheckingKind ty err) = ErrorCheckingKind ty (unwrap pos err)
807− unwrap pos (ErrorInModule mn err) = ErrorInModule mn (unwrap pos err)
808− unwrap pos (ErrorInApplication _ _ _ err) = unwrap pos err
809− unwrap pos (ErrorInDataConstructor nm err) = ErrorInDataConstructor nm (unwrap pos err)
810− unwrap pos (ErrorInTypeConstructor nm err) = ErrorInTypeConstructor nm (unwrap pos err)
811− unwrap pos (ErrorInBindingGroup nms err) = ErrorInBindingGroup nms (unwrap pos err)
812− unwrap pos (ErrorInDataBindingGroup err) = ErrorInDataBindingGroup (unwrap pos err)
813− unwrap pos (ErrorInTypeSynonym nm err) = ErrorInTypeSynonym nm (unwrap pos err)
814− unwrap pos (ErrorInValueDeclaration nm err) = ErrorInValueDeclaration nm (unwrap pos err)
815− unwrap pos (ErrorInTypeDeclaration nm err) = ErrorInTypeDeclaration nm (unwrap pos err)
816− unwrap pos (ErrorInForeignImport nm err) = ErrorInForeignImport nm (unwrap pos err)
817− unwrap pos (NotYetDefined ns err) = NotYetDefined ns (unwrap pos err)
818− unwrap _ (PositionedError pos err) = unwrap (Just pos) err
819− unwrap pos other = wrap pos other
820−
821− wrap :: Maybe SourceSpan -> ErrorMessage -> ErrorMessage
822− wrap Nothing = id
823− wrap (Just pos) = PositionedError pos
824
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
825
827
826-- |
828-- |
827-- Pretty print multiple errors
829-- Pretty print multiple errors
@@ -837,11 +839,11 @@ prettyPrintMultipleWarnings full = renderBox . prettyPrintMultipleWarningsBox fu
837
839
838-- | Pretty print warnings as a Box
840-- | Pretty print warnings as a Box
839prettyPrintMultipleWarningsBox :: Bool -> MultipleErrors -> Box.Box
841prettyPrintMultipleWarningsBox :: Bool -> MultipleErrors -> Box.Box
840−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
841
843
842-- | Pretty print errors as a Box
844-- | Pretty print errors as a Box
843prettyPrintMultipleErrorsBox :: Bool -> MultipleErrors -> Box.Box
845prettyPrintMultipleErrorsBox :: Bool -> MultipleErrors -> Box.Box
844−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
845
847
846prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> State UnknownMap Box.Box
848prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> State UnknownMap Box.Box
847prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
849prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
@@ -851,15 +853,16 @@ prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
851 , result
853 , result
852 ]
854 ]
853prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) = do
855prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) = do
854− result <- forM es $ (liftM $ Box.moveRight 2) . prettyPrintSingleError full level
856+ result <- forM es $ prettyPrintSingleError full level
855− return $
857+ return $ Box.vsep 1 Box.left $ concat $ zipWith withIntro [1 :: Int ..] result
856− Box.vcat Box.left [ Box.text intro
858+ where
857− , Box.vsep 1 Box.left result
859+ withIntro i err = [ Box.text (intro ++ " " ++ show i ++ " of " ++ show (length es) ++ ":")
860+ , Box.moveRight 2 err
858− ]
861+ ]
859
862
860-- | Pretty print a Parsec ParseError as a Box
863-- | Pretty print a Parsec ParseError as a Box
861prettyPrintParseError :: P.ParseError -> Box.Box
864prettyPrintParseError :: P.ParseError -> Box.Box
862−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
863
866
864-- |
867-- |
865-- Pretty print ParseError detail messages.
868-- Pretty print ParseError detail messages.
@@ -872,9 +875,9 @@ prettyPrintParseErrorMessages msgOr msgUnknown msgExpecting msgUnExpected msgEnd
872 | 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]
873
876
874 where
877 where
875− (sysUnExpect,msgs1) = span ((SysUnExpect "") ==) msgs
878+ (sysUnExpect,msgs1) = span (SysUnExpect "" ==) msgs
876− (unExpect,msgs2) = span ((UnExpect "") ==) msgs1
879+ (unExpect,msgs2) = span (UnExpect "" ==) msgs1
877− (expect,messages) = span ((Expect "") ==) msgs2
880+ (expect,messages) = span (Expect "" ==) msgs2
878
881
879 showExpect = showMany msgExpecting expect
882 showExpect = showMany msgExpecting expect
880 showUnExpect = showMany msgUnExpected unExpect
883 showUnExpect = showMany msgUnExpected unExpect
@@ -905,8 +908,9 @@ prettyPrintParseErrorMessages msgOr msgUnknown msgExpecting msgUnExpected msgEnd
905
908
906 clean = nub . filter (not . null)
909 clean = nub . filter (not . null)
907
910
911+-- | Indent to the right, and pad on top and bottom.
908indent :: Box.Box -> Box.Box
912indent :: Box.Box -> Box.Box
909−indent = Box.moveRight 2
913+indent = Box.moveUp 1 . Box.moveDown 1 . Box.moveRight 2
910
914
911line :: String -> Box.Box
915line :: String -> Box.Box
912line = Box.text
916line = Box.text
@@ -922,7 +926,7 @@ renderBox = unlines . map trimEnd . lines . Box.render
922interpretMultipleErrorsAndWarnings :: (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
923interpretMultipleErrorsAndWarnings (err, ws) = do
927interpretMultipleErrorsAndWarnings (err, ws) = do
924 tell ws
928 tell ws
925− either throwError return $ err
929+ either throwError return err
926
930
927-- |
931-- |
928-- 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
@@ -946,8 +950,7 @@ warnAndRethrowWithPosition :: (MonadError MultipleErrors m, MonadWriter Multiple
946warnAndRethrowWithPosition pos = rethrowWithPosition pos . warnWithPosition pos
950warnAndRethrowWithPosition pos = rethrowWithPosition pos . warnWithPosition pos
947
951
948withPosition :: SourceSpan -> ErrorMessage -> ErrorMessage
952withPosition :: SourceSpan -> ErrorMessage -> ErrorMessage
949−withPosition _ (PositionedError pos err) = withPosition pos err
953+withPosition pos (ErrorMessage hints se) = ErrorMessage (PositionedError pos : hints) se
950−withPosition pos err = PositionedError pos err
951
954
952-- |
955-- |
953-- Collect errors in in parallel
956-- Collect errors in in parallel
src/Language/PureScript/Linter.hs+4−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)
src/Language/PureScript/Linter/Exhaustive.hs+74−47
@@ -29,6 +29,9 @@ import qualified Data.Map as M
29import Data.Maybe (fromMaybe)
29import Data.Maybe (fromMaybe)
30import Data.List (foldl', sortBy, nub)
30import Data.List (foldl', sortBy, nub)
31import Data.Function (on)
31import Data.Function (on)
32+#if __GLASGOW_HASKELL__ < 710
33+import Data.Traversable (sequenceA)
34+#endif
32
35
33import Control.Monad (unless)
36import Control.Monad (unless)
34import Control.Applicative
37import Control.Applicative
@@ -43,7 +46,13 @@ import Language.PureScript.Kinds
43import Language.PureScript.Types as P
46import Language.PureScript.Types as P
44import Language.PureScript.Errors
47import Language.PureScript.Errors
45
48
46−import Language.PureScript.AST.Traversals (everywhereOnValuesTopDownM)
49+-- | There are two modes of failure for the redudancy check:
50+--
51+-- 1. Exhaustivity was incomeplete due to too many cases, so we couldn't determine redundancy.
52+-- 2. We didn't attempt to determine redundancy for a binder, e.g. an integer binder.
53+--
54+-- We want to warn the user in the first case.
55+data RedudancyError = Incomplete | Unknown
47
56
48-- |
57-- |
49-- Qualifies a propername from a given qualified propername and a default module name
58-- Qualifies a propername from a given qualified propername and a default module name
@@ -59,20 +68,20 @@ qualifyName n defmn qn = Qualified (Just mn) n
59-- where: - ProperName is the name of the constructor (for example, "Nothing" in Maybe)
68-- where: - ProperName is the name of the constructor (for example, "Nothing" in Maybe)
60-- - [Type] is the list of arguments, if it has (for example, "Just" has [TypeVar "a"])
69-- - [Type] is the list of arguments, if it has (for example, "Just" has [TypeVar "a"])
61--
70--
62−getConstructors :: Environment -> ModuleName -> (Qualified ProperName) -> [(ProperName, [Type])]
71+getConstructors :: Environment -> ModuleName -> Qualified ProperName -> [(ProperName, [Type])]
63getConstructors env defmn n = extractConstructors lnte
72getConstructors env defmn n = extractConstructors lnte
64 where
73 where
65 qpn :: Qualified ProperName
74 qpn :: Qualified ProperName
66 qpn = getConsDataName n
75 qpn = getConsDataName n
67
76
68− getConsDataName :: (Qualified ProperName) -> (Qualified ProperName)
77+ getConsDataName :: Qualified ProperName -> Qualified ProperName
69 getConsDataName con = qualifyName nm defmn con
78 getConsDataName con = qualifyName nm defmn con
70 where
79 where
71 nm = case getConsInfo con of
80 nm = case getConsInfo con of
72 Nothing -> error $ "Constructor " ++ showQualified runProperName con ++ " not in the scope of the current environment in getConsDataName."
81 Nothing -> error $ "Constructor " ++ showQualified runProperName con ++ " not in the scope of the current environment in getConsDataName."
73 Just (_, pm, _, _) -> pm
82 Just (_, pm, _, _) -> pm
74
83
75− getConsInfo :: (Qualified ProperName) -> Maybe (DataDeclType, ProperName, Type, [Ident])
84+ getConsInfo :: Qualified ProperName -> Maybe (DataDeclType, ProperName, Type, [Ident])
76 getConsInfo con = M.lookup con dce
85 getConsInfo con = M.lookup con dce
77 where
86 where
78 dce :: M.Map (Qualified ProperName) (DataDeclType, ProperName, Type, [Ident])
87 dce :: M.Map (Qualified ProperName) (DataDeclType, ProperName, Type, [Ident])
@@ -103,27 +112,27 @@ genericMerge _ [] [] = []
103genericMerge f bs [] = map (\(s, b) -> f s (Just b) Nothing) bs
112genericMerge f bs [] = map (\(s, b) -> f s (Just b) Nothing) bs
104genericMerge f [] bs = map (\(s, b) -> f s Nothing (Just b)) bs
113genericMerge f [] bs = map (\(s, b) -> f s Nothing (Just b)) bs
105genericMerge f bsl@((s, b):bs) bsr@((s', b'):bs')
114genericMerge f bsl@((s, b):bs) bsr@((s', b'):bs')
106− | s < s' = (f s (Just b) Nothing) : genericMerge f bs bsr
115+ | s < s' = f s (Just b) Nothing : genericMerge f bs bsr
107− | s > s' = (f s' Nothing (Just b')) : genericMerge f bsl bs'
116+ | s > s' = f s' Nothing (Just b') : genericMerge f bsl bs'
108− | otherwise = (f s (Just b) (Just b')) : genericMerge f bs bs'
117+ | otherwise = f s (Just b) (Just b') : genericMerge f bs bs'
109
118
110-- |
119-- |
111-- Find the uncovered set between two binders:
120-- Find the uncovered set between two binders:
112-- the first binder is the case we are trying to cover, the second one is the matching binder
121-- the first binder is the case we are trying to cover, the second one is the matching binder
113--
122--
114−missingCasesSingle :: Environment -> ModuleName -> Binder -> Binder -> ([Binder], Maybe Bool)
123+missingCasesSingle :: Environment -> ModuleName -> Binder -> Binder -> ([Binder], Either RedudancyError Bool)
115−missingCasesSingle _ _ _ NullBinder = ([], Just True)
124+missingCasesSingle _ _ _ NullBinder = ([], return True)
116−missingCasesSingle _ _ _ (VarBinder _) = ([], Just True)
125+missingCasesSingle _ _ _ (VarBinder _) = ([], return True)
117missingCasesSingle env mn (VarBinder _) b = missingCasesSingle env mn NullBinder b
126missingCasesSingle env mn (VarBinder _) b = missingCasesSingle env mn NullBinder b
118missingCasesSingle env mn br (NamedBinder _ bl) = missingCasesSingle env mn br bl
127missingCasesSingle env mn br (NamedBinder _ bl) = missingCasesSingle env mn br bl
119missingCasesSingle env mn NullBinder cb@(ConstructorBinder con _) =
128missingCasesSingle env mn NullBinder cb@(ConstructorBinder con _) =
120− (concatMap (\cp -> fst $ missingCasesSingle env mn cp cb) allPatterns, Just True)
129+ (concatMap (\cp -> fst $ missingCasesSingle env mn cp cb) allPatterns, return True)
121 where
130 where
122 allPatterns = map (\(p, t) -> ConstructorBinder (qualifyName p mn con) (initialize $ length t))
131 allPatterns = map (\(p, t) -> ConstructorBinder (qualifyName p mn con) (initialize $ length t))
123 $ getConstructors env mn con
132 $ getConstructors env mn con
124missingCasesSingle env mn cb@(ConstructorBinder con bs) (ConstructorBinder con' bs')
133missingCasesSingle env mn cb@(ConstructorBinder con bs) (ConstructorBinder con' bs')
125 | con == con' = let (bs'', pr) = missingCasesMultiple env mn bs bs' in (map (ConstructorBinder con) bs'', pr)
134 | con == con' = let (bs'', pr) = missingCasesMultiple env mn bs bs' in (map (ConstructorBinder con) bs'', pr)
126− | otherwise = ([cb], Just False)
135+ | otherwise = ([cb], return False)
127missingCasesSingle env mn NullBinder (ObjectBinder bs) =
136missingCasesSingle env mn NullBinder (ObjectBinder bs) =
128 (map (ObjectBinder . zip (map fst bs)) allMisses, pr)
137 (map (ObjectBinder . zip (map fst bs)) allMisses, pr)
129 where
138 where
@@ -146,12 +155,12 @@ missingCasesSingle env mn (ObjectBinder bs) (ObjectBinder bs') =
146 compBS e s b b' = (s, compB e b b')
155 compBS e s b b' = (s, compB e b b')
147
156
148 (sortedNames, binders) = unzip $ genericMerge (compBS NullBinder) sbs sbs'
157 (sortedNames, binders) = unzip $ genericMerge (compBS NullBinder) sbs sbs'
149−missingCasesSingle _ _ NullBinder (BooleanBinder b) = ([BooleanBinder $ not b], Just True)
158+missingCasesSingle _ _ NullBinder (BooleanBinder b) = ([BooleanBinder $ not b], return True)
150missingCasesSingle _ _ (BooleanBinder bl) (BooleanBinder br)
159missingCasesSingle _ _ (BooleanBinder bl) (BooleanBinder br)
151− | bl == br = ([], Just True)
160+ | bl == br = ([], return True)
152− | otherwise = ([BooleanBinder bl], Just False)
161+ | otherwise = ([BooleanBinder bl], return False)
153missingCasesSingle env mn b (PositionedBinder _ _ cb) = missingCasesSingle env mn b cb
162missingCasesSingle env mn b (PositionedBinder _ _ cb) = missingCasesSingle env mn b cb
154−missingCasesSingle _ _ b _ = ([b], Nothing)
163+missingCasesSingle _ _ b _ = ([b], Left Unknown)
155
164
156-- |
165-- |
157-- Returns the uncovered set of binders
166-- Returns the uncovered set of binders
@@ -179,7 +188,7 @@ missingCasesSingle _ _ b _ = ([b], Nothing)
179-- redundant or not, but uncovered at least. If we use `y` instead, we'll need to have a redundancy checker
188-- redundant or not, but uncovered at least. If we use `y` instead, we'll need to have a redundancy checker
180-- (which ought to be available soon), or increase the complexity of the algorithm.
189-- (which ought to be available soon), or increase the complexity of the algorithm.
181--
190--
182−missingCasesMultiple :: Environment -> ModuleName -> [Binder] -> [Binder] -> ([[Binder]], Maybe Bool)
191+missingCasesMultiple :: Environment -> ModuleName -> [Binder] -> [Binder] -> ([[Binder]], Either RedudancyError Bool)
183missingCasesMultiple env mn = go
192missingCasesMultiple env mn = go
184 where
193 where
185 go [] [] = ([], pure True)
194 go [] [] = ([], pure True)
@@ -213,10 +222,10 @@ isExhaustiveGuard (Right _) = True
213-- |
222-- |
214-- Returns the uncovered set of case alternatives
223-- Returns the uncovered set of case alternatives
215--
224--
216−missingCases :: Environment -> ModuleName -> [Binder] -> CaseAlternative -> ([[Binder]], Maybe Bool)
225+missingCases :: Environment -> ModuleName -> [Binder] -> CaseAlternative -> ([[Binder]], Either RedudancyError Bool)
217missingCases env mn uncovered ca = missingCasesMultiple env mn uncovered (caseAlternativeBinders ca)
226missingCases env mn uncovered ca = missingCasesMultiple env mn uncovered (caseAlternativeBinders ca)
218
227
219−missingAlternative :: Environment -> ModuleName -> CaseAlternative -> [Binder] -> ([[Binder]], Maybe Bool)
228+missingAlternative :: Environment -> ModuleName -> CaseAlternative -> [Binder] -> ([[Binder]], Either RedudancyError Bool)
220missingAlternative env mn ca uncovered
229missingAlternative env mn ca uncovered
221 | isExhaustiveGuard (caseAlternativeResult ca) = mcases
230 | isExhaustiveGuard (caseAlternativeResult ca) = mcases
222 | otherwise = ([uncovered], snd mcases)
231 | otherwise = ([uncovered], snd mcases)
@@ -232,51 +241,69 @@ missingAlternative env mn ca uncovered
232checkExhaustive :: forall m. (MonadWriter MultipleErrors m) => Environment -> ModuleName -> Int -> [CaseAlternative] -> m ()
241checkExhaustive :: forall m. (MonadWriter MultipleErrors m) => Environment -> ModuleName -> Int -> [CaseAlternative] -> m ()
233checkExhaustive env mn numArgs cas = makeResult . first nub $ foldl' step ([initialize numArgs], (pure True, [])) cas
242checkExhaustive env mn numArgs cas = makeResult . first nub $ foldl' step ([initialize numArgs], (pure True, [])) cas
234 where
243 where
235− step :: ([[Binder]], (Maybe Bool, [[Binder]])) -> CaseAlternative -> ([[Binder]], (Maybe Bool, [[Binder]]))
244+ step :: ([[Binder]], (Either RedudancyError Bool, [[Binder]])) -> CaseAlternative -> ([[Binder]], (Either RedudancyError Bool, [[Binder]]))
236 step (uncovered, (nec, redundant)) ca =
245 step (uncovered, (nec, redundant)) ca =
237 let (missed, pr) = unzip (map (missingAlternative env mn ca) uncovered)
246 let (missed, pr) = unzip (map (missingAlternative env mn ca) uncovered)
247+ (missed', approx) = splitAt 10000 (concat missed)
238− cond = or <$> sequenceA pr
248+ cond = liftA2 (&&) (or <$> sequenceA pr) nec
239− in (concat missed, (liftA2 (&&) cond nec,
249+ in (missed', ( if null approx
250+ then cond
251+ else Left Incomplete
252+ , if either (const True) id cond
253+ then redundant
240− if fromMaybe True cond then redundant else caseAlternativeBinders ca : redundant))
254+ else caseAlternativeBinders ca : redundant
241−#if __GLASGOW_HASKELL__ < 710
255+ )
242− where
256+ )
243− sequenceA = foldr (liftA2 (:)) (pure [])
244−#endif
245
257
246− makeResult :: ([[Binder]], (Maybe Bool, [[Binder]])) -> m ()
258+ makeResult :: ([[Binder]], (Either RedudancyError Bool, [[Binder]])) -> m ()
247− makeResult (bss, (_, bss')) =
259+ makeResult (bss, (rr, bss')) =
248 do unless (null bss) tellExhaustive
260 do unless (null bss) tellExhaustive
249 unless (null bss') tellRedundant
261 unless (null bss') tellRedundant
262+ case rr of
263+ Left Incomplete -> tellIncomplete
264+ _ -> return ()
250 where
265 where
251 tellExhaustive = tell . errorMessage . uncurry NotExhaustivePattern . second null . splitAt 5 $ bss
266 tellExhaustive = tell . errorMessage . uncurry NotExhaustivePattern . second null . splitAt 5 $ bss
252 tellRedundant = tell . errorMessage . uncurry OverlappingPattern . second null . splitAt 5 $ bss'
267 tellRedundant = tell . errorMessage . uncurry OverlappingPattern . second null . splitAt 5 $ bss'
268+ tellIncomplete = tell . errorMessage $ IncompleteExhaustivityCheck
253
269
254-- |
270-- |
255-- Exhaustivity checking over a list of declarations
271-- Exhaustivity checking over a list of declarations
256--
272--
257checkExhaustiveDecls :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Environment -> ModuleName -> [Declaration] -> m ()
273checkExhaustiveDecls :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Environment -> ModuleName -> [Declaration] -> m ()
258−checkExhaustiveDecls env mn ds =
274+checkExhaustiveDecls env mn = mapM_ onDecl
259− let (f, _, _) = everywhereOnValuesTopDownM return checkExpr return
275+ where
276+ onDecl :: Declaration -> m ()
277+ onDecl (BindingGroupDeclaration bs) = mapM_ (onDecl . convert) bs
278+ where
279+ convert :: (Ident, NameKind, Expr) -> Declaration
280+ convert (name, nk, e) = ValueDeclaration name nk [] (Right e)
281+ onDecl (ValueDeclaration name _ _ (Right e)) = censor (addHint (ErrorInValueDeclaration name)) (onExpr e)
282+ onDecl (PositionedDeclaration pos _ dec) = censor (addHint (PositionedError pos)) (onDecl dec)
283+ onDecl _ = return ()
260
284
261− f' :: Declaration -> m Declaration
285+ onExpr :: Expr -> m ()
262− f' d@(BindingGroupDeclaration bs) = mapM_ (f' . convert) bs >> return d
286+ onExpr (UnaryMinus e) = onExpr e
263− where
287+ onExpr (ArrayLiteral es) = mapM_ onExpr es
264− convert :: (Ident, NameKind, Expr) -> Declaration
288+ onExpr (ObjectLiteral es) = mapM_ (onExpr . snd) es
265− convert (name, nk, e) = ValueDeclaration name nk [] (Right e)
289+ onExpr (TypeClassDictionaryConstructorApp _ e) = onExpr e
266− f' d@(ValueDeclaration name _ _ _) = censor (onErrorMessages (ErrorInValueDeclaration name)) $ f d
290+ onExpr (Accessor _ e) = onExpr e
267− f' (PositionedDeclaration pos com dec) = PositionedDeclaration pos com <$> censor (onErrorMessages (PositionedError pos)) (f' dec)
291+ onExpr (ObjectUpdate o es) = onExpr o >> mapM_ (onExpr . snd) es
268− -- Don't generate two warnings for desugared dictionaries.
292+ onExpr (Abs _ e) = onExpr e
269− f' d@TypeInstanceDeclaration{} = return d
293+ onExpr (App e1 e2) = onExpr e1 >> onExpr e2
270− f' d = f d
294+ onExpr (IfThenElse e1 e2 e3) = onExpr e1 >> onExpr e2 >> onExpr e3
295+ onExpr (Case es cas) = checkExhaustive env mn (length es) cas >> mapM_ onExpr es >> mapM_ onCaseAlternative cas
296+ onExpr (TypedValue _ e _) = onExpr e
297+ onExpr (Let ds e) = mapM_ onDecl ds >> onExpr e
298+ onExpr (PositionedValue pos _ e) = censor (addHint (PositionedError pos)) (onExpr e)
299+ onExpr _ = return ()
271
300
272− in mapM_ f' ds
301+ onCaseAlternative :: CaseAlternative -> m ()
273− where
302+ onCaseAlternative (CaseAlternative _ (Left es)) = mapM_ (\(e, g) -> onExpr e >> onExpr g) es
274− checkExpr :: Expr -> m Expr
303+ onCaseAlternative (CaseAlternative _ (Right e)) = onExpr e
275− checkExpr c@(Case expr cas) = checkExhaustive env mn (length expr) cas >> return c
276− checkExpr other = return other
277
304
278-- |
305-- |
279-- Exhaustivity checking over a single module
306-- Exhaustivity checking over a single module
280--
307--
281checkExhaustiveModule :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Environment -> Module -> m ()
308checkExhaustiveModule :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Environment -> Module -> m ()
282−checkExhaustiveModule env (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ checkExhaustiveDecls env mn ds
309+checkExhaustiveModule env (Module _ _ mn ds _) = censor (addHint (ErrorInModule mn)) $ checkExhaustiveDecls env mn ds
src/Language/PureScript/Make.hs+122−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,113 @@ 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+ externs <- sequence <$> for barriers (takeMVar . fst . snd)
170− let env = foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
180+ return $ foldl' (flip applyExternsFileToEnvironment) initEnvironment (fromMaybe (error "make: externs were missing but no errors reported.") externs)
171− evalSupplyT nextVar $ go env desugared
172− where
173
181
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
182 where
210− combine :: (Ord a) => [(a, b)] -> M.Map a [b]
183+ checkModuleNamesAreUnique :: m ()
211− combine = M.fromList . map ((fst . head) &&& map snd) . groupBy ((==) `on` fst) . sortBy (compare `on` fst)
184+ checkModuleNamesAreUnique =
185+ case findDuplicate (map getModuleName ms) of
186+ Nothing -> return ()
187+ Just mn -> throwError . errorMessage $ DuplicateModuleName mn
188+
189+ -- Verify that a list of values has unique keys
190+ findDuplicate :: (Ord a) => [a] -> Maybe a
191+ findDuplicate = go . sort
192+ where
193+ go (x : y : xs)
194+ | x == y = Just x
195+ | otherwise = go (y : xs)
196+ go _ = Nothing
197+
198+ -- Sort a list so its elements appear in the same order as in another list.
199+ inOrderOf :: (Ord a) => [a] -> [a] -> [a]
200+ inOrderOf xs ys = let s = S.fromList xs in filter (`S.member` s) ys
201+
202+ buildModule :: [(ModuleName, (C.MVar (Maybe ExternsFile), C.MVar (Maybe MultipleErrors)))] -> Module -> [ModuleName] -> m ()
203+ buildModule barriers m@(Module _ _ moduleName _ _) deps = flip catchError (markComplete Nothing . Just) $ do
204+ -- We need to wait for dependencies to be built, before checking if the current
205+ -- module should be rebuilt, so the first thing to do is to wait on the
206+ -- MVars for the module's dependencies.
207+ mexterns <- sequence <$> mapM (readMVar . fst . fromMaybe (error "make: no barrier") . flip lookup barriers) deps
208+
209+ outputTimestamp <- getOutputTimestamp moduleName
210+ dependencyTimestamp <- maximumMaybe <$> mapM (fmap shouldExist . getOutputTimestamp) deps
211+ inputTimestamp <- getInputTimestamp moduleName
212+
213+ let shouldRebuild = case (inputTimestamp, dependencyTimestamp, outputTimestamp) of
214+ (Right (Just t1), Just t3, Just t2) -> t1 > t2 || t3 > t2
215+ (Right (Just t1), Nothing, Just t2) -> t1 > t2
216+ (Left RebuildNever, _, Just _) -> False
217+ _ -> True
218+
219+ let rebuild =
220+ case mexterns of
221+ Just externs -> do
222+ progress $ CompilingModule moduleName
223+ let env = foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
224+ lint m
225+ ([desugared], nextVar) <- runSupplyT 0 $ desugar externs [m]
226+ (checked@(Module ss coms _ elaborated exps), env') <- runCheck' env $ typeCheckModule desugared
227+ checkExhaustiveModule env' checked
228+ regrouped <- createBindingGroups moduleName . collapseBindingGroups $ elaborated
229+ let mod' = Module ss coms moduleName regrouped exps
230+ corefn = CF.moduleToCoreFn env' mod'
231+ [renamed] = renameInModules [corefn]
232+ exts = moduleToExternsFile mod' env'
233+ evalSupplyT nextVar $ codegen renamed env' $ encode exts
234+ markComplete (Just exts) Nothing
235+ Nothing -> markComplete Nothing Nothing
236+
237+ if shouldRebuild
238+ then rebuild
239+ else do
240+ mexts <- decodeExterns . snd <$> readExterns moduleName
241+ case mexts of
242+ Just exts -> markComplete (Just exts) Nothing
243+ Nothing -> rebuild
244+ where
245+ markComplete :: Maybe ExternsFile -> Maybe MultipleErrors -> m ()
246+ markComplete externs errors = do
247+ putMVar (fst $ fromMaybe (error "make: no barrier") $ lookup moduleName barriers) externs
248+ putMVar (snd $ fromMaybe (error "make: no barrier") $ lookup moduleName barriers) errors
249+
250+ maximumMaybe :: (Ord a) => [a] -> Maybe a
251+ maximumMaybe [] = Nothing
252+ maximumMaybe xs = Just $ maximum xs
253+
254+ -- Make sure a dependency exists
255+ shouldExist :: Maybe UTCTime -> UTCTime
256+ shouldExist (Just t) = t
257+ shouldExist _ = error "make: dependency should already have been built."
258+
259+ decodeExterns :: B.ByteString -> Maybe ExternsFile
260+ decodeExterns bs = do
261+ externs <- decode bs
262+ guard $ efVersion externs == showVersion Paths.version
263+ return externs
212
264
213-- |
265-- |
214-- Add an import declaration for a module if it does not already explicitly import it.
266-- Add an import declaration for a module if it does not already explicitly import it.
@@ -231,6 +283,14 @@ importPrim = addDefaultImport (ModuleName [ProperName C.prim])
231newtype Make a = Make { unMake :: ReaderT Options (WriterT MultipleErrors (ExceptT MultipleErrors IO)) a }
283newtype Make a = Make { unMake :: ReaderT Options (WriterT MultipleErrors (ExceptT MultipleErrors IO)) a }
232 deriving (Functor, Applicative, Monad, MonadIO, MonadError MultipleErrors, MonadWriter MultipleErrors, MonadReader Options)
284 deriving (Functor, Applicative, Monad, MonadIO, MonadError MultipleErrors, MonadWriter MultipleErrors, MonadReader Options)
233
285
286+instance MonadBase IO Make where
287+ liftBase = liftIO
288+
289+instance MonadBaseControl IO Make where
290+ type StM Make a = Either MultipleErrors (a, MultipleErrors)
291+ liftBaseWith f = Make $ liftBaseWith $ \q -> f (q . unMake)
292+ restoreM = Make . restoreM
293+
234-- |
294-- |
235-- Execute a 'Make' monad, returning either errors, or the result of the compile plus any warnings.
295-- Execute a 'Make' monad, returning either errors, or the result of the compile plus any warnings.
236--
296--
@@ -305,15 +365,15 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
305 requiresForeign = not . null . CF.moduleForeign
365 requiresForeign = not . null . CF.moduleForeign
306
366
307 getTimestamp :: FilePath -> Make (Maybe UTCTime)
367 getTimestamp :: FilePath -> Make (Maybe UTCTime)
308− getTimestamp path = makeIO (const (SimpleErrorWrapper $ CannotGetFileInfo path)) $ do
368+ getTimestamp path = makeIO (const (ErrorMessage [] $ CannotGetFileInfo path)) $ do
309 exists <- doesFileExist path
369 exists <- doesFileExist path
310 traverse (const $ getModificationTime path) $ guard exists
370 traverse (const $ getModificationTime path) $ guard exists
311
371
312 readTextFile :: FilePath -> Make B.ByteString
372 readTextFile :: FilePath -> Make B.ByteString
313− readTextFile path = makeIO (const (SimpleErrorWrapper $ CannotReadFile path)) $ B.readFile path
373+ readTextFile path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ B.readFile path
314
374
315 writeTextFile :: FilePath -> B.ByteString -> Make ()
375 writeTextFile :: FilePath -> B.ByteString -> Make ()
316− writeTextFile path text = makeIO (const (SimpleErrorWrapper $ CannotWriteFile path)) $ do
376+ writeTextFile path text = makeIO (const (ErrorMessage [] $ CannotWriteFile path)) $ do
317 mkdirp path
377 mkdirp path
318 B.writeFile path text
378 B.writeFile path text
319 where
379 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+26−28
@@ -151,33 +151,34 @@ parseImportDeclaration' = do
151 where
151 where
152 stdImport = do
152 stdImport = do
153 moduleName' <- moduleName
153 moduleName' <- moduleName
154− stdImportHiding moduleName' <|> stdImportQualifying moduleName'
154+ suffixHiding moduleName' <|> suffixQualifyingList moduleName'
155 where
155 where
156− stdImportHiding mn = do
156+ suffixHiding mn = do
157 reserved "hiding"
157 reserved "hiding"
158− declType <- importDeclarationType Hiding
158+ declType <- qualifyingList Hiding
159− return (mn, declType, Nothing)
160− stdImportQualifying mn = do
161− declType <- importDeclarationType Explicit
162 return (mn, declType, Nothing)
159 return (mn, declType, Nothing)
160+ suffixQualifyingList mn = do
161+ declType <- qualifyingList Explicit
162+ qName <- P.optionMaybe qualifiedName
163+ return (mn, declType, qName)
164+ qualifiedName = reserved "as" *> moduleName
163 qualImport = do
165 qualImport = do
164 reserved "qualified"
166 reserved "qualified"
165 indented
167 indented
166 moduleName' <- moduleName
168 moduleName' <- moduleName
167− declType <- importDeclarationType Explicit
169+ declType <- qualifyingList Explicit
168− reserved "as"
170+ qName <- qualifiedName
169− asQ <- moduleName
170− return (moduleName', declType, Just asQ)
171+ return (moduleName', declType, Just qName)
171− importDeclarationType expectedType = do
172+ qualifyingList expectedType = do
172 idents <- P.optionMaybe $ indented *> parens (commaSep parseDeclarationRef)
173 idents <- P.optionMaybe $ indented *> parens (commaSep parseDeclarationRef)
173 return $ fromMaybe Implicit (expectedType <$> idents)
174 return $ fromMaybe Implicit (expectedType <$> idents)
174
175
175
176
176parseDeclarationRef :: TokenParser DeclarationRef
177parseDeclarationRef :: TokenParser DeclarationRef
177parseDeclarationRef =
178parseDeclarationRef =
178− parseModuleRef <|> (
179+ parseModuleRef <|>
179− withSourceSpan PositionedDeclarationRef $
180+ withSourceSpan PositionedDeclarationRef
180− ValueRef <$> parseIdent
181+ (ValueRef <$> parseIdent
181 <|> do name <- properName
182 <|> do name <- properName
182 dctors <- P.optionMaybe $ parens (symbol' ".." *> pure Nothing <|> Just <$> commaSep properName)
183 dctors <- P.optionMaybe $ parens (symbol' ".." *> pure Nothing <|> Just <$> commaSep properName)
183 return $ maybe (TypeClassRef name) (TypeRef name) dctors
184 return $ maybe (TypeClassRef name) (TypeRef name) dctors
@@ -203,8 +204,8 @@ parseTypeClassDeclaration = do
203 mark (P.many (same *> positioned parseTypeDeclaration))
204 mark (P.many (same *> positioned parseTypeDeclaration))
204 return $ TypeClassDeclaration className idents implies members
205 return $ TypeClassDeclaration className idents implies members
205
206
206−parseTypeInstanceDeclaration :: TokenParser Declaration
207+parseInstanceDeclaration :: TokenParser (TypeInstanceBody -> Declaration)
207−parseTypeInstanceDeclaration = do
208+parseInstanceDeclaration = do
208 reserved "instance"
209 reserved "instance"
209 name <- parseIdent <* indented <* doubleColon
210 name <- parseIdent <* indented <* doubleColon
210 deps <- P.optionMaybe $ do
211 deps <- P.optionMaybe $ do
@@ -214,24 +215,21 @@ parseTypeInstanceDeclaration = do
214 return deps
215 return deps
215 className <- indented *> parseQualified properName
216 className <- indented *> parseQualified properName
216 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
217 members <- P.option [] . P.try $ do
223 members <- P.option [] . P.try $ do
218 indented *> reserved "where"
224 indented *> reserved "where"
219 mark (P.many (same *> positioned parseValueDeclaration))
225 mark (P.many (same *> positioned parseValueDeclaration))
220− return $ TypeInstanceDeclaration name (fromMaybe [] deps) className ty (ExplicitInstance members)
226+ return $ instanceDecl (ExplicitInstance members)
221
227
222parseDerivingInstanceDeclaration :: TokenParser Declaration
228parseDerivingInstanceDeclaration :: TokenParser Declaration
223parseDerivingInstanceDeclaration = do
229parseDerivingInstanceDeclaration = do
224 reserved "derive"
230 reserved "derive"
225− reserved "instance"
231+ instanceDecl <- parseInstanceDeclaration
226− name <- parseIdent <* indented <* doubleColon
227− deps <- P.optionMaybe $ do
228− deps <- parens (commaSep1 ((,) <$> parseQualified properName <*> P.many (noWildcards parseTypeAtom)))
229− indented
230− rfatArrow
231− return deps
232− className <- indented *> parseQualified properName
233− ty <- P.many (indented *> noWildcards parseTypeAtom)
234− return $ TypeInstanceDeclaration name (fromMaybe [] deps) className ty DerivedInstance
232+ return $ instanceDecl DerivedInstance
235
233
236positioned :: TokenParser Declaration -> TokenParser Declaration
234positioned :: TokenParser Declaration -> TokenParser Declaration
237positioned = withSourceSpan PositionedDeclaration
235positioned = withSourceSpan PositionedDeclaration
@@ -295,7 +293,7 @@ parseModulesFromFiles toFilePath input = do
295 collect vss = [ (k, v) | (k, vs) <- vss, v <- vs ]
293 collect vss = [ (k, v) | (k, vs) <- vss, v <- vs ]
296
294
297toPositionedError :: P.ParseError -> ErrorMessage
295toPositionedError :: P.ParseError -> ErrorMessage
298−toPositionedError perr = PositionedError (SourceSpan name start end) (SimpleErrorWrapper (ErrorParsingModule perr))
296+toPositionedError perr = ErrorMessage [ PositionedError (SourceSpan name start end) ] (ErrorParsingModule perr)
299 where
297 where
300 name = (P.sourceName . P.errorPos) perr
298 name = (P.sourceName . P.errorPos) perr
301 start = (toSourcePos . P.errorPos) perr
299 start = (toSourcePos . P.errorPos) perr
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+19−15
@@ -14,7 +14,8 @@
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16module Language.PureScript.Pretty.Kinds (
16module Language.PureScript.Pretty.Kinds (
17− prettyPrintKind
17+ prettyPrintKind,
18+ kindAsBox
18) where
19) where
19
20
20import Data.Maybe (fromMaybe)
21import Data.Maybe (fromMaybe)
@@ -23,14 +24,15 @@ import Control.Arrow (ArrowPlus(..))
23import Control.PatternArrows
24import Control.PatternArrows
24
25
25import Language.PureScript.Kinds
26import Language.PureScript.Kinds
26−import Language.PureScript.Pretty.Common
27
27
28+import Text.PrettyPrint.Boxes (Box(), text, render, (<>))
29+
28−typeLiterals :: Pattern () Kind String
30+typeLiterals :: Pattern () Kind Box
29typeLiterals = mkPattern match
31typeLiterals = mkPattern match
30 where
32 where
31− match Star = Just "*"
33+ match Star = Just $ text "*"
32− match Bang = Just "!"
34+ match Bang = Just $ text "!"
33− match (KUnknown u) = Just $ 'u' : show u
35+ match (KUnknown u) = Just $ text $ 'u' : show u
34 match _ = Nothing
36 match _ = Nothing
35
37
36matchRow :: Pattern () Kind ((), Kind)
38matchRow :: Pattern () Kind ((), Kind)
@@ -45,15 +47,17 @@ funKind = mkPattern match
45 match (FunKind arg ret) = Just (arg, ret)
47 match (FunKind arg ret) = Just (arg, ret)
46 match _ = Nothing
48 match _ = Nothing
47
49
48−-- |
49−-- Generate a pretty-printed string representing a Kind
50+-- | Generate a pretty-printed string representing a Kind
50−--
51prettyPrintKind :: Kind -> String
51prettyPrintKind :: Kind -> String
52+prettyPrintKind = render . kindAsBox
53+
54+kindAsBox :: Kind -> Box
52−prettyPrintKind = fromMaybe (error "Incomplete pattern") . pattern matchKind ()
55+kindAsBox = fromMaybe (error "Incomplete pattern") . pattern matchKind ()
53 where
56 where
54− matchKind :: Pattern () Kind String
57+ matchKind :: Pattern () Kind Box
55− matchKind = buildPrettyPrinter operators (typeLiterals <+> fmap parens matchKind)
58+ matchKind = buildPrettyPrinter operators (typeLiterals <+> fmap ((text "(" <>) . (<> text ")")) matchKind)
59+
56− operators :: OperatorTable () Kind String
60+ operators :: OperatorTable () Kind Box
57 operators =
61 operators =
58− OperatorTable [ [ Wrap matchRow $ \_ k -> "# " ++ k]
62+ OperatorTable [ [ Wrap matchRow $ \_ k -> text "# " <> k]
59− , [ AssocR funKind $ \arg ret -> arg ++ " -> " ++ ret ] ]
63+ , [ AssocR funKind $ \arg ret -> arg <> text " -> " <> ret ] ]
src/Language/PureScript/Pretty/Types.hs+56−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,54 @@ 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 `before` (text ") => " <> typeAsBox 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])] -> Box
54+constraintsAsBox = vcat left . zipWith (\i (pn, tys) -> text (if i == 0 then "( " else ", ") <> constraintAsBox pn tys) [0 :: Int ..]
55+ where
56+ constraintAsBox pn tys = hsep 1 left (text (runProperName (disqualify pn)) : map typeAtomAsBox tys)
57+
50-- |
58-- |
51-- Generate a pretty-printed string representing a Row
59-- Generate a pretty-printed string representing a Row
52--
60--
53−prettyPrintRow :: Type -> String
61+prettyPrintRowWith :: Char -> Char -> Type -> Box
54−prettyPrintRow = (\(tys, rest) -> intercalate ", " (map (uncurry nameAndTypeToPs) tys) ++ tailToPs rest) . toList []
62+prettyPrintRowWith open close = uncurry listToBox . toList []
55 where
63 where
56− nameAndTypeToPs :: String -> Type -> String
64+ nameAndTypeToPs :: Char -> String -> Type -> Box
57− nameAndTypeToPs name ty = prettyPrintObjectKey name ++ " :: " ++ prettyPrintType ty
65+ nameAndTypeToPs start name ty = text (start : ' ' : prettyPrintObjectKey name ++ " :: ") <> typeAsBox ty
66+
58− tailToPs :: Type -> String
67+ tailToPs :: Type -> Box
59− tailToPs REmpty = ""
68+ tailToPs REmpty = nullBox
60− tailToPs other = " | " ++ prettyPrintType other
69+ tailToPs other = text "| " <> typeAsBox other
70+
71+ listToBox :: [(String, Type)] -> Type -> Box
72+ listToBox [] REmpty = text [open, close]
73+ listToBox [] rest = text [ open, ' ' ] <> tailToPs rest <> text [ ' ', close ]
74+ listToBox ts rest = vcat left $
75+ zipWith (\(nm, ty) i -> nameAndTypeToPs (if i == 0 then open else ',') nm ty) ts [0 :: Int ..] ++
76+ [ tailToPs rest, text [close] ]
77+
61 toList :: [(String, Type)] -> Type -> ([(String, Type)], Type)
78 toList :: [(String, Type)] -> Type -> ([(String, Type)], Type)
62 toList tys (RCons name ty row) = toList ((name, ty):tys) row
79 toList tys (RCons name ty row) = toList ((name, ty):tys) row
63 toList tys r = (tys, r)
80 toList tys r = (tys, r)
64
81
82+prettyPrintRow :: Type -> String
83+prettyPrintRow = render . prettyPrintRowWith '(' ')'
84+
65typeApp :: Pattern () Type (Type, Type)
85typeApp :: Pattern () Type (Type, Type)
66typeApp = mkPattern match
86typeApp = mkPattern match
67 where
87 where
@@ -92,19 +112,19 @@ insertPlaceholders = everywhereOnTypesTopDown convertForAlls . everywhereOnTypes
92 go idents other = PrettyPrintForAll idents other
112 go idents other = PrettyPrintForAll idents other
93 convertForAlls other = other
113 convertForAlls other = other
94
114
95−matchTypeAtom :: Pattern () Type String
115+matchTypeAtom :: Pattern () Type Box
96−matchTypeAtom = typeLiterals <+> fmap parens matchType
116+matchTypeAtom = typeLiterals <+> fmap ((`before` text ")") . (text "(" <>)) matchType
97
117
98−matchType :: Pattern () Type String
118+matchType :: Pattern () Type Box
99matchType = buildPrettyPrinter operators matchTypeAtom
119matchType = buildPrettyPrinter operators matchTypeAtom
100 where
120 where
101− operators :: OperatorTable () Type String
121+ operators :: OperatorTable () Type Box
102 operators =
122 operators =
103− OperatorTable [ [ AssocL typeApp $ \f x -> f ++ " " ++ x ]
123+ OperatorTable [ [ AssocL typeApp $ \f x -> f `beforeWithSpace` x ]
104− , [ AssocR appliedFunction $ \arg ret -> arg ++ " -> " ++ ret
124+ , [ AssocR appliedFunction $ \arg ret -> (arg <> text " ") `before` (text "-> " <> ret)
105 ]
125 ]
106− , [ Wrap forall_ $ \idents ty -> "forall " ++ unwords idents ++ ". " ++ ty ]
126+ , [ Wrap forall_ $ \idents ty -> text ("forall " ++ unwords idents ++ ". ") <> ty ]
107− , [ Wrap kinded $ \k ty -> ty ++ " :: " ++ prettyPrintKind k ]
127+ , [ Wrap kinded $ \k ty -> ty `before` (text " :: " <> kindAsBox k) ]
108 ]
128 ]
109
129
110forall_ :: Pattern () Type ([String], Type)
130forall_ :: Pattern () Type ([String], Type)
@@ -113,15 +133,16 @@ forall_ = mkPattern match
113 match (PrettyPrintForAll idents ty) = Just (idents, ty)
133 match (PrettyPrintForAll idents ty) = Just (idents, ty)
114 match _ = Nothing
134 match _ = Nothing
115
135
116−-- |
136+typeAtomAsBox :: Type -> Box
137+typeAtomAsBox = fromMaybe (error "Incomplete pattern") . pattern matchTypeAtom () . insertPlaceholders
138+
117−-- Generate a pretty-printed string representing a Type, as it should appear inside parentheses
139+-- | Generate a pretty-printed string representing a Type, as it should appear inside parentheses
118−--
119prettyPrintTypeAtom :: Type -> String
140prettyPrintTypeAtom :: Type -> String
120−prettyPrintTypeAtom = fromMaybe (error "Incomplete pattern") . pattern matchTypeAtom () . insertPlaceholders
141+prettyPrintTypeAtom = render . typeAtomAsBox
121
142
143+typeAsBox :: Type -> Box
144+typeAsBox = fromMaybe (error "Incomplete pattern") . pattern matchType () . insertPlaceholders
122
145
123−-- |
124−-- Generate a pretty-printed string representing a Type
146+-- | Generate a pretty-printed string representing a Type
125−--
126prettyPrintType :: Type -> String
147prettyPrintType :: Type -> String
127−prettyPrintType = fromMaybe (error "Incomplete pattern") . pattern matchType () . insertPlaceholders
148+prettyPrintType = render . typeAsBox
src/Language/PureScript/Pretty/Values.hs+92−152
@@ -21,173 +21,113 @@ 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 ++ " = "
91− , prettyPrintValue' val
100+ text (showIdent ident ++ " = ") <> prettyPrintValue val
92− ]
93prettyPrintDeclaration (PositionedDeclaration _ _ d) = prettyPrintDeclaration d
101prettyPrintDeclaration (PositionedDeclaration _ _ d) = prettyPrintDeclaration d
94prettyPrintDeclaration _ = error "Invalid argument to prettyPrintDeclaration"
102prettyPrintDeclaration _ = error "Invalid argument to prettyPrintDeclaration"
95
103
96−prettyPrintCaseAlternative :: CaseAlternative -> StateT PrinterState Maybe String
104+prettyPrintCaseAlternative :: CaseAlternative -> Box
97prettyPrintCaseAlternative (CaseAlternative binders result) =
105prettyPrintCaseAlternative (CaseAlternative binders result) =
98− concat <$> sequence
99− [ return (unwords (map prettyPrintBinderAtom binders))
106+ text (unwords (map prettyPrintBinderAtom binders)) <> prettyPrintResult result
100− , prettyPrintResult result
101− ]
102 where
107 where
103− prettyPrintResult (Left gs) = concat <$> sequence
108+ prettyPrintResult :: Either [(Guard, Expr)] Expr -> Box
104− [ return "\n"
109+ prettyPrintResult (Left gs) =
105− , withIndent $ prettyPrintMany prettyPrintGuardedValue gs
110+ vcat left (map prettyPrintGuardedValue gs)
106− ]
107− prettyPrintResult (Right v) = (" -> " ++) <$> prettyPrintValue' v
111+ prettyPrintResult (Right v) = text " -> " <> prettyPrintValue v
108−
112+
109− prettyPrintGuardedValue (grd, val) =
113+ prettyPrintGuardedValue :: (Guard, Expr) -> Box
110− concat <$> sequence
114+ prettyPrintGuardedValue (grd, val) = foldl1 before
111− [ return "| "
115+ [ text " | "
112− , prettyPrintValue' grd
116+ , prettyPrintValue grd
113− , return " -> "
117+ , text " -> "
114− , prettyPrintValue' val
118+ , prettyPrintValue val
115− ]
119+ ]
116−
120+
117−prettyPrintDoNotationElement :: DoNotationElement -> StateT PrinterState Maybe String
121+prettyPrintDoNotationElement :: DoNotationElement -> Box
118prettyPrintDoNotationElement (DoNotationValue val) =
122prettyPrintDoNotationElement (DoNotationValue val) =
119− prettyPrintValue' val
123+ prettyPrintValue val
120prettyPrintDoNotationElement (DoNotationBind binder val) =
124prettyPrintDoNotationElement (DoNotationBind binder val) =
121− concat <$> sequence
122− [ return (prettyPrintBinder binder)
125+ text (prettyPrintBinder binder ++ " <- ") <> prettyPrintValue val
123− , return " <- "
124− , prettyPrintValue' val
125− ]
126prettyPrintDoNotationElement (DoNotationLet ds) =
126prettyPrintDoNotationElement (DoNotationLet ds) =
127− concat <$> sequence
127+ text "let" //
128− [ return "let "
129− , withIndent $ prettyPrintMany prettyPrintDeclaration ds
128+ moveRight 2 (vcat left (map prettyPrintDeclaration ds))
130− ]
131prettyPrintDoNotationElement (PositionedDoNotationElement _ _ el) = prettyPrintDoNotationElement el
129prettyPrintDoNotationElement (PositionedDoNotationElement _ _ el) = prettyPrintDoNotationElement el
132
130
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
131prettyPrintBinderAtom :: Binder -> String
192prettyPrintBinderAtom NullBinder = "_"
132prettyPrintBinderAtom NullBinder = "_"
193prettyPrintBinderAtom (StringBinder str) = show str
133prettyPrintBinderAtom (StringBinder str) = show str
@@ -196,7 +136,7 @@ prettyPrintBinderAtom (NumberBinder num) = either show show num
196prettyPrintBinderAtom (BooleanBinder True) = "true"
136prettyPrintBinderAtom (BooleanBinder True) = "true"
197prettyPrintBinderAtom (BooleanBinder False) = "false"
137prettyPrintBinderAtom (BooleanBinder False) = "false"
198prettyPrintBinderAtom (VarBinder ident) = showIdent ident
138prettyPrintBinderAtom (VarBinder ident) = showIdent ident
199−prettyPrintBinderAtom (ConstructorBinder ctor []) = showQualified runProperName ctor
139+prettyPrintBinderAtom (ConstructorBinder ctor []) = runProperName (disqualify ctor)
200prettyPrintBinderAtom (ObjectBinder bs) =
140prettyPrintBinderAtom (ObjectBinder bs) =
201 "{ "
141 "{ "
202 ++ intercalate ", " (map prettyPrintObjectPropertyBinder bs)
142 ++ intercalate ", " (map prettyPrintObjectPropertyBinder bs)
@@ -216,7 +156,7 @@ prettyPrintBinderAtom b = parens (prettyPrintBinder b)
216-- Generate a pretty-printed string representing a Binder
156-- Generate a pretty-printed string representing a Binder
217--
157--
218prettyPrintBinder :: Binder -> String
158prettyPrintBinder :: Binder -> String
219−prettyPrintBinder (ConstructorBinder ctor []) = showQualified runProperName ctor
159+prettyPrintBinder (ConstructorBinder ctor []) = runProperName (disqualify ctor)
220−prettyPrintBinder (ConstructorBinder ctor args) = showQualified runProperName ctor ++ " " ++ unwords (map prettyPrintBinderAtom args)
160+prettyPrintBinder (ConstructorBinder ctor args) = runProperName (disqualify ctor) ++ " " ++ unwords (map prettyPrintBinderAtom args)
221prettyPrintBinder (PositionedBinder _ _ binder) = prettyPrintBinder binder
161prettyPrintBinder (PositionedBinder _ _ binder) = prettyPrintBinder binder
222prettyPrintBinder b = prettyPrintBinderAtom b
162prettyPrintBinder 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+1−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]
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+2−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
@@ -207,7 +207,6 @@ renameInModule env imports (Module ss coms mn decls exps) =
207 where
207 where
208 updateType :: Type -> m Type
208 updateType :: Type -> m Type
209 updateType (TypeConstructor name) = TypeConstructor <$> updateTypeName name pos
209 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
210 updateType (ConstrainedType cs t) = ConstrainedType <$> updateConstraints pos cs <*> pure t
212 updateType t = return t
211 updateType t = return t
213
212
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+15−27
@@ -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
@@ -267,13 +267,12 @@ 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
267-- 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.
268-- required by exported members are also exported.
269--
269--
270−typeCheckModule :: Maybe ModuleName -> Module -> Check Module
270+typeCheckModule :: Module -> Check Module
271−typeCheckModule _ (Module _ _ _ _ Nothing) = error "exports should have been elaborated"
271+typeCheckModule (Module _ _ _ _ Nothing) = error "exports should have been elaborated"
272−typeCheckModule mainModuleName (Module ss coms mn decls (Just exps)) = warnAndRethrow (onErrorMessages (ErrorInModule mn)) $ do
272+typeCheckModule (Module ss coms mn decls (Just exps)) = warnAndRethrow (addHint (ErrorInModule mn)) $ do
273 modify (\s -> s { checkCurrentModule = Just mn })
273 modify (\s -> s { checkCurrentModule = Just mn })
274− decls' <- typeCheckAll mainModuleName mn exps decls
274+ decls' <- typeCheckAll mn exps decls
275 forM_ exps $ \e -> do
275 forM_ exps $ \e -> do
276− checkTypesAreExported e
277 checkClassMembersAreExported e
276 checkClassMembersAreExported e
278 checkClassesAreExported e
277 checkClassesAreExported e
279 return $ Module ss coms mn decls' (Just exps)
278 return $ Module ss coms mn decls' (Just exps)
@@ -295,17 +294,6 @@ typeCheckModule mainModuleName (Module ss coms mn decls (Just exps)) = warnAndRe
295 exports _ _ = False
294 exports _ _ = False
296 checkMemberExport _ _ = return ()
295 checkMemberExport _ _ = return ()
297
296
298− -- Check that all the type constructors defined in the current module that appear in member types
299− -- have also been exported from the module
300− checkTypesAreExported :: DeclarationRef -> Check ()
301− checkTypesAreExported = checkMemberExport findTcons
302− where
303− findTcons :: Type -> [DeclarationRef]
304− findTcons = everythingOnTypes (++) go
305− where
306− go (TypeConstructor (Qualified (Just mn') name)) | mn' == mn = [TypeRef name (error "Data constructors unused in checkTypesAreExported")]
307− go _ = []
308−
309 -- Check that all the classes defined in the current module that appear in member types have also
297 -- Check that all the classes defined in the current module that appear in member types have also
310 -- been exported from the module
298 -- been exported from the module
311 checkClassesAreExported :: DeclarationRef -> Check ()
299 checkClassesAreExported :: 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+2−2
@@ -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
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+15−67
@@ -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--
@@ -419,7 +382,7 @@ binderRequiresMonotype _ = True
419
382
420-- | Instantiate polytypes only when necessitated by a binder.
383-- | Instantiate polytypes only when necessitated by a binder.
421instantiateForBinders :: [Expr] -> [CaseAlternative] -> UnifyT Type Check ([Expr], [Type])
384instantiateForBinders :: [Expr] -> [CaseAlternative] -> UnifyT Type Check ([Expr], [Type])
422−instantiateForBinders vals cas = fmap unzip $ zipWithM (\val inst -> do
385+instantiateForBinders vals cas = unzip <$> zipWithM (\val inst -> do
423 TypedValue _ val' ty <- infer val
386 TypedValue _ val' ty <- infer val
424 if inst
387 if inst
425 then instantiatePolyTypeWithUnknowns val' ty
388 then instantiatePolyTypeWithUnknowns val' ty
@@ -457,7 +420,7 @@ checkBinders nvals ret (CaseAlternative binders result : bs) = do
457-- Check the type of a value, rethrowing errors to provide a better error message
420-- Check the type of a value, rethrowing errors to provide a better error message
458--
421--
459check :: Expr -> Type -> UnifyT Type Check Expr
422check :: Expr -> Type -> UnifyT Type Check Expr
460−check val ty = rethrow (onErrorMessages (ErrorCheckingType val ty)) $ check' val ty
423+check val ty = rethrow (addHint (ErrorCheckingType val ty)) $ check' val ty
461
424
462-- |
425-- |
463-- Check the type of a value
426-- Check the type of a value
@@ -493,9 +456,6 @@ check' val t@(ConstrainedType constraints ty) = do
493
456
494 instantiateSuperclass :: [String] -> [Type] -> [Type] -> [Type]
457 instantiateSuperclass :: [String] -> [Type] -> [Type] -> [Type]
495 instantiateSuperclass args supArgs tys = map (replaceAllTypeVars (zip args tys)) supArgs
458 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
459check' val u@(TUnknown _) = do
500 val'@(TypedValue _ _ ty) <- infer val
460 val'@(TypedValue _ _ ty) <- infer val
501 -- Don't unify an unknown with an inferred polytype
461 -- Don't unify an unknown with an inferred polytype
@@ -599,9 +559,6 @@ check' v@(Constructor c) ty = do
599check' (Let ds val) ty = do
559check' (Let ds val) ty = do
600 (ds', val') <- inferLetBinding [] ds val (`check` ty)
560 (ds', val') <- inferLetBinding [] ds val (`check` ty)
601 return $ TypedValue True (Let ds' val') ty
561 return $ TypedValue True (Let ds' val') ty
602−check' val ty | containsTypeSynonyms ty = do
603− ty' <- introduceSkolemScope <=< expandAllTypeSynonyms <=< replaceTypeWildcards $ ty
604− check val ty'
605check' val kt@(KindedType ty kind) = do
562check' val kt@(KindedType ty kind) = do
606 checkTypeKind ty kind
563 checkTypeKind ty kind
607 val' <- check' val ty
564 val' <- check' val ty
@@ -615,12 +572,6 @@ check' val ty = do
615 Nothing -> throwError . errorMessage $ SubsumptionCheckFailed
572 Nothing -> throwError . errorMessage $ SubsumptionCheckFailed
616 Just v' -> return $ TypedValue True v' ty
573 Just v' -> return $ TypedValue True v' ty
617
574
618−containsTypeSynonyms :: Type -> Bool
619−containsTypeSynonyms = everythingOnTypes (||) go where
620− go (SaturatedTypeSynonym _ _) = True
621− go _ = False
622−
623−
624-- |
575-- |
625-- Check the type of a collection of named record fields
576-- Check the type of a collection of named record fields
626--
577--
@@ -655,7 +606,7 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
655-- Check the type of a function application, rethrowing errors to provide a better error message
606-- Check the type of a function application, rethrowing errors to provide a better error message
656--
607--
657checkFunctionApplication :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
608checkFunctionApplication :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
658−checkFunctionApplication fn fnTy arg ret = rethrow (onErrorMessages (ErrorInApplication fn fnTy arg)) $ do
609+checkFunctionApplication fn fnTy arg ret = rethrow (addHint (ErrorInApplication fn fnTy arg)) $ do
659 subst <- unifyCurrentSubstitution <$> UnifyT get
610 subst <- unifyCurrentSubstitution <$> UnifyT get
660 checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
611 checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
661
612
@@ -683,9 +634,6 @@ checkFunctionApplication' fn u@(TUnknown _) arg ret = do
683 ret' <- maybe fresh return ret
634 ret' <- maybe fresh return ret
684 u =?= function ty ret'
635 u =?= function ty ret'
685 return (ret', App fn arg')
636 return (ret', App fn arg')
686−checkFunctionApplication' fn (SaturatedTypeSynonym name tyArgs) arg ret = do
687− ty <- introduceSkolemScope <=< expandTypeSynonym name $ tyArgs
688− checkFunctionApplication fn ty arg ret
689checkFunctionApplication' fn (KindedType ty _) arg ret =
637checkFunctionApplication' fn (KindedType ty _) arg ret =
690 checkFunctionApplication fn ty arg ret
638 checkFunctionApplication fn ty arg ret
691checkFunctionApplication' fn (ConstrainedType constraints fnTy) arg ret = do
639checkFunctionApplication' 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
src/System/IO/UTF8.hsnew file+9
@@ -0,0 +1,9 @@
1+module System.IO.UTF8
2+where
3+import System.IO (hGetContents, hSetEncoding, openFile, utf8, IOMode (..))
4+
5+readUTF8File :: FilePath -> IO String
6+readUTF8File inFile = do
7+ h <- openFile inFile ReadMode
8+ hSetEncoding h utf8
9+ hGetContents h
stack-lts-3.yaml+1−1
@@ -2,4 +2,4 @@ flags: {}
2packages:
2packages:
3- '.'
3- '.'
4extra-deps:
4extra-deps:
5−resolver: lts-3.4
5+resolver: lts-3.6
stack-nightly.yaml+1−1
@@ -2,4 +2,4 @@ flags: {}
2packages:
2packages:
3- '.'
3- '.'
4extra-deps:
4extra-deps:
5−resolver: nightly-2015-09-09
5+resolver: nightly-2015-09-29
tests/Main.hs+4−3
@@ -66,6 +66,7 @@ import System.Exit
66import System.Process
66import System.Process
67import System.FilePath
67import System.FilePath
68import System.Directory
68import System.Directory
69+import System.IO.UTF8
69import qualified System.Info
70import qualified System.Info
70import qualified System.FilePath.Glob as Glob
71import qualified System.FilePath.Glob as Glob
71
72
@@ -97,7 +98,7 @@ makeActions foreigns = (P.buildMakeActions modulesDir (error "makeActions: input
97
98
98readInput :: [FilePath] -> IO [(FilePath, String)]
99readInput :: [FilePath] -> IO [(FilePath, String)]
99readInput inputFiles = forM inputFiles $ \inputFile -> do
100readInput inputFiles = forM inputFiles $ \inputFile -> do
100− text <- readFile inputFile
101+ text <- readUTF8File inputFile
101 return (inputFile, text)
102 return (inputFile, text)
102
103
103type TestM = WriterT [(FilePath, String)] IO
104type TestM = WriterT [(FilePath, String)] IO
@@ -157,7 +158,7 @@ assertDoesNotCompile inputFiles foreigns = do
157
158
158 where
159 where
159 getShouldFailWith =
160 getShouldFailWith =
160− readFile
161+ readUTF8File
161 >>> liftIO
162 >>> liftIO
162 >>> fmap ( lines
163 >>> fmap ( lines
163 >>> mapMaybe (stripPrefix "-- @shouldFailWith ")
164 >>> mapMaybe (stripPrefix "-- @shouldFailWith ")
@@ -184,7 +185,7 @@ main = do
184 supportPurs <- supportFiles "purs"
185 supportPurs <- supportFiles "purs"
185 supportJS <- supportFiles "js"
186 supportJS <- supportFiles "js"
186
187
187− foreignFiles <- forM supportJS (\f -> (f,) <$> readFile f)
188+ foreignFiles <- forM supportJS (\f -> (f,) <$> readUTF8File f)
188 Right (foreigns, _) <- runExceptT $ runWriterT $ P.parseForeignModulesFromFiles foreignFiles
189 Right (foreigns, _) <- runExceptT $ runWriterT $ P.parseForeignModulesFromFiles foreignFiles
189
190
190 let passing = cwd </> "examples" </> "passing"
191 let passing = cwd </> "examples" </> "passing"