git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge remote-tracking branch 'refs/remotes/upstream/master' into psci-node-flags

Conflicts: psci/Main.hs

commitf0d351fea81cdc94f16dab5a465fef423cfc6882 authorMichael Xavier <michael@michaelxavier.net> dateFri 20 Feb 2015, 21:42 (12 years ago) parent75225a87bc1490
163 files changed+3404−1824
LICENSE+35−35 README.md+2 RELEASE-0.2.md+13−13 RELEASE-0.3.md+8−8 RELEASE-0.4.md+8−8 RELEASE-0.5.md+3−3 RELEASE-0.7.md+6−6 bundle/README+4−4 bundle/build.sh+1−1 bundle/winbuild.sh+3−3 examples/failing/DuplicateDeclarationsInLet.purs+9 examples/failing/NewtypeMultiArgs.purs+1−1 examples/failing/NewtypeMultiCtor.purs+1−1 examples/failing/SkolemEscape2.purs+1−1 examples/failing/UnknownType.purs+1−1 examples/failing/UnknownValue.purs−25 examples/manual/failing/ArgLengthMismatch.purs+1−1 examples/manual/failing/ExportExplicit.purs+1−1 examples/manual/failing/ExportExplicit1.purs+2−2 examples/manual/failing/ExportExplicit2.purs+1−1 examples/manual/failing/ExportExplicit3.purs+1−1 examples/manual/failing/RedefinedFixity.purs+1−1 examples/manual/failing/RequiredHiddenType.purs+2−2 examples/manual/passing/ExportExplicit.purs+2−2 examples/manual/passing/ExportExplicit2.purs+1−1 examples/manual/passing/Import.purs+1−1 examples/manual/passing/ImportExplicit.purs+1−1 examples/manual/passing/ImportQualified.purs+3−3 examples/manual/passing/Module.purs+1−1 examples/manual/passing/ModuleDeps.purs+1−1 examples/passing/810.purs+11 examples/passing/BindersInFunctions.purs+7−5 examples/passing/BindingGroups.purs+2−2 examples/passing/CheckFunction.purs+5 examples/passing/CheckSynonymBug.purs+6−4 examples/passing/Comparisons.purs+8−6 examples/passing/Conditional.purs+1−1 examples/passing/Console.purs+1−1 examples/passing/DeepArrayBinder.purs+6−4 examples/passing/DeepCase.purs+2−2 examples/passing/Dollar.purs+1−1 examples/passing/EmptyDataDecls.purs+12−8 examples/passing/EmptyRow.purs+1−1 examples/passing/ExtendedInfixOperators.purs+20 examples/passing/ExternRaw.purs+20−7 examples/passing/FFI.purs+6−4 examples/passing/FinalTagless.purs+1−1 examples/passing/FunctionScope.purs+6−4 examples/passing/Functions2.purs+5−3 examples/passing/Guards.purs+2−2 examples/passing/HoistError.purs+7−5 examples/passing/JSReserved.purs+2−2 examples/passing/KindedType.purs+1−1 examples/passing/Let.purs+7−7 examples/passing/Monad.purs+2−2 examples/passing/MutRec.purs+1−1 examples/passing/MutRec2.purs+1−1 examples/passing/MutRec3.purs+1−1 examples/passing/NamedPatterns.purs+1−1 examples/passing/Newtype.purs+3−3 examples/passing/NewtypeWithRecordUpdate.purs+15 examples/passing/ObjectGetter.purs+11 examples/passing/ObjectSynonym.purs+1−1 examples/passing/ObjectUpdate2.purs+1−1 examples/passing/ObjectUpdater.purs+35 examples/passing/ObjectWildcards.purs+31 examples/passing/Objects.purs+1−1 examples/passing/OneConstructor.purs+1−1 examples/passing/OperatorAssociativity.purs+34−7 examples/passing/OperatorSections.purs+21 examples/passing/Operators.purs+23−5 examples/passing/OptimizerBug.purs+1−1 examples/passing/PartialFunction.purs+10−8 examples/passing/Patterns.purs+3−3 examples/passing/Person.purs+8−6 examples/passing/Rank2Data.purs+7−7 examples/passing/Rank2TypeSynonym.purs+2−2 examples/passing/Rank2Types.purs+1−1 examples/passing/Recursion.purs+1−1 examples/passing/RowPolyInstanceContext.purs+20 examples/passing/RowSynonyms.purs+46 examples/passing/ScopedTypeVariables.purs+34 examples/passing/Sequence.purs+2−2 examples/passing/ShadowedRename.purs+7−5 examples/passing/ShadowedTCO.purs+5−5 examples/passing/ShadowedTCOLet.purs+3−3 examples/passing/SignedNumericLiterals.purs+2−2 examples/passing/Superclasses3.purs+1−1 examples/passing/TailCall.purs+2−2 examples/passing/TopLevelCase.purs+1−1 examples/passing/TypeClassImport.purs+3−3 examples/passing/TypeClassMemberOrderChange.purs+1−1 examples/passing/TypeDecl.purs+1−1 examples/passing/TypeSynonyms.purs+2−2 examples/passing/TypeWildcardsRecordExtension.purs+1−1 examples/passing/Where.purs+6−6 examples/passing/s.purs+1−1 hierarchy/Main.hs+6−7 prelude/README.md+343−33 prelude/images/Prelude.png prelude/prelude.purs+655−470 prelude/updateDocs.sh+1−1 psc-docs/Main.hs+111−105 psc-make/Main.hs+37−31 psc/Main.hs+30−23 psci/Commands.hs+1−1 psci/Main.hs+138−95 psci/Parser.hs+5−5 purescript.cabal+20−17 src/Control/Monad/Unify.hs+155 src/Language/PureScript.hs+43−37 src/Language/PureScript/AST/Binders.hs+3−2 src/Language/PureScript/AST/Declarations.hs+60−21 src/Language/PureScript/AST/SourcePos.hs+2−2 src/Language/PureScript/AST/Traversals.hs+56−32 src/Language/PureScript/CodeGen/Externs.hs+16−4 src/Language/PureScript/CodeGen/JS.hs+88−69 src/Language/PureScript/CodeGen/JS/AST.hs+10−1 src/Language/PureScript/CodeGen/JS/Common.hs+42−2 src/Language/PureScript/CodeGen/JS/Optimizer.hs+29−19 src/Language/PureScript/CodeGen/JS/Optimizer/Inliner.hs+28−18 src/Language/PureScript/Comments.hs+25 src/Language/PureScript/Constants.hs+15 src/Language/PureScript/CoreFn/Ann.hs+9−2 src/Language/PureScript/CoreFn/Binders.hs+2−1 src/Language/PureScript/CoreFn/Desugar.hs+150−143 src/Language/PureScript/CoreFn/Expr.hs+42−5 src/Language/PureScript/CoreFn/Literals.hs+2−1 src/Language/PureScript/CoreFn/Meta.hs+3−6 src/Language/PureScript/Environment.hs+10−5 src/Language/PureScript/Errors.hs+28−15 src/Language/PureScript/ModuleDependencies.hs+7−7 src/Language/PureScript/Options.hs+5−2 src/Language/PureScript/Parser.hs+1−1 src/Language/PureScript/Parser/Common.hs+7−6 src/Language/PureScript/Parser/Declarations.hs+42−12 src/Language/PureScript/Parser/Lexer.hs+44−34 src/Language/PureScript/Parser/Types.hs+1−1 src/Language/PureScript/Pretty/JS.hs+45−9 src/Language/PureScript/Pretty/Types.hs+1−1 src/Language/PureScript/Pretty/Values.hs+40−31 src/Language/PureScript/Renamer.hs+1−1 src/Language/PureScript/Sugar.hs+19−10 src/Language/PureScript/Sugar/BindingGroups.hs+10−11 src/Language/PureScript/Sugar/CaseDeclarations.hs+9−10 src/Language/PureScript/Sugar/DoNotation.hs+3−3 src/Language/PureScript/Sugar/Names.hs+58−32 src/Language/PureScript/Sugar/ObjectWildcards.hs+61 src/Language/PureScript/Sugar/Operators.hs+28−16 src/Language/PureScript/Sugar/TypeClasses.hs+23−23 src/Language/PureScript/Sugar/TypeDeclarations.hs+6−8 src/Language/PureScript/Supply.hs+1−1 src/Language/PureScript/TypeChecker.hs+19−19 src/Language/PureScript/TypeChecker/Entailment.hs+25−4 src/Language/PureScript/TypeChecker/Kinds.hs+72−46 src/Language/PureScript/TypeChecker/Monad.hs+20−11 src/Language/PureScript/TypeChecker/Rows.hs+1−1 src/Language/PureScript/TypeChecker/Skolems.hs+2−1 src/Language/PureScript/TypeChecker/Subsumption.hs+2−3 src/Language/PureScript/TypeChecker/Synonyms.hs+6−5 src/Language/PureScript/TypeChecker/Types.hs+41−42 src/Language/PureScript/TypeChecker/Unify.hs+24−4 tests/Main.hs+6−6
LICENSE+35−35
@@ -41,43 +41,43 @@ PureScript uses the following Haskell library packages. Their license files foll
4141base LICENSE file:
4242
4343 This library (libraries/base) is derived from code from several
44− sources:
45−
44+ sources:
45+
4646 * Code from the GHC project which is largely (c) The University of
4747 Glasgow, and distributable under a BSD-style license (see below),
48−
48+
4949 * Code from the Haskell 98 Report which is (c) Simon Peyton Jones
5050 and freely redistributable (but see the full license for
5151 restrictions).
52−
52+
5353 * Code from the Haskell Foreign Function Interface specification,
5454 which is (c) Manuel M. T. Chakravarty and freely redistributable
5555 (but see the full license for restrictions).
56−
56+
5757 The full text of these licenses is reproduced below. All of the
5858 licenses are BSD-style or compatible.
59−
59+
6060 -----------------------------------------------------------------------------
61−
61+
6262 The Glasgow Haskell Compiler License
63−
64− Copyright 2004, The University Court of the University of Glasgow.
63+
64+ Copyright 2004, The University Court of the University of Glasgow.
6565 All rights reserved.
66−
66+
6767 Redistribution and use in source and binary forms, with or without
6868 modification, are permitted provided that the following conditions are met:
69−
69+
7070 - Redistributions of source code must retain the above copyright notice,
7171 this list of conditions and the following disclaimer.
72−
72+
7373 - Redistributions in binary form must reproduce the above copyright notice,
7474 this list of conditions and the following disclaimer in the documentation
7575 and/or other materials provided with the distribution.
76−
76+
7777 - Neither name of the University nor the names of its contributors may be
7878 used to endorse or promote products derived from this software without
79− specific prior written permission.
80−
79+ specific prior written permission.
80+
8181 THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
8282 GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
8383 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
@@ -90,14 +90,14 @@ base LICENSE file:
9090 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
9191 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
9292 DAMAGE.
93−
93+
9494 -----------------------------------------------------------------------------
95−
95+
9696 Code derived from the document "Report on the Programming Language
9797 Haskell 98", is distributed under the following license:
98−
98+
9999 Copyright (c) 2002 Simon Peyton Jones
100−
100+
101101 The authors intend this Report to belong to the entire Haskell
102102 community, and so we grant permission to copy and distribute it for
103103 any purpose, provided that it is reproduced in its entirety,
@@ -105,15 +105,15 @@ base LICENSE file:
105105 copied and distributed for any purpose, provided that the modified
106106 version is clearly presented as such, and that it does not claim to
107107 be a definition of the Haskell 98 Language.
108−
108+
109109 -----------------------------------------------------------------------------
110−
110+
111111 Code derived from the document "The Haskell 98 Foreign Function
112112 Interface, An Addendum to the Haskell 98 Report" is distributed under
113113 the following license:
114−
114+
115115 Copyright (c) 2002 Manuel M. T. Chakravarty
116−
116+
117117 The authors intend this Report to belong to the entire Haskell
118118 community, and so we grant permission to copy and distribute it for
119119 any purpose, provided that it is reproduced in its entirety,
@@ -121,9 +121,9 @@ base LICENSE file:
121121 copied and distributed for any purpose, provided that the modified
122122 version is clearly presented as such, and that it does not claim to
123123 be a definition of the Haskell 98 Foreign Function Interface.
124−
124+
125125 -----------------------------------------------------------------------------
126−
126+
127127containers LICENSE file:
128128
129129 The Glasgow Haskell Compiler License
@@ -161,7 +161,7 @@ containers LICENSE file:
161161directory LICENSE file:
162162
163163 This library (libraries/base) is derived from code from two
164− sources:
164+ sources:
165165
166166 * Code from the GHC project which is largely (c) The University of
167167 Glasgow, and distributable under a BSD-style license (see below),
@@ -177,7 +177,7 @@ directory LICENSE file:
177177
178178 The Glasgow Haskell Compiler License
179179
180− Copyright 2004, The University Court of the University of Glasgow.
180+ Copyright 2004, The University Court of the University of Glasgow.
181181 All rights reserved.
182182
183183 Redistribution and use in source and binary forms, with or without
@@ -185,14 +185,14 @@ directory LICENSE file:
185185
186186 - Redistributions of source code must retain the above copyright notice,
187187 this list of conditions and the following disclaimer.
188−
188+
189189 - Redistributions in binary form must reproduce the above copyright notice,
190190 this list of conditions and the following disclaimer in the documentation
191191 and/or other materials provided with the distribution.
192−
192+
193193 - Neither name of the University nor the names of its contributors may be
194194 used to endorse or promote products derived from this software without
195− specific prior written permission.
195+ specific prior written permission.
196196
197197 THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
198198 GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
@@ -451,7 +451,7 @@ pattern-arrows LICENSE file:
451451process LICENSE file:
452452
453453 This library (libraries/process) is derived from code from two
454− sources:
454+ sources:
455455
456456 * Code from the GHC project which is largely (c) The University of
457457 Glasgow, and distributable under a BSD-style license (see below),
@@ -467,7 +467,7 @@ process LICENSE file:
467467
468468 The Glasgow Haskell Compiler License
469469
470− Copyright 2004, The University Court of the University of Glasgow.
470+ Copyright 2004, The University Court of the University of Glasgow.
471471 All rights reserved.
472472
473473 Redistribution and use in source and binary forms, with or without
@@ -475,14 +475,14 @@ process LICENSE file:
475475
476476 - Redistributions of source code must retain the above copyright notice,
477477 this list of conditions and the following disclaimer.
478−
478+
479479 - Redistributions in binary form must reproduce the above copyright notice,
480480 this list of conditions and the following disclaimer in the documentation
481481 and/or other materials provided with the distribution.
482−
482+
483483 - Neither name of the University nor the names of its contributors may be
484484 used to endorse or promote products derived from this software without
485− specific prior written permission.
485+ specific prior written permission.
486486
487487 THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
488488 GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
README.md+2
@@ -9,6 +9,8 @@ PureScript is a small strongly, statically typed programming language with expre
99- [Wiki](http://wiki.purescript.org)
1010- [#purescript IRC @ FreeNode](http://webchat.freenode.net/?channels=purescript)
1111- [Twitter](http://twitter.com/purescript)
12+- [Google Group](https://groups.google.com/forum/#!forum/purescript)
1213- [Try PureScript!](http://try.purescript.org/)
14+- [Pursuit Search Engine](http://pursuit.purescript.org/)
1315- [Release Notes](https://github.com/purescript/purescript/blob/master/RELEASE-0.6.md)
1416- [Contributing to PureScript](https://github.com/purescript/purescript/blob/master/CONTRIBUTING.md)
RELEASE-0.2.md+13−13
@@ -10,31 +10,31 @@ Many thanks to the [contributors](https://github.com/purescript/purescript/graph
1010- RankNTypes
1111
1212 This experimental feature allows polymorphic types (introduced with `forall`) to appear on the left of a function arrow, or as the type of a record field, etc. For example:
13−
13+
1414 rank2 :: (forall a. a -> a) -> Number
1515 rank2 = \f -> if f true then f 1 else f 2
16−
16+
1717- Modules
1818- Polymorphic Object Update
1919
2020 Records now support member update in which the type of the field changes during the update. For example:
2121
2222 data Wrap a = Wrap a
23−
23+
2424 update = \o -> o { prop = Wrap o.prop }
2525
2626### Enhancements
2727
2828- Naked expressions as statements
29−
29+
3030 Naked expressions of type `{}` can now be used as statements.
3131
3232- Split code generation into `AST -> JS` and `JS -> String`
33−
33+
3434 JavaScript generation is now split into the generation of a JavaScript AST, and the pretty-printing of that AST. This enables some optimizations, and a better JavaScript pretty-printer.
35−
35+
3636- Syntactic sugar for introducing curried functions
37−
37+
3838 Single-argument functions and multiple-argument functions can now be introduced in the same way:
3939
4040 test = \a (b, c) d -> a + b + c + d
@@ -42,32 +42,32 @@ Many thanks to the [contributors](https://github.com/purescript/purescript/graph
4242- JavaScript optimizations
4343
4444 Some basic dead-variable elimination, inlining and eta-conversion are now performed on the generated JavaScript.
45−
45+
4646- Generate formatted Javascript
4747
4848 The generated JavaScript is now formatted to be more readable. In particular, newlines get generated, and the correct indentation is used.
4949
5050- More valid infix operators
51−
51+
5252 The colon and period characters are now valid in infix operator names.
5353
5454### Syntax Changes
5555
5656- Avoid 'do' keyword for blocks
57−
57+
5858 `do` will be used later for Haskell-like monad comprehensions, so its previous use in introducing blocks of statements is now invalid. The `do` keyword is still reserved.
5959
6060- Member foreign import syntax
6161
62− A small syntactic addition to the FFI, to support a common use case.
62+ A small syntactic addition to the FFI, to support a common use case.
6363
6464- Make FFI syntax match Haskell
65−
65+
6666 Use `foreign import` instead of `extern`.
6767
6868- Make record declaration syntax match Haskell
6969- Simplify array binders
70−
70+
7171 There are now two types of array binders: cons binders `x : xs -> ...` and array binders `[x, y, z] -> ...` instead of the previously confusing `[x:xs]`.
7272
7373- Array indexing syntax is ambiguous
RELEASE-0.3.md+8−8
@@ -14,40 +14,40 @@ Many thanks to the [contributors](https://github.com/purescript/purescript/graph
1414 sum (x:xs) = x + sum xs
1515
1616- Basic support for type classes has been added. Polymorphic types of the form `forall a. (C a) => ...` will not be inferred but can be checked. Type inference still works if all type class instances can be determined. There is not yet support for functionality like GHC's `FlexibleInstances`, `FlexibleContexts` or `MultiParamTypesClasses`. For example:
17−
17+
1818 class Truthy a where
1919 isTrue :: a -> Boolean
20−
20+
2121 instance Truthy Boolean where
2222 isTrue b = b
23−
23+
2424 instance Truthy String where
2525 isTrue "" = false
2626 isTrue _ = true
27−
27+
2828 ifThenElse :: forall a b. (Truthy a) => a -> b -> b -> b
2929 ifThenElse a tr fa = if isTrue a then tr else fa
3030
3131- There is now support for `do` notation, using the `Monad` type class from the `Prelude` module. For example:
3232
3333 data Maybe = Nothing | Just a
34−
34+
3535 instance Prelude.Monad Maybe where
3636 ret = Just
3737 (>>=) Nothing _ = Nothing
3838 (>>=) (Just a) f = f a
39−
39+
4040 test = do
4141 x <- Just 1
4242 y <- Just 2
4343 ret $ x + y
44−
44+
4545- There is now a better story for side-effects. The `Eff` module in the `Prelude` defines a monad `Eff e` where e is a row of effect types. The kind system now defines a new kind `!` of effects. Row polymorphism allows different native effects to be interleaved. For example:
4646
4747 test = do
4848 trace "Testing"
4949 throwError "Error!"
50−
50+
5151 has inferred type `forall eff. Eff (trace :: Trace | error :: Error String | eff)`.
5252 See the `/examples/passing/Eff.purs` file for a more in-depth set of examples.
5353 Supported native effects currently include `ST`, `Trace`, `Error` and `DOM` (via the `libraries/jquery` module).
RELEASE-0.4.md+8−8
@@ -8,17 +8,17 @@ This release saw major contributions from [a number of new contributors](https:/
88- Try out the latest features [here](http://tryps.functorial.com).
99
1010## Breaking Changes
11−
11+
1212- Multiple argument functions are no longer available.
1313- When used in the browser, PureScript modules are now accessed through `window.PS.<ModuleName>`. The `PS` object name can be changed via the `--browser-namespace` compiler argument.
1414- The `--run-main` argument has been replaced with `--main` which can now accept a module name in which to find the `main` function.
15−
15+
1616### New Features
17−
17+
1818- Dead code elimination. The new compiler argument `--module=` can be used to specify one or more modules that should be kept in the generated code along with their dependencies. If no modules are specified, all code is exported.
19−
19+
2020### Enhancements
21−
21+
2222- The `->` and `[]` types are now usable in type class instances.
2323- The file path is included in syntax error messages.
2424- Most reserved Javascript names (`return`, `const`, etc) are now usable.
@@ -28,9 +28,9 @@ This release saw major contributions from [a number of new contributors](https:/
2828- It is no longer necessary to sort modules in order of dependencies manually.
2929- Case statements matching data constructors no longer generate unnecessary constructor checks at runtime if there is only a single data constructor.
3030- New optimizer rules were added to inline JavaScript's built-in operators.
31−
31+
3232### Bug Fixes
33−
33+
3434- Floats parse correctly.
3535- Using data constructors in pattern matches now works properly across modules.
3636- PureScript modules no longer overwrite global objects with the same name.
@@ -43,7 +43,7 @@ This release saw major contributions from [a number of new contributors](https:/
4343- A bug which allowed skolem variables to escape their scope was add (thanks to Brian McKenna).
4444- Modules containing mutually recursive type synonyms and data declarations now compile correctly.
4545- A number of bugs in the optimizer were addressed.
46−
46+
4747### Libraries
4848
4949- The `Prelude` has been greatly expanded. Definitions for built-in JavaScript operators have been moved into the Prelude.
RELEASE-0.5.md+3−3
@@ -54,7 +54,7 @@
5454- The escape check was removed, since it was too restrictive (paf31)
5555- The binary operator reordering step was greatly simplified (paf31)
5656- The Object type constructor can now be referenced explicitly as `Prim.Object` (with kind `# * -> *`) (paf31)
57−- Optimizations are now enabled by default and can be disabled with the `--no-tco` and `--no-magic-do` flags (garyb)
57+- Optimizations are now enabled by default and can be disabled with the `--no-tco` and `--no-magic-do` flags (garyb)
5858- Unary minus and signed numeric literals are now supported again (paf31, garyb)
5959- Type errors have been simplified, the full trace can be enabled with `--verbose-errors` or `-v` (paf31)
6060- Error messages now display source positions (paf31, garyb)
@@ -63,7 +63,7 @@
6363- `(++)` is now an alias for the Semigroup operator `(<>)` (paf31)
6464- Error messages for classes with undefined or missing members have been improved (garyb)
6565- The SYB dependency was removed, and traversals rewritten by hand, for a large performance increase (paf31)
66−
66+
6767### Bug Fixes
6868
6969- The subsumes relation has been fixed for object types (paf31)
@@ -94,6 +94,6 @@
9494- The `grunt-purescript` plugin has been updated to provide support for new command line options.
9595- There is a new `gulp-purescript` plugin available for compiling with Gulp.
9696
97−### Documentation
97+### Documentation
9898
9999- There is a new `hierarchy` executable which will generate `.dot` diagrams based on the type class hierarchy of a module. The Prelude docs have been updated to include such a type class diagram. (joneshf)
RELEASE-0.7.md+6−6
@@ -12,7 +12,7 @@ positive _ = false
1212but this is not:
1313
1414```haskell
15−positive n | n > 0
15+positive n | n > 0
1616 = true
1717positive _ = false
1818```
@@ -32,20 +32,20 @@ positive _ = false
3232
3333### Breaking Changes
3434
35−-
35+-
3636
3737### New Features
3838
39−-
39+-
4040
4141### Enhancements
4242
43−-
43+-
4444
4545### Libraries
4646
47−-
47+-
4848
4949### Documentation
5050
51−-
51+-
bundle/README+4−4
@@ -1,9 +1,9 @@
1− ____ ____ _ _
2−| _ \ _ _ _ __ ___/ ___| ___ _ __(_)_ __ | |_
1+ ____ ____ _ _
2+| _ \ _ _ _ __ ___/ ___| ___ _ __(_)_ __ | |_
33| |_) | | | | '__/ _ \___ \ / __| '__| | '_ \| __|
4−| __/| |_| | | | __/___) | (__| | | | |_) | |_
4+| __/| |_| | | | __/___) | (__| | | | |_) | |_
55|_| \__,_|_| \___|____/ \___|_| |_| .__/ \__|
6− |_|
6+ |_|
77
88Installation Instructions
99-------------------------
bundle/build.sh+1−1
@@ -4,7 +4,7 @@ SCRIPTPATH=$( cd "$(dirname "$0")" ; pwd -P )
44
55OS=$1
66
7−if [ -z $OS ]
7+if [ -z $OS ]
88then
99 echo "Usage: build.sh osname"
1010 exit 1
bundle/winbuild.sh+3−3
@@ -26,9 +26,9 @@ cp README build/purescript/
2626cp ../LICENSE build/purescript/
2727
2828# Make the binary bundle
29−pushd build
29+pushd build
3030tar -zcvf ../win64.tar.gz purescript
31−popd
31+popd
3232
3333# Calculate the MD5 hash
3434md5sum win64.tar.gz > win64.md5
@@ -36,5 +36,5 @@ md5sum win64.tar.gz > win64.md5
3636# Remove the staging directory
3737rm -rf build/
3838
39−popd
39+popd
4040
examples/failing/DuplicateDeclarationsInLet.pursnew file+9
@@ -0,0 +1,9 @@
1+module Main where
2+
3+foo = a
4+ where
5+ a :: Number
6+ a = 1
7+
8+ a :: Number
9+ a = 2
examples/failing/NewtypeMultiArgs.purs+1−1
@@ -1,3 +1,3 @@
11module Main where
22
3−newtype Thing = Thing String Boolean
3+newtype Thing = Thing String Boolean
examples/failing/NewtypeMultiCtor.purs+1−1
@@ -1,3 +1,3 @@
11module Main where
22
3−newtype Thing = Thing String | Other
3+newtype Thing = Thing String | Other
examples/failing/SkolemEscape2.purs+1−1
@@ -6,4 +6,4 @@ import Control.Monad.ST
66
77test _ = do
88 r <- runST (newSTRef 0)
9− return 0
9+ return 0
examples/failing/UnknownType.purs+1−1
@@ -1,4 +1,4 @@
11module Main where
22
33test :: Number -> Something
4−test = {}
4+test = {}
examples/failing/UnknownValue.pursdeleted−25
@@ -1,25 +0,0 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff
5−import Control.Monad.ST
6−import Debug.Trace
7−
8−test = runSTArray (do
9− a <- newSTArray 2 0
10− pokeSTArray a 0 1
11− pokeSTArray a 1 2
12− return a)
13−
14−fromTo lo hi = runSTArray (do
15− arr <- newSTArray (hi - lo + 1) 0
16− (let
17− go lo hi _ arr | lo > hi = return arr
18− go lo hi i arr = do
19− pokeSTArray arrr i lo
20− go (lo + 1) hi (i + 1) arr
21− in go lo hi 0 arr))
22−
23−main = do
24− let t1 = runPure (fromTo 10 20)
25− trace "Done"
examples/manual/failing/ArgLengthMismatch.purs+1−1
@@ -1,4 +1,4 @@
11module ArgLengthMismatch where
22
33 f x y = true
4− f = false
4+ f = false
examples/manual/failing/ExportExplicit.purs+1−1
@@ -2,4 +2,4 @@
22module M1 (x, y, z) where
33
44 x = 1
5− y = 2
5+ y = 2
examples/manual/failing/ExportExplicit1.purs+2−2
@@ -5,9 +5,9 @@ module M1 (X(X)) where
55module Main where
66
77 import M1
8−
8+
99 testX = X
10−
10+
1111 -- should fail as Y constructor is not exported from M1
1212 testY = Y
1313
examples/manual/failing/ExportExplicit2.purs+1−1
@@ -2,4 +2,4 @@
22module M1 (X(Y)) where
33
44 data X = X
5− data Y = Y
5+ data Y = Y
examples/manual/failing/ExportExplicit3.purs+1−1
@@ -6,7 +6,7 @@ module M1 (X(..)) where
66module Main where
77
88 import M1
9−
9+
1010 -- should fail as Z is not exported from M1
1111 testZ = M1.Z
1212
examples/manual/failing/RedefinedFixity.purs+1−1
@@ -1,6 +1,6 @@
11module RedefinedFixity where
22
33 (!?) x y = x + y
4−
4+
55 infix 2 !?
66 infix 2 !?
examples/manual/failing/RequiredHiddenType.purs+2−2
@@ -3,6 +3,6 @@ module Foo (B(..), a, b) where
33
44 data A = A
55 data B = B
6−
6+
77 a = A
8− b = B
8+ b = B
examples/manual/passing/ExportExplicit.purs+2−2
@@ -3,7 +3,7 @@ module M1 (X(X), Z(..), foo) where
33 data X = X | Y
44 data Z = Z
55
6− foo :: Number
6+ foo :: Number
77 foo = 0
88
99 bar :: Number
@@ -12,7 +12,7 @@ module M1 (X(X), Z(..), foo) where
1212module Main where
1313
1414 import M1
15−
15+
1616 testX = X
1717 testZ = Z
1818 testFoo = foo
examples/manual/passing/ExportExplicit2.purs+1−1
@@ -1,6 +1,6 @@
11module M1 (bar) where
22
3− foo :: Number
3+ foo :: Number
44 foo = 0
55
66 bar :: Number
examples/manual/passing/Import.purs+1−1
@@ -13,7 +13,7 @@ module M2 where
1313 import M1
1414
1515 main = \_ -> foo 42
16−
16+
1717module Main where
1818
1919main = Debug.Trace.trace "Done"
examples/manual/passing/ImportExplicit.purs+1−1
@@ -7,7 +7,7 @@ module Main where
77
88 import M1 (X(..))
99
10− testX :: X
10+ testX :: X
1111 testX = X
1212 testY = Y
1313
examples/manual/passing/ImportQualified.purs+3−3
@@ -1,5 +1,5 @@
11module M1 where
2−
2+
33 trace x = x
44
55module Main where
@@ -8,5 +8,5 @@ module Main where
88 import Control.Monad.Eff
99 import M1
1010 import qualified Debug.Trace as T
11−
12− main = T.trace (trace "Done")
11+
12+ main = T.trace (trace "Done")
examples/manual/passing/Module.purs+1−1
@@ -22,7 +22,7 @@ module M2 where
2222
2323 match :: M1.Foo -> String
2424 match = \f -> case f of M1.Foo s -> s ++ "foo"
25−
25+
2626module Main where
2727
2828main = Debug.Trace.trace "Done"
examples/manual/passing/ModuleDeps.purs+1−1
@@ -11,7 +11,7 @@ bar = M3.baz
1111module M3 where
1212
1313baz = 1
14−
14+
1515module Main where
1616
1717main = Debug.Trace.trace "Done"
examples/passing/810.pursnew file+11
@@ -0,0 +1,11 @@
1+module Main where
2+
3+data Maybe a = Nothing | Just a
4+
5+test :: forall a. Maybe a -> Maybe a
6+test m = o.x
7+ where
8+ o = case m of Nothing -> { x : Nothing }
9+ Just a -> { x : Just a }
10+
11+main = Debug.Trace.trace "Done"
examples/passing/BindersInFunctions.purs+7−5
@@ -5,12 +5,14 @@ import Prelude
55tail = \(_:xs) -> xs
66
77foreign import error
8− "function error(msg) {\
9− \ throw msg;\
10− \}" :: forall a. String -> a
8+ """
9+ function error(msg) {
10+ throw msg;
11+ }
12+ """ :: forall a. String -> a
1113
12−main =
14+main =
1315 let ts = tail [1, 2, 3] in
14− if ts == [2, 3]
16+ if ts == [2, 3]
1517 then Debug.Trace.trace "Done"
1618 else error "Incorrect result from 'tails'."
examples/passing/BindingGroups.purs+2−2
@@ -1,6 +1,6 @@
11module Main where
2−
3−foo = bar
2+
3+foo = bar
44 where bar r = r + 1
55
66r = foo 2
examples/passing/CheckFunction.pursnew file+5
@@ -0,0 +1,5 @@
1+module Main where
2+
3+test = ((\x -> x+1) >>> (\x -> x*2)) 4
4+
5+main = Debug.Trace.trace "Done"
examples/passing/CheckSynonymBug.purs+6−4
@@ -2,12 +2,14 @@ module Main where
22
33 import Prelude
44
5− type Foo a = [a]
5+ type Foo a = [a]
66
77 foreign import length
8− "function length(a) {\
9− \ return a.length;\
10− \}" :: forall a. [a] -> Number
8+ """
9+ function length(a) {
10+ return a.length;
11+ }
12+ """ :: forall a. [a] -> Number
1113
1214 foo _ = length ([] :: Foo Number)
1315
examples/passing/Comparisons.purs+8−6
@@ -6,12 +6,14 @@ import Debug.Trace
66foreign import data Assert :: !
77
88foreign import assert
9− "function assert(x) {\
10− \ return function () {\
11− \ if (!x) throw new Error('assertion failed');\
12− \ return {};\
13− \ };\
14− \};" :: forall e. Boolean -> Eff (assert :: Assert | e) Unit
9+ """
10+ function assert(x) {
11+ return function() {
12+ if (!x) throw new Error('assertion failed');
13+ return {};
14+ };
15+ }
16+ """ :: forall e. Boolean -> Eff (assert :: Assert | e) Unit
1517
1618main = do
1719 assert (1 < 2)
examples/passing/Conditional.purs+1−1
@@ -2,7 +2,7 @@ module Main where
22
33 import Prelude ()
44
5− fns = \f -> if f true then f else \x -> x
5+ fns = \f -> if f true then f else \x -> x
66
77 not = \x -> if x then false else true
88
examples/passing/Console.purs+1−1
@@ -9,5 +9,5 @@ replicateM_ 0 _ = return {}
99replicateM_ n act = do
1010 act
1111 replicateM_ (n - 1) act
12−
12+
1313main = replicateM_ 10 (trace "Hello World!")
examples/passing/DeepArrayBinder.purs+6−4
@@ -6,10 +6,12 @@ match2 :: [Number] -> Number
66match2 (x : y : xs) = x * y + match2 xs
77match2 _ = 0
88
9−foreign import explode
10− "function explode() {\
11− \ throw new Error('Incorrect result');\
12− \}" :: forall eff a. Eff eff a
9+foreign import explode
10+ """
11+ function explode() {
12+ throw new Error('Incorrect result');
13+ }
14+ """ :: forall eff a. Eff eff a
1315
1416main = case match2 [1, 2, 3, 4, 5, 6, 7, 8, 9] of
1517 100 -> Debug.Trace.trace "Done"
examples/passing/DeepCase.purs+2−2
@@ -4,9 +4,9 @@ import Debug.Trace
44import Control.Monad.Eff
55import Control.Monad.ST
66
7−f x y =
7+f x y =
88 let
9− g = case y of
9+ g = case y of
1010 0 -> x
1111 x -> 1 + x * x
1212 in g + x + y
examples/passing/Dollar.purs+1−1
@@ -12,5 +12,5 @@ id x = x
1212test1 x = id $ id $ id $ id $ x
1313
1414test2 x = id id $ id x
15−
15+
1616main = Debug.Trace.trace "Done"
examples/passing/EmptyDataDecls.purs+12−8
@@ -11,19 +11,23 @@ nil :: forall a. ArrayBox Z a
1111nil = ArrayBox []
1212
1313foreign import concat
14− "function concat(l1) {\
15− \ return function (l2) {\
16− \ return l1.concat(l2);\
17− \ };\
18− \}" :: forall a. [a] -> [a] -> [a]
14+ """
15+ function concat(l1) {
16+ return function(l2) {
17+ return l1.concat(l2);
18+ };
19+ }
20+ """ :: forall a. [a] -> [a] -> [a]
1921
2022cons' :: forall a n. a -> ArrayBox n a -> ArrayBox (S n) a
2123cons' x (ArrayBox xs) = ArrayBox $ concat [x] xs
2224
2325foreign import error
24− "function error(msg) {\
25− \ throw msg;\
26− \}" :: forall a. String -> a
26+ """
27+ function error(msg) {
28+ throw msg;
29+ }
30+ """ :: forall a. String -> a
2731
2832main = case cons' 1 $ cons' 2 $ cons' 3 nil of
2933 ArrayBox [1, 2, 3] -> Debug.Trace.trace "Done"
examples/passing/EmptyRow.purs+1−1
@@ -1,6 +1,6 @@
11module Main where
22
3−data Foo r = Foo { | r }
3+data Foo r = Foo { | r }
44
55test :: Foo ()
66test = Foo {}
examples/passing/ExtendedInfixOperators.pursnew file+20
@@ -0,0 +1,20 @@
1+module Main where
2+
3+zipWith :: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
4+zipWith _ [] _ = []
5+zipWith _ _ [] = []
6+zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
7+
8+test1 = [1, 2, 3] `zipWith (+)` [4, 5, 6]
9+
10+comparing :: forall a b. (Ord b) => (a -> b) -> a -> a -> Ordering
11+comparing f = compare `Data.Function.on` f
12+
13+sum [] = 0
14+sum (x:xs) = x + sum xs
15+
16+test2 = [1, 2, 3] `comparing sum` [4, 5, 6]
17+
18+main = do
19+ Debug.Trace.print test1
20+ Debug.Trace.print test2
examples/passing/ExternRaw.purs+20−7
@@ -1,13 +1,26 @@
11module Main where
22
3−foreign import first "function first(xs) { return xs[0]; }" :: forall a. [a] -> a
3+foreign import first
4+ """
5+ function first(xs) {
6+ return xs[0];
7+ }
8+ """ :: forall a. [a] -> a
49
5−foreign import loop "function loop() { while (true) {} }" :: forall a. a
10+foreign import loop
11+ """
12+ function loop() {
13+ while (true) {}
14+ }
15+ """ :: forall a. a
616
7−foreign import concat "function concat(xs) { \
8− \ return function(ys) { \
9− \ return xs.concat(ys); \
10− \ };\
11− \}" :: forall a. [a] -> [a] -> [a]
17+foreign import concat
18+ """
19+ function concat(xs) {
20+ return function(ys) {
21+ return xs.concat(ys);
22+ };
23+ }
24+ """ :: forall a. [a] -> [a] -> [a]
1225
1326main = Debug.Trace.trace "Done"
examples/passing/FFI.purs+6−4
@@ -1,9 +1,11 @@
11module Main where
22
3−foreign import foo
4− "function foo(s) {\
5− \ return s;\
6− \}" :: String -> String
3+foreign import foo
4+ """
5+ function foo(s) {
6+ return s;
7+ }
8+ """ :: String -> String
79
810bar :: String -> String
911bar _ = foo "test"
examples/passing/FinalTagless.purs+1−1
@@ -5,7 +5,7 @@ import Prelude
55class E e where
66 num :: Number -> e Number
77 add :: e Number -> e Number -> e Number
8−
8+
99type Expr a = forall e. (E e) => e a
1010
1111data Id a = Id a
examples/passing/FunctionScope.purs+6−4
@@ -5,10 +5,12 @@ module Main where
55 mkValue :: Number -> Number
66 mkValue id = id
77
8− foreign import error
9− "function error(msg) {\
10− \ throw msg;\
11− \}" :: forall a. String -> a
8+ foreign import error
9+ """
10+ function error(msg) {
11+ throw msg;
12+ }
13+ """ :: forall a. String -> a
1214
1315 main = do
1416 let value = mkValue 1
examples/passing/Functions2.purs+5−3
@@ -6,9 +6,11 @@ module Main where
66 test = \const _ -> const
77
88 foreign import error
9− "function error(msg) {\
10− \ throw msg;\
11− \}" :: forall a. String -> a
9+ """
10+ function error(msg) {
11+ throw msg;
12+ }
13+ """ :: forall a. String -> a
1214
1315 main = do
1416 let value = test "Done" {}
examples/passing/Guards.purs+2−2
@@ -21,9 +21,9 @@ module Main where
2121 | otherwise -> m
2222
2323 testIndentation :: Number -> Number -> Number
24− testIndentation x y | x > 0
24+ testIndentation x y | x > 0
2525 = x + y
26− | otherwise
26+ | otherwise
2727 = y - x
2828
2929 main = Debug.Trace.trace $ min "Done" "ZZZZ"
examples/passing/HoistError.purs+7−5
@@ -4,11 +4,13 @@ import Control.Monad.Eff
44import Debug.Trace
55
66foreign import f
7− "function f(x) {\
8− \ return function () {\
9− \ if (x !== 0) throw new Error('x is not 0');\
10− \ }\
11− \}" :: forall e. Number -> Eff e Number
7+ """
8+ function f(x) {
9+ return function() {
10+ if (x !== 0) throw new Error('x is not 0');
11+ };
12+ }
13+ """ :: forall e. Number -> Eff e Number
1214
1315main = do
1416 let x = 0
examples/passing/JSReserved.purs+2−2
@@ -4,9 +4,9 @@ module Main where
44
55 yield = 0
66 member = 1
7−
7+
88 public = \return -> return
9−
9+
1010 this catch = catch
1111
1212 main = Debug.Trace.trace "Done"
examples/passing/KindedType.purs+1−1
@@ -26,6 +26,6 @@ class Clazz (a :: *) where
2626 def :: a
2727
2828instance clazzString :: Clazz String where
29− def = "test"
29+ def = "test"
3030
3131main = Debug.Trace.trace "Done"
examples/passing/Let.purs+7−7
@@ -4,12 +4,12 @@ import Prelude
44import Control.Monad.Eff
55import Control.Monad.ST
66
7−test1 x = let
7+test1 x = let
88 y :: Number
9− y = x + 1
9+ y = x + 1
1010 in y
1111
12−test2 x y =
12+test2 x y =
1313 let x' = x + 1 in
1414 let y' = y + 1 in
1515 x' + y'
@@ -17,10 +17,10 @@ test2 x y =
1717test3 = let f x y z = x + y + z in
1818 f 1 2 3
1919
20−test4 = let f x [y, z] = x y z in
20+test4 = let f x [y, z] = x y z in
2121 f (+) [1, 2]
2222
23−test5 = let
23+test5 = let
2424 f x | x > 0 = g (x / 2) + 1
2525 f x = 0
2626 g x = f (x - 1) + 1
@@ -42,12 +42,12 @@ test7 = let
4242 in if f true then f 1 else f 2
4343
4444test8 :: Number -> Number
45−test8 x = let
45+test8 x = let
4646 go y | (x - 0.1 < y * y) && (y * y < x + 0.1) = y
4747 go y = go $ (y + x / y) / 2
4848 in go x
4949
50−test10 _ =
50+test10 _ =
5151 let
5252 f x = g x * 3
5353 g x = f x / 2
examples/passing/Monad.purs+2−2
@@ -17,12 +17,12 @@ module Main where
1717 maybe = { return : Just
1818 , bind : \ma f -> case ma of
1919 Nothing -> Nothing
20− Just a -> f a
20+ Just a -> f a
2121 }
2222
2323 test :: forall m. Monad m -> m Number
2424 test = \m -> m.bind (m.return 1) (\n1 ->
25− m.bind (m.return "Test") (\n2 ->
25+ m.bind (m.return "Test") (\n2 ->
2626 m.return n1))
2727
2828 test1 = test id
examples/passing/MutRec.purs+1−1
@@ -1,4 +1,4 @@
1−module Main where
1+module Main where
22
33 import Prelude
44
examples/passing/MutRec2.purs+1−1
@@ -1,7 +1,7 @@
11module Main where
22
33data A = A B
4−
4+
55data B = B A
66
77foreign import data S :: *
examples/passing/MutRec3.purs+1−1
@@ -1,7 +1,7 @@
11module Main where
22
33data A = A B
4−
4+
55data B = B A
66
77foreign import data S :: *
examples/passing/NamedPatterns.purs+1−1
@@ -1,6 +1,6 @@
11module Main where
22
3− foo = \x -> case x of
3+ foo = \x -> case x of
44 y@{ foo = "Foo" } -> y
55 y -> y
66
examples/passing/Newtype.purs+3−3
@@ -12,11 +12,11 @@ newtype Box a = Box a
1212
1313instance showBox :: (Show a) => Show (Box a) where
1414 show (Box x) = "Box " ++ show x
15−
15+
1616apply f x = f x
17−
17+
1818main = do
1919 print $ Thing "hello"
2020 print $ Box 42
2121 print $ apply Box 9000
22− trace "Done"
22+ trace "Done"
examples/passing/NewtypeWithRecordUpdate.pursnew file+15
@@ -0,0 +1,15 @@
1+-- https://github.com/purescript/purescript/issues/812
2+
3+module Main where
4+
5+import Debug.Trace
6+
7+newtype NewType a = NewType (Object a)
8+
9+rec1 :: Object (a :: Number, b :: Number, c:: Number)
10+rec1 = { a: 0, b: 0, c: 0 }
11+
12+rec2 :: NewType (a :: Number, b :: Number, c :: Number)
13+rec2 = NewType (rec1 { a = 1 })
14+
15+main = trace "Done"
examples/passing/ObjectGetter.pursnew file+11
@@ -0,0 +1,11 @@
1+module Main where
2+
3+getX = _.x
4+
5+point = { x: 1, y: 0 }
6+
7+main = do
8+ Debug.Trace.print $ getX point
9+ Debug.Trace.trace $ _." 123 string Prop Name " { " 123 string Prop Name ": "OK" }
10+ Debug.Trace.trace $ (_.x >>> _.y) { x: { y: "Nested" } }
11+ Debug.Trace.trace $ _.value { value: "Done!" }
examples/passing/ObjectSynonym.purs+1−1
@@ -10,4 +10,4 @@ type Outer = { inner :: Inner }
1010outer :: Outer
1111outer = { inner: inner }
1212
13−main = Debug.Trace.trace "Done"
13+main = Debug.Trace.trace "Done"
examples/passing/ObjectUpdate2.purs+1−1
@@ -7,7 +7,7 @@ foreign import x "var x = {};" :: forall r. X r
77blah :: forall r. X r -> X r
88blah x = x
99
10−test = blah x
10+test = blah x
1111 { baz = "blah"
1212 }
1313
examples/passing/ObjectUpdater.pursnew file+35
@@ -0,0 +1,35 @@
1+module Main where
2+
3+import Control.Monad.Eff
4+import Debug.Trace
5+
6+foreign import eqeqeq
7+ """
8+ function eqeqeq(x) {
9+ return function (y) {
10+ if (x == y) return x;
11+ throw new Error("Unexpected result: " + x + " /== " + y);
12+ };
13+ };
14+ """ :: forall a. a -> a -> a
15+
16+(===) = eqeqeq
17+infixl 4 ===
18+
19+getValue :: forall e. Eff (| e) Boolean
20+getValue = return true
21+
22+main = do
23+ let record = { value: false }
24+ record' <- record { value = _ } <$> getValue
25+ print $ record'.value === true
26+
27+ let point = { x: 1, y: 1 }
28+ x = 10
29+ point' = (point { x = _, y = x }) 100
30+
31+ print $ point'.x === 100
32+ print $ point'.y === 10
33+
34+ let record2 = (_ { x = _ }) { x: 0 } 10
35+ print $ record2.x === 10
examples/passing/ObjectWildcards.pursnew file+31
@@ -0,0 +1,31 @@
1+module Main where
2+
3+import Control.Monad.Eff
4+import Debug.Trace
5+
6+mkRecord = { foo: _, bar: _, baz: "baz" }
7+
8+getValue :: forall e. Eff (| e) Boolean
9+getValue = return true
10+
11+foreign import eqeqeq
12+ """
13+ function eqeqeq(x) {
14+ return function (y) {
15+ if (x == y) return x;
16+ throw new Error("Unexpected result: " + x + " /== " + y);
17+ };
18+ };
19+ """ :: forall a. a -> a -> a
20+
21+(===) = eqeqeq
22+infixl 4 ===
23+
24+main = do
25+ obj <- { value: _ } <$> getValue
26+ print obj.value
27+ let x = 1
28+ point <- { x: _, y: x } <$> return 2
29+ print $ point.x === 2
30+ print $ point.y === 1
31+ trace (mkRecord 1 "Done!").bar
examples/passing/Objects.purs+1−1
@@ -31,5 +31,5 @@ module Main where
3131 { "***": n } -> n
3232
3333 test7 {a: snoog , b : blah } = blah
34−
34+
3535 main = Debug.Trace.trace "Done"
examples/passing/OneConstructor.purs+1−1
@@ -2,6 +2,6 @@ module Main where
22
33data One a = One a
44
5−one (One a) = a
5+one' (One a) = a
66
77main = Debug.Trace.trace "Done"
examples/passing/OperatorAssociativity.purs+34−7
@@ -1,15 +1,42 @@
11module Main where
22
33import Control.Monad.Eff
4+import Debug.Trace
5+
6+foreign import data Assert :: !
7+
8+foreign import assert
9+ """
10+ function assert(x) {
11+ return function(desc) {
12+ return function() {
13+ if (!x) throw new Error('assertion (' + desc + ') failed');
14+ return {};
15+ };
16+ };
17+ }
18+ """ :: forall e. Boolean -> String -> Eff (assert :: Assert | e) Unit
419
520bug :: Number -> Number -> Number
621bug a b = 0 - (a - b)
722
8−foreign import explode
9− "function explode() {\
10− \ throw new Error('Assertion failed!');\
11− \}":: forall eff a. Eff eff a
23+foreign import explode
24+ """
25+ function explode() {
26+ throw new Error('Assertion failed!');
27+ }
28+ """ :: forall eff a. Eff eff a
29+
30+main = do
31+ assert (bug 0 2 == 2) "bug 0 2 == 2"
32+ assert (0 - (0 - 2) == 2) "0 - (0 - 2) == 2"
33+ assert (0 - (0 + 2) == -2) "0 - (0 + 2) == -2"
34+
35+ assert (6 / (3 * 2) == 1) "6 / (3 * 2) == 1"
36+ assert ((6 / 3) * 2 == 4) "(6 / 3) * 2 == 4"
37+
38+ assert (6 % (2 * 2) == 2) "6 % (2 * 2) == 2"
39+ assert ((6 % 2) * 2 == 0) "(6 % 2) * 2 == 0"
1240
13−main = case bug 0 2 of
14− 2 -> Debug.Trace.trace "Done!"
15− _ -> explode
41+ assert (4 % (9 / 3) == 1) "4 % (9 / 3) == 1"
42+ assert ((4 % 9) / 2 == 2) "(4 % 9) / 2 == 2"
examples/passing/OperatorSections.pursnew file+21
@@ -0,0 +1,21 @@
1+module Main where
2+
3+foreign import eqeqeq
4+ """
5+ function eqeqeq(x) {
6+ return function (y) {
7+ if (x == y) return x;
8+ throw new Error("Unexpected result: " + x + " /== " + y);
9+ };
10+ };
11+ """ :: forall a. a -> a -> a
12+
13+(===) = eqeqeq
14+infixl 4 ===
15+
16+main = do
17+ Debug.Trace.print $ (/ 2) 4 === 2
18+ Debug.Trace.print $ (2 /) 4 === 0.5
19+ Debug.Trace.print $ (`const` 1) 2 === 2
20+ Debug.Trace.print $ (1 `const`) 2 === 1
21+ Debug.Trace.trace "Done!"
examples/passing/Operators.purs+23−5
@@ -2,7 +2,7 @@ module Main where
22
33 import Control.Monad.Eff
44 import Debug.Trace
5−
5+
66 (?!) :: forall a. a -> a -> a
77 (?!) x _ = x
88
@@ -29,7 +29,7 @@ module Main where
2929
3030 test6 = ((\x -> x) `k` 2) 3
3131
32− (<+>) :: String -> String -> String
32+ (<+>) :: String -> String -> String
3333 (<+>) = \s1 s2 -> s1 ++ s2
3434
3535 test7 = "Hello" <+> "World!"
@@ -39,7 +39,7 @@ module Main where
3939
4040 foo :: String -> String
4141 foo = \s -> s
42−
42+
4343 test8 = foo @@ "Hello World"
4444
4545 test9 = Main.foo @@ "Hello World"
@@ -52,7 +52,7 @@ module Main where
5252 test11 = [1, 2, 3] ... [4, 5, 6]
5353
5454 test12 (<%>) a b = a <%> b
55−
55+
5656 test13 = \(<%>) a b -> a <%> b
5757
5858 test14 :: Number -> Number -> Boolean
@@ -61,9 +61,23 @@ module Main where
6161 test15 :: Number -> Number -> Boolean
6262 test15 a b = const false $ a `test14` b
6363
64− test16 :: Number -> Number -> Number
64+ test16 :: Number -> Number -> Number
6565 test16 x y = x .|. y .&. y
6666
67+ test17 :: Number
68+ test17 = negate (-1)
69+
70+ test18 :: Number
71+ test18 = negate $ negate 1
72+
73+ test19 :: Number
74+ test19 = negate $ negate (-1)
75+
76+ test20 :: Number
77+ test20 = 1 @ 2
78+ where
79+ (@) x y = x + y * y
80+
6781 main = do
6882 let t1 = test1 1 2 (\x y -> x + y)
6983 let t2 = test2
@@ -81,4 +95,8 @@ module Main where
8195 let t14 = test14 1 2
8296 let t15 = test15 1 2
8397 let t16 = test16 1 2
98+ let t17 = test17
99+ let t18 = test18
100+ let t19 = test19
101+ let t20 = test20
84102 trace "Done"
examples/passing/OptimizerBug.purs+1−1
@@ -5,5 +5,5 @@ import Prelude
55x a = 1 + y a
66
77y a = x a
8−
8+
99main = Debug.Trace.trace "Done"
examples/passing/PartialFunction.purs+10−8
@@ -1,14 +1,16 @@
11module Main where
22
33foreign import testError
4− "function testError(f) {\
5− \ try {\
6− \ return f();\
7− \ } catch (e) {\
8− \ if (e instanceof Error) return 'success';\
9− \ throw new Error('Pattern match failure is not Error');\
10− \ }\
11− \}" :: (Unit -> Number) -> String
4+ """
5+ function testError(f) {
6+ try {
7+ return f();
8+ } catch (e) {
9+ if (e instanceof Error) return 'success';
10+ throw new Error('Pattern match failure is not Error');
11+ }
12+ }
13+ """ :: (Unit -> Number) -> String
1214
1315fn :: Number -> Number
1416fn 0 = 0
examples/passing/Patterns.purs+3−3
@@ -2,7 +2,7 @@ module Main where
22
33 import Prelude
44
5− test = \x -> case x of
5+ test = \x -> case x of
66 { str = "Foo", bool = true } -> true
77 { str = "Bar", bool = b } -> b
88 _ -> false
@@ -17,12 +17,12 @@ module Main where
1717 _ -> 0
1818
1919
20− h = \o -> case o of
20+ h = \o -> case o of
2121 a@[_,_,_] -> a
2222 _ -> []
2323
2424 isDesc :: [Number] -> Boolean
2525 isDesc [x, y] | x > y = true
2626 isDesc _ = false
27−
27+
2828 main = Debug.Trace.trace "Done"
examples/passing/Person.purs+8−6
@@ -4,13 +4,15 @@ module Main where
44
55 data Person = Person { name :: String, age :: Number }
66
7− foreign import itoa
8− "function itoa(n) {\
9− \ return n.toString();\
10− \}" :: Number -> String
11−
7+ foreign import itoa
8+ """
9+ function itoa(n) {
10+ return n.toString();
11+ }
12+ """ :: Number -> String
13+
1214 showPerson :: Person -> String
1315 showPerson = \p -> case p of
1416 Person o -> o.name ++ ", aged " ++ itoa(o.age)
15−
17+
1618 main = Debug.Trace.trace "Done"
examples/passing/Rank2Data.purs+7−7
@@ -12,18 +12,18 @@ module Main where
1212 runNat = \nat -> case nat of
1313 Nat f -> f 0 (\n -> n + 1)
1414
15− zero = Nat (\zero _ -> zero)
15+ zero' = Nat (\zero' _ -> zero')
1616
1717 succ = \n -> case n of
18− Nat f -> Nat (\zero succ -> succ (f zero succ))
18+ Nat f -> Nat (\zero' succ -> succ (f zero' succ))
1919
2020 add = \n m -> case n of
2121 Nat f -> case m of
22− Nat g -> Nat (\zero succ -> g (f zero succ) succ)
22+ Nat g -> Nat (\zero' succ -> g (f zero' succ) succ)
2323
24− one = succ zero
25− two = succ zero
24+ one' = succ zero'
25+ two = succ zero'
2626 four = add two two
2727 fourNumber = runNat four
28−
29− main = Debug.Trace.trace "Done"
28+
29+ main = Debug.Trace.trace "Done'"
examples/passing/Rank2TypeSynonym.purs+2−2
@@ -3,10 +3,10 @@ module Main where
33import Control.Monad.Eff
44
55type Foo a = forall f. (Monad f) => f a
6−
6+
77foo :: forall a. a -> Foo a
88foo x = pure x
9−
9+
1010bar :: Foo Number
1111bar = foo 3
1212
examples/passing/Rank2Types.purs+1−1
@@ -7,5 +7,5 @@ module Main where
77
88 forever :: forall m a b. (forall a b. m a -> (a -> m b) -> m b) -> m a -> m b
99 forever = \bind action -> bind action $ \_ -> forever bind action
10−
10+
1111 main = Debug.Trace.trace "Done"
examples/passing/Recursion.purs+1−1
@@ -6,5 +6,5 @@ module Main where
66 0 -> 1
77 1 -> 1
88 n -> fib (n - 1) + fib (n - 2)
9−
9+
1010 main = Debug.Trace.trace "Done"
examples/passing/RowPolyInstanceContext.pursnew file+20
@@ -0,0 +1,20 @@
1+module Main where
2+
3+class T s m where
4+ state :: (s -> s) -> m Unit
5+
6+data S s a = S (s -> { new :: s, ret :: a })
7+
8+instance st :: T s (S s) where
9+ state f = S $ \s -> { new: f s, ret: unit }
10+
11+test1 :: forall r . S { foo :: String | r } Unit
12+test1 = state $ \o -> o { foo = o.foo ++ "!" }
13+
14+test2 :: forall m r . (T { foo :: String | r } m) => m Unit
15+test2 = state $ \o -> o { foo = o.foo ++ "!" }
16+
17+main = do
18+ let t1 = test1
19+ let t2 = test2
20+ Debug.Trace.trace "Done"
examples/passing/RowSynonyms.pursnew file+46
@@ -0,0 +1,46 @@
1+module Main where
2+
3+import Control.Monad.Eff
4+import Control.Monad.ST
5+
6+type State bindings =
7+ {
8+ bindings :: {addition :: Number | bindings},
9+ other :: String
10+ }
11+
12+type MyBindings = (test :: Number)
13+
14+data Shadow bindings = Shadow String
15+
16+shadows :: Shadow (Object MyBindings)
17+shadows = Shadow "uhh"
18+
19+main :: Eff () Unit
20+main = withIt
21+ shadows
22+ \ bindings -> do
23+ let state =
24+ {
25+ bindings : bindings,
26+ other : "Test"
27+ }
28+ runST do
29+ stRef <- newSTRef state
30+ handleKeyD stRef
31+ return unit
32+
33+
34+withIt :: forall bindings eff a. Shadow (Object bindings) ->
35+ ({addition :: Number | bindings} -> Eff eff a) -> Eff eff a
36+withIt (Shadow str) success = do
37+ b <- withBindings
38+ success (b{addition = 1})
39+
40+foreign import withBindings
41+"""
42+ function withBindings() {}
43+""" :: forall eff bindings. Eff eff bindings
44+
45+handleKeyD :: forall h eff. STRef h (State MyBindings) -> Eff (st :: ST h | eff) Unit
46+handleKeyD state = return unit
examples/passing/ScopedTypeVariables.pursnew file+34
@@ -0,0 +1,34 @@
1+module Main where
2+
3+test1 :: forall a. (a -> a) -> a -> a
4+test1 f x = g (g x)
5+ where
6+ g :: a -> a
7+ g y = f (f y)
8+
9+test2 :: forall a. (a -> a) -> a -> a
10+test2 = h
11+ where
12+ h :: forall b. (b -> b) -> b -> b
13+ h f x = g (g x)
14+ where
15+ g :: b -> b
16+ g y = f (f y)
17+
18+test3 :: Number
19+test3 = ((\b -> b :: b) :: forall b. b -> b) 0
20+
21+test4 :: forall a. (a -> a) -> a -> a
22+test4 = h
23+ where
24+ h :: forall b. (b -> b) -> b -> b
25+ h f x = g (g x)
26+ where
27+ g :: b -> b
28+ g y = j (f (f y))
29+ where
30+ j :: forall b. b -> b
31+ j x = x
32+
33+
34+main = Debug.Trace.trace "Done"
examples/passing/Sequence.purs+2−2
@@ -4,9 +4,9 @@ import Control.Monad.Eff
44
55class Sequence t where
66 sequence :: forall m a. (Monad m) => t (m a) -> m (t a)
7−
7+
88instance sequenceArray :: Sequence [] where
99 sequence [] = pure []
10− sequence (x:xs) = (:) <$> x <*> sequence xs
10+ sequence (x:xs) = (:) <$> x <*> sequence xs
1111
1212main = sequence $ [Debug.Trace.trace "Done"]
examples/passing/ShadowedRename.purs+7−5
@@ -4,11 +4,13 @@ import Control.Monad.Eff
44import Debug.Trace
55
66foreign import f
7− "function f(x) {\
8− \ return function () {\
9− \ if (x !== 2) throw new Error('x is not 2');\
10− \ }\
11− \}" :: forall e. Number -> Eff e Number
7+ """
8+ function f(x) {
9+ return function() {
10+ if (x !== 2) throw new Error('x is not 2');
11+ };
12+ }
13+ """ :: forall e. Number -> Eff e Number
1214
1315foo foo = let foo_1 = \_ -> foo
1416 foo_2 = foo_1 unit + 1
examples/passing/ShadowedTCO.purs+5−5
@@ -2,14 +2,14 @@ module Main where
22
33runNat f = f 0 (\n -> n + 1)
44
5−zero z _ = z
5+zero' z _ = z
66
7−succ f zero succ = succ (f zero succ)
7+succ f zero' succ = succ (f zero' succ)
88
9−add f g zero succ = g (f zero succ) succ
9+add f g zero' succ = g (f zero' succ) succ
1010
11−one = succ zero
12−two = succ one
11+one' = succ zero'
12+two = succ one'
1313four = add two two
1414fourNumber = runNat four
1515
examples/passing/ShadowedTCOLet.purs+3−3
@@ -1,7 +1,7 @@
11module Main where
22
3−f x y z =
4− let f 1 2 3 = 1
3+f x y z =
4+ let f 1 2 3 = 1
55 in f x z y
6−
6+
77main = Debug.Trace.trace $ show $ f 1 3 2
examples/passing/SignedNumericLiterals.purs+2−2
@@ -6,10 +6,10 @@ module Main where
66 y = -0.5
77 z = 0.5
88 w = 1
9−
9+
1010 f :: Number -> Number
1111 f x = -x
1212
1313 test1 = 2 - 1
14−
14+
1515 main = Debug.Trace.trace "Done"
examples/passing/Superclasses3.purs+1−1
@@ -33,7 +33,7 @@ instance applicativeMTrace :: Applicative MTrace where
3333instance bindMTrace :: Bind MTrace where
3434 (>>=) m f = MTrace (runMTrace m >>= (runMTrace <<< f))
3535
36−instance monadMTrace :: Monad MTrace
36+instance monadMTrace :: Monad MTrace
3737
3838instance writerMTrace :: MonadWriter String MTrace where
3939 tell s = MTrace (trace s)
examples/passing/TailCall.purs+2−2
@@ -9,7 +9,7 @@ test n (x:xs) = test (n + x) xs
99loop :: forall a. Number -> a
1010loop x = loop (x + 1)
1111
12−notATailCall = \x ->
12+notATailCall = \x ->
1313 (\notATailCall -> notATailCall x) (\x -> x)
14−
14+
1515main = Debug.Trace.print (test 0 [1, 2, 3])
examples/passing/TopLevelCase.purs+1−1
@@ -14,5 +14,5 @@ module Main where
1414 data A = A
1515
1616 parseTest A 0 = 0
17−
17+
1818 main = Debug.Trace.trace "Done"
examples/passing/TypeClassImport.purs+3−3
@@ -7,9 +7,9 @@ foreign import data C :: *
77foreign import t "var t = null;" :: T
88
99foreign import inst """
10− var inst = {
11− show: function(t) {
12− return 'Done';
10+ var inst = {
11+ show: function(t) {
12+ return 'Done';
1313 }
1414 }""" :: C
1515
examples/passing/TypeClassMemberOrderChange.purs+1−1
@@ -3,7 +3,7 @@ module Main where
33class Test a where
44 fn :: a -> a -> a
55 val :: a
6−
6+
77instance testBoolean :: Test Boolean where
88 val = true
99 fn x y = y
examples/passing/TypeDecl.purs+1−1
@@ -8,5 +8,5 @@ module Main where
88 iterate :: forall a. Number -> (a -> a) -> a -> a
99 iterate 0 f a = a
1010 iterate n f a = iterate (n - 1) f (f a)
11−
11+
1212 main = Debug.Trace.trace "Done"
examples/passing/TypeSynonyms.purs+2−2
@@ -1,6 +1,6 @@
11module Main where
22
3− type Lens a b =
3+ type Lens a b =
44 { get :: a -> b
55 , set :: a -> b -> a
66 }
@@ -14,7 +14,7 @@ module Main where
1414 type Pair a b = { fst :: a, snd :: b }
1515
1616 fst :: forall a b. Lens (Pair a b) a
17− fst =
17+ fst =
1818 { get: \p -> p.fst
1919 , set: \p a -> { fst: a, snd: p.snd }
2020 }
examples/passing/TypeWildcardsRecordExtension.purs+1−1
@@ -1,5 +1,5 @@
11module Main where
2−
2+
33foo :: forall a. {b :: Number | a} -> {b :: Number | _}
44foo f = f
55
examples/passing/Where.purs+6−6
@@ -7,24 +7,24 @@ import Control.Monad.ST
77test1 x = y
88 where
99 y :: Number
10− y = x + 1
10+ y = x + 1
1111
1212test2 x y = x' + y'
1313 where
1414 x' = x + 1
1515 y' = y + 1
16−
16+
1717
1818test3 = f 1 2 3
1919 where f x y z = x + y + z
20−
20+
2121
2222test4 = f (+) [1, 2]
2323 where f x [y, z] = x y z
24−
24+
2525
2626test5 = g 10
27− where
27+ where
2828 f x | x > 0 = g (x / 2) + 1
2929 f x = 0
3030 g x = f (x - 1) + 1
@@ -35,7 +35,7 @@ test6 = if f true then f 1 else f 2
3535
3636test7 :: Number -> Number
3737test7 x = go x
38− where
38+ where
3939 go y | (x - 0.1 < y * y) && (y * y < x + 0.1) = y
4040 go y = go $ (y + x / y) / 2
4141
examples/passing/s.purs+1−1
@@ -1,5 +1,5 @@
11module Main where
22
33 s = \x y z -> x z (y z)
4−
4+
55 main = Debug.Trace.trace "Done"
hierarchy/Main.hs+6−7
@@ -25,13 +25,12 @@ import Options.Applicative
2525import System.Directory (createDirectoryIfMissing)
2626import System.FilePath ((</>))
2727import System.Exit (exitFailure, exitSuccess)
28−import System.IO (stderr)
28+import System.IO (hPutStr, stderr)
2929
3030import Text.Parsec as Par (ParseError)
3131
3232import qualified Language.PureScript as P
3333import qualified Paths_purescript as Paths
34−import qualified System.IO.UTF8 as U
3534
3635
3736data HierarchyOptions = HierarchyOptions
@@ -56,14 +55,14 @@ runModuleName (P.ModuleName pns) = intercalate "_" (P.runProperName `map` pns)
5655
5756readInput :: FilePath -> IO (Either Par.ParseError [P.Module])
5857readInput filename = do
59− content <- U.readFile filename
58+ content <- readFile filename
6059 return $ fmap (map snd) $ P.parseModulesFromFiles id [(filename, content)]
6160
6261compile :: HierarchyOptions -> IO ()
6362compile (HierarchyOptions input mOutput) = do
6463 modules <- readInput input
6564 case modules of
66− Left err -> U.hPutStr stderr (show err) >> exitFailure
65+ Left err -> hPutStr stderr (show err) >> exitFailure
6766 Right ms -> do
6867 for_ ms $ \(P.Module moduleName decls _) ->
6968 let name = runModuleName moduleName
@@ -76,15 +75,15 @@ compile (HierarchyOptions input mOutput) = do
7675 in unless (null supers) $ case mOutput of
7776 Just output -> do
7877 createDirectoryIfMissing True output
79− U.writeFile (output </> name) hier
80− Nothing -> U.putStrLn hier
78+ writeFile (output </> name) hier
79+ Nothing -> putStrLn hier
8180 exitSuccess
8281
8382superClasses :: P.Declaration -> [SuperMap]
8483superClasses (P.TypeClassDeclaration sub _ supers@(_:_) _) =
8584 fmap (\(P.Qualified _ super, _) -> SuperMap (Right (super, sub))) supers
8685superClasses (P.TypeClassDeclaration sub _ _ _) = [SuperMap (Left sub)]
87−superClasses (P.PositionedDeclaration _ decl) = superClasses decl
86+superClasses (P.PositionedDeclaration _ _ decl) = superClasses decl
8887superClasses _ = []
8988
9089inputFile :: Parser FilePath
prelude/README.md+343−33
@@ -4,28 +4,40 @@
44
55### Types
66
7− data Ordering where
8− LT :: Ordering
9− GT :: Ordering
10− EQ :: Ordering
7+#### `Ordering`
118
12− newtype Unit where
13− Unit :: { } -> Unit
9+ data Ordering
10+ = LT
11+ | GT
12+ | EQ
13+
14+#### `Unit`
15+
16+ newtype Unit
17+ = Unit { }
1418
1519
1620### Type Classes
1721
1822![Prelude](images/Prelude.png)
1923
24+#### `Applicative`
25+
2026 class (Apply f) <= Applicative f where
2127 pure :: forall a. a -> f a
2228
29+#### `Apply`
30+
2331 class (Functor f) <= Apply f where
2432 (<*>) :: forall a b. f (a -> b) -> f a -> f b
2533
34+#### `Bind`
35+
2636 class (Apply m) <= Bind m where
2737 (>>=) :: forall a b. m a -> (a -> m b) -> m b
2838
39+#### `Bits`
40+
2941 class Bits b where
3042 (.&.) :: b -> b -> b
3143 (.|.) :: b -> b -> b
@@ -35,153 +47,349 @@
3547 zshr :: b -> Number -> b
3648 complement :: b -> b
3749
50+#### `BoolLike`
51+
3852 class BoolLike b where
3953 (&&) :: b -> b -> b
4054 (||) :: b -> b -> b
4155 not :: b -> b
4256
57+#### `Category`
58+
4359 class (Semigroupoid a) <= Category a where
4460 id :: forall t. a t t
4561
62+#### `DivisionRing`
63+
64+Ring where every nonzero element has a multiplicative inverse (possibly
65+a non-commutative field) so that ```a `mod` b = zero```
66+
67+ class (Ring a, ModuloSemiring a) <= DivisionRing a where
68+
69+#### `Eq`
70+
4671 class Eq a where
4772 (==) :: a -> a -> Boolean
4873 (/=) :: a -> a -> Boolean
4974
75+#### `Functor`
76+
5077 class Functor f where
5178 (<$>) :: forall a b. (a -> b) -> f a -> f b
5279
53− class (Applicative m, Bind m) <= Monad m where
80+#### `ModuloSemiring`
5481
55− class Num a where
56− (+) :: a -> a -> a
57− (-) :: a -> a -> a
58− (*) :: a -> a -> a
82+Semiring with modulo operation and division where
83+```a / b * b + (a `mod` b) = a```
84+
85+ class (Semiring a) <= ModuloSemiring a where
5986 (/) :: a -> a -> a
60− (%) :: a -> a -> a
61− negate :: a -> a
87+ mod :: a -> a -> a
88+
89+#### `Monad`
90+
91+ class (Applicative m, Bind m) <= Monad m where
92+
93+#### `Num`
94+
95+A commutative field
96+
97+ class (DivisionRing a) <= Num a where
98+
99+#### `Ord`
62100
63101 class (Eq a) <= Ord a where
64102 compare :: a -> a -> Ordering
65103
104+#### `Ring`
105+
106+Addition, multiplication, and subtraction
107+
108+ class (Semiring a) <= Ring a where
109+ (-) :: a -> a -> a
110+
111+#### `Semigroup`
112+
66113 class Semigroup a where
67114 (<>) :: a -> a -> a
68115
116+#### `Semigroupoid`
117+
69118 class Semigroupoid a where
70119 (<<<) :: forall b c d. a c d -> a b c -> a b d
71120
121+#### `Semiring`
122+
123+Addition and multiplication
124+
125+ class Semiring a where
126+ (+) :: a -> a -> a
127+ zero :: a
128+ (*) :: a -> a -> a
129+ one :: a
130+
131+#### `Show`
132+
72133 class Show a where
73134 show :: a -> String
74135
75136
76137### Type Class Instances
77138
139+#### `applicativeArr`
140+
78141 instance applicativeArr :: Applicative (Prim.Function r)
79142
143+#### `applyArr`
144+
80145 instance applyArr :: Apply (Prim.Function r)
81146
147+#### `bindArr`
148+
82149 instance bindArr :: Bind (Prim.Function r)
83150
151+#### `bitsNumber`
152+
84153 instance bitsNumber :: Bits Number
85154
155+#### `boolLikeBoolean`
156+
86157 instance boolLikeBoolean :: BoolLike Boolean
87158
159+#### `categoryArr`
160+
88161 instance categoryArr :: Category Prim.Function
89162
163+#### `divisionRingNumber`
164+
165+ instance divisionRingNumber :: DivisionRing Number
166+
167+#### `eqArray`
168+
90169 instance eqArray :: (Eq a) => Eq [a]
91170
171+#### `eqBoolean`
172+
92173 instance eqBoolean :: Eq Boolean
93174
175+#### `eqNumber`
176+
94177 instance eqNumber :: Eq Number
95178
179+#### `eqOrdering`
180+
96181 instance eqOrdering :: Eq Ordering
97182
183+#### `eqString`
184+
98185 instance eqString :: Eq String
99186
187+#### `eqUnit`
188+
100189 instance eqUnit :: Eq Unit
101190
191+#### `functorArr`
192+
102193 instance functorArr :: Functor (Prim.Function r)
103194
195+#### `moduloSemiringNumber`
196+
197+ instance moduloSemiringNumber :: ModuloSemiring Number
198+
199+#### `monadArr`
200+
104201 instance monadArr :: Monad (Prim.Function r)
105202
203+#### `numNumber`
204+
106205 instance numNumber :: Num Number
107206
207+#### `ordArray`
208+
108209 instance ordArray :: (Ord a) => Ord [a]
109210
211+#### `ordBoolean`
212+
110213 instance ordBoolean :: Ord Boolean
111214
215+#### `ordNumber`
216+
112217 instance ordNumber :: Ord Number
113218
219+#### `ordString`
220+
114221 instance ordString :: Ord String
115222
223+#### `ordUnit`
224+
116225 instance ordUnit :: Ord Unit
117226
227+#### `ringNumber`
228+
229+ instance ringNumber :: Ring Number
230+
231+#### `semigroupArr`
232+
118233 instance semigroupArr :: (Semigroup s') => Semigroup (s -> s')
119234
235+#### `semigroupString`
236+
120237 instance semigroupString :: Semigroup String
121238
239+#### `semigroupUnit`
240+
122241 instance semigroupUnit :: Semigroup Unit
123242
243+#### `semigroupoidArr`
244+
124245 instance semigroupoidArr :: Semigroupoid Prim.Function
125246
247+#### `semiringNumber`
248+
249+ instance semiringNumber :: Semiring Number
250+
251+#### `showArray`
252+
126253 instance showArray :: (Show a) => Show [a]
127254
255+#### `showBoolean`
256+
128257 instance showBoolean :: Show Boolean
129258
259+#### `showNumber`
260+
130261 instance showNumber :: Show Number
131262
263+#### `showOrdering`
264+
132265 instance showOrdering :: Show Ordering
133266
267+#### `showString`
268+
134269 instance showString :: Show String
135270
271+#### `showUnit`
272+
136273 instance showUnit :: Show Unit
137274
138275
139276### Values
140277
278+#### `(#)`
279+
141280 (#) :: forall a b. a -> (a -> b) -> b
142281
282+#### `($)`
283+
143284 ($) :: forall a b. (a -> b) -> a -> b
144285
286+#### `(++)`
287+
145288 (++) :: forall s. (Semigroup s) => s -> s -> s
146289
290+#### `(:)`
291+
147292 (:) :: forall a. a -> [a] -> [a]
148293
294+#### `(<#>)`
295+
149296 (<#>) :: forall f a b. (Functor f) => f a -> (a -> b) -> f b
150297
298+#### `(<)`
299+
151300 (<) :: forall a. (Ord a) => a -> a -> Boolean
152301
302+#### `(<=)`
303+
153304 (<=) :: forall a. (Ord a) => a -> a -> Boolean
154305
306+#### `(>)`
307+
155308 (>) :: forall a. (Ord a) => a -> a -> Boolean
156309
310+#### `(>=)`
311+
157312 (>=) :: forall a. (Ord a) => a -> a -> Boolean
158313
314+#### `(>>>)`
315+
159316 (>>>) :: forall a b c d. (Semigroupoid a) => a b c -> a c d -> a b d
160317
318+#### `ap`
319+
161320 ap :: forall m a b. (Monad m) => m (a -> b) -> m a -> m b
162321
322+#### `asTypeOf`
323+
324+This function returns its first argument, and can be used to assert type equalities.
325+This can be useful when types are otherwise ambiguous.
326+
327+E.g.
328+
329+ main = print $ [] `asTypeOf` [0]
330+
331+If instead, we had written `main = print []`, the type of the argument `[]` would have
332+been ambiguous, resulting in a compile-time error.
333+
163334 asTypeOf :: forall a. a -> a -> a
164335
336+#### `cons`
337+
165338 cons :: forall a. a -> [a] -> [a]
166339
340+#### `const`
341+
342+Returns its first argument and ignores its second.
343+
167344 const :: forall a b. a -> b -> a
168345
346+#### `flip`
347+
348+Flips the order of the arguments to a function of two arguments.
349+
169350 flip :: forall a b c. (a -> b -> c) -> b -> a -> c
170351
352+#### `liftA1`
353+
171354 liftA1 :: forall f a b. (Applicative f) => (a -> b) -> f a -> f b
172355
356+#### `liftM1`
357+
173358 liftM1 :: forall m a b. (Monad m) => (a -> b) -> m a -> m b
174359
360+#### `negate`
361+
362+ negate :: forall a. (Ring a) => a -> a
363+
364+#### `otherwise`
365+
366+An alias for `true`, which can be useful in guard clauses:
367+
368+E.g.
369+
370+ max x y | x >= y = x
371+ | otherwise = y
372+
175373 otherwise :: Boolean
176374
375+#### `refEq`
376+
177377 refEq :: forall a. a -> a -> Boolean
178378
379+#### `refIneq`
380+
179381 refIneq :: forall a. a -> a -> Boolean
180382
383+#### `return`
384+
181385 return :: forall m a. (Monad m) => a -> m a
182386
387+#### `unit`
388+
183389 unit :: Unit
184390
391+#### `void`
392+
185393 void :: forall f a. (Functor f) => f a -> f Unit
186394
187395
@@ -189,102 +397,152 @@
189397
190398### Types
191399
400+#### `Fn0`
401+
192402 data Fn0 :: * -> *
193403
404+#### `Fn1`
405+
194406 data Fn1 :: * -> * -> *
195407
408+#### `Fn10`
409+
196410 data Fn10 :: * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *
197411
412+#### `Fn2`
413+
198414 data Fn2 :: * -> * -> * -> *
199415
416+#### `Fn3`
417+
200418 data Fn3 :: * -> * -> * -> * -> *
201419
420+#### `Fn4`
421+
202422 data Fn4 :: * -> * -> * -> * -> * -> *
203423
424+#### `Fn5`
425+
204426 data Fn5 :: * -> * -> * -> * -> * -> * -> *
205427
428+#### `Fn6`
429+
206430 data Fn6 :: * -> * -> * -> * -> * -> * -> * -> *
207431
432+#### `Fn7`
433+
208434 data Fn7 :: * -> * -> * -> * -> * -> * -> * -> * -> *
209435
436+#### `Fn8`
437+
210438 data Fn8 :: * -> * -> * -> * -> * -> * -> * -> * -> * -> *
211439
440+#### `Fn9`
441+
212442 data Fn9 :: * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *
213443
214444
215445### Values
216446
447+#### `mkFn0`
448+
217449 mkFn0 :: forall a. (Unit -> a) -> Fn0 a
218450
451+#### `mkFn1`
452+
219453 mkFn1 :: forall a b. (a -> b) -> Fn1 a b
220454
455+#### `mkFn10`
456+
221457 mkFn10 :: forall a b c d e f g h i j k. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k) -> Fn10 a b c d e f g h i j k
222458
459+#### `mkFn2`
460+
223461 mkFn2 :: forall a b c. (a -> b -> c) -> Fn2 a b c
224462
463+#### `mkFn3`
464+
225465 mkFn3 :: forall a b c d. (a -> b -> c -> d) -> Fn3 a b c d
226466
467+#### `mkFn4`
468+
227469 mkFn4 :: forall a b c d e. (a -> b -> c -> d -> e) -> Fn4 a b c d e
228470
471+#### `mkFn5`
472+
229473 mkFn5 :: forall a b c d e f. (a -> b -> c -> d -> e -> f) -> Fn5 a b c d e f
230474
475+#### `mkFn6`
476+
231477 mkFn6 :: forall a b c d e f g. (a -> b -> c -> d -> e -> f -> g) -> Fn6 a b c d e f g
232478
479+#### `mkFn7`
480+
233481 mkFn7 :: forall a b c d e f g h. (a -> b -> c -> d -> e -> f -> g -> h) -> Fn7 a b c d e f g h
234482
483+#### `mkFn8`
484+
235485 mkFn8 :: forall a b c d e f g h i. (a -> b -> c -> d -> e -> f -> g -> h -> i) -> Fn8 a b c d e f g h i
236486
487+#### `mkFn9`
488+
237489 mkFn9 :: forall a b c d e f g h i j. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j) -> Fn9 a b c d e f g h i j
238490
491+#### `on`
492+
239493 on :: forall a b c. (b -> b -> c) -> (a -> b) -> a -> a -> c
240494
241− runFn0 :: forall a. Fn0 a -> a
495+#### `runFn0`
242496
243− runFn1 :: forall a b. Fn1 a b -> a -> b
497+ runFn0 :: forall a. Fn0 a -> a
244498
245− runFn10 :: forall a b c d e f g h i j k. Fn10 a b c d e f g h i j k -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k
499+#### `runFn1`
246500
247− runFn2 :: forall a b c. Fn2 a b c -> a -> b -> c
501+ runFn1 :: forall a b. Fn1 a b -> a -> b
248502
249− runFn3 :: forall a b c d. Fn3 a b c d -> a -> b -> c -> d
503+#### `runFn10`
250504
251− runFn4 :: forall a b c d e. Fn4 a b c d e -> a -> b -> c -> d -> e
505+ runFn10 :: forall a b c d e f g h i j k. Fn10 a b c d e f g h i j k -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k
252506
253− runFn5 :: forall a b c d e f. Fn5 a b c d e f -> a -> b -> c -> d -> e -> f
507+#### `runFn2`
254508
255− runFn6 :: forall a b c d e f g. Fn6 a b c d e f g -> a -> b -> c -> d -> e -> f -> g
509+ runFn2 :: forall a b c. Fn2 a b c -> a -> b -> c
256510
257− runFn7 :: forall a b c d e f g h. Fn7 a b c d e f g h -> a -> b -> c -> d -> e -> f -> g -> h
511+#### `runFn3`
258512
259− runFn8 :: forall a b c d e f g h i. Fn8 a b c d e f g h i -> a -> b -> c -> d -> e -> f -> g -> h -> i
513+ runFn3 :: forall a b c d. Fn3 a b c d -> a -> b -> c -> d
260514
261− runFn9 :: forall a b c d e f g h i j. Fn9 a b c d e f g h i j -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j
515+#### `runFn4`
262516
517+ runFn4 :: forall a b c d e. Fn4 a b c d e -> a -> b -> c -> d -> e
263518
264−## Module Data.Eq
519+#### `runFn5`
265520
266−### Types
521+ runFn5 :: forall a b c d e f. Fn5 a b c d e f -> a -> b -> c -> d -> e -> f
267522
268− newtype Ref a where
269− Ref :: a -> Ref a
523+#### `runFn6`
270524
525+ runFn6 :: forall a b c d e f g. Fn6 a b c d e f g -> a -> b -> c -> d -> e -> f -> g
271526
272−### Type Class Instances
527+#### `runFn7`
273528
274− instance eqRef :: Eq (Ref a)
529+ runFn7 :: forall a b c d e f g h. Fn7 a b c d e f g h -> a -> b -> c -> d -> e -> f -> g -> h
275530
276− instance functorRef :: Functor Ref
531+#### `runFn8`
277532
533+ runFn8 :: forall a b c d e f g h i. Fn8 a b c d e f g h i -> a -> b -> c -> d -> e -> f -> g -> h -> i
278534
279−### Values
535+#### `runFn9`
280536
281− liftRef :: forall a b. (a -> a -> b) -> Ref a -> Ref a -> b
537+ runFn9 :: forall a b c d e f g h i j. Fn9 a b c d e f g h i j -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j
282538
283539
284540## Module Prelude.Unsafe
285541
286542### Values
287543
544+#### `unsafeIndex`
545+
288546 unsafeIndex :: forall a. [a] -> Number -> a
289547
290548
@@ -292,38 +550,66 @@
292550
293551### Types
294552
553+#### `Eff`
554+
295555 data Eff :: # ! -> * -> *
296556
557+#### `Pure`
558+
297559 type Pure a = forall e. Eff e a
298560
299561
300562### Type Class Instances
301563
564+#### `applicativeEff`
565+
302566 instance applicativeEff :: Applicative (Eff e)
303567
568+#### `applyEff`
569+
304570 instance applyEff :: Apply (Eff e)
305571
572+#### `bindEff`
573+
306574 instance bindEff :: Bind (Eff e)
307575
576+#### `functorEff`
577+
308578 instance functorEff :: Functor (Eff e)
309579
580+#### `monadEff`
581+
310582 instance monadEff :: Monad (Eff e)
311583
312584
313585### Values
314586
587+#### `bindE`
588+
315589 bindE :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b
316590
591+#### `forE`
592+
317593 forE :: forall e. Number -> Number -> (Number -> Eff e Unit) -> Eff e Unit
318594
595+#### `foreachE`
596+
319597 foreachE :: forall e a. [a] -> (a -> Eff e Unit) -> Eff e Unit
320598
599+#### `returnE`
600+
321601 returnE :: forall e a. a -> Eff e a
322602
603+#### `runPure`
604+
323605 runPure :: forall a. Pure a -> a
324606
607+#### `untilE`
608+
325609 untilE :: forall e. Eff e Boolean -> Eff e Unit
326610
611+#### `whileE`
612+
327613 whileE :: forall e a. Eff e Boolean -> Eff e a -> Eff e Unit
328614
329615
@@ -331,6 +617,8 @@
331617
332618### Values
333619
620+#### `unsafeInterleaveEff`
621+
334622 unsafeInterleaveEff :: forall eff1 eff2 a. Eff eff1 a -> Eff eff2 a
335623
336624
@@ -338,13 +626,19 @@
338626
339627### Types
340628
629+#### `Trace`
630+
341631 data Trace :: !
342632
343633
344634### Values
345635
636+#### `print`
637+
346638 print :: forall a r. (Show a) => a -> Eff (trace :: Trace | r) Unit
347639
640+#### `trace`
641+
348642 trace :: forall r. String -> Eff (trace :: Trace | r) Unit
349643
350644
@@ -352,23 +646,39 @@
352646
353647### Types
354648
649+#### `ST`
650+
355651 data ST :: * -> !
356652
653+#### `STRef`
654+
357655 data STRef :: * -> * -> *
358656
359657
360658### Values
361659
660+#### `modifySTRef`
661+
362662 modifySTRef :: forall a h r. STRef h a -> (a -> a) -> Eff (st :: ST h | r) a
363663
664+#### `newSTRef`
665+
364666 newSTRef :: forall a h r. a -> Eff (st :: ST h | r) (STRef h a)
365667
668+#### `pureST`
669+
366670 pureST :: forall a. (forall h r. Eff (st :: ST h | r) a) -> a
367671
672+#### `readSTRef`
673+
368674 readSTRef :: forall a h r. STRef h a -> Eff (st :: ST h | r) a
369675
676+#### `runST`
677+
370678 runST :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
371679
680+#### `writeSTRef`
681+
372682 writeSTRef :: forall a h r. STRef h a -> a -> Eff (st :: ST h | r) a
373683
374684
prelude/images/Prelude.png

Binary file not shown.

prelude/prelude.purs+655−470
@@ -13,8 +13,13 @@ module Prelude
1313 , Applicative, pure, liftA1
1414 , Bind, (>>=)
1515 , Monad, return, liftM1, ap
16− , Num, (+), (-), (*), (/), (%)
16+ , Semiring, (+), zero, (*), one
17+ , ModuloSemiring, (/), mod
18+ , Ring, (-)
19+ , (%)
1720 , negate
21+ , DivisionRing
22+ , Num
1823 , Eq, (==), (/=), refEq, refIneq
1924 , Ord, Ordering(..), compare, (<), (>), (<=), (>=)
2025 , Bits, (.&.), (.|.), (.^.), shl, shr, zshr, complement
@@ -24,15 +29,32 @@ module Prelude
2429 , Unit(..), unit
2530 ) where
2631
32+ -- | An alias for `true`, which can be useful in guard clauses:
33+ -- |
34+ -- | E.g.
35+ -- |
36+ -- | max x y | x >= y = x
37+ -- | | otherwise = y
2738 otherwise :: Boolean
2839 otherwise = true
2940
41+ -- | Flips the order of the arguments to a function of two arguments.
3042 flip :: forall a b c. (a -> b -> c) -> b -> a -> c
3143 flip f b a = f a b
3244
45+ -- | Returns its first argument and ignores its second.
3346 const :: forall a b. a -> b -> a
3447 const a _ = a
3548
49+ -- | This function returns its first argument, and can be used to assert type equalities.
50+ -- | This can be useful when types are otherwise ambiguous.
51+ -- |
52+ -- | E.g.
53+ -- |
54+ -- | main = print $ [] `asTypeOf` [0]
55+ -- |
56+ -- | If instead, we had written `main = print []`, the type of the argument `[]` would have
57+ -- | been ambiguous, resulting in a compile-time error.
3658 asTypeOf :: forall a. a -> a -> a
3759 asTypeOf x _ = x
3860
@@ -69,19 +91,23 @@ module Prelude
6991 (:) = cons
7092
7193 foreign import cons
72− "function cons(e) {\
73− \ return function(l) {\
74− \ return [e].concat(l);\
75− \ };\
76− \}" :: forall a. a -> [a] -> [a]
94+ """
95+ function cons(e) {
96+ return function(l) {
97+ return [e].concat(l);
98+ };
99+ }
100+ """ :: forall a. a -> [a] -> [a]
77101
78102 class Show a where
79103 show :: a -> String
80104
81105 foreign import showStringImpl
82− "function showStringImpl(s) {\
83− \ return JSON.stringify(s);\
84− \}" :: String -> String
106+ """
107+ function showStringImpl(s) {
108+ return JSON.stringify(s);
109+ }
110+ """ :: String -> String
85111
86112 instance showUnit :: Show Unit where
87113 show (Unit {}) = "Unit {}"
@@ -93,23 +119,28 @@ module Prelude
93119 show true = "true"
94120 show false = "false"
95121
96− foreign import showNumberImpl "function showNumberImpl(n) {\
97− \ return n.toString();\
98− \}" :: Number -> String
122+ foreign import showNumberImpl
123+ """
124+ function showNumberImpl(n) {
125+ return n.toString();
126+ }
127+ """ :: Number -> String
99128
100129 instance showNumber :: Show Number where
101130 show = showNumberImpl
102131
103132 foreign import showArrayImpl
104− "function showArrayImpl(f) {\
105− \ return function(xs) {\
106− \ var ss = [];\
107− \ for (var i = 0, l = xs.length; i < l; i++) {\
108− \ ss[i] = f(xs[i]);\
109− \ }\
110− \ return '[' + ss.join(',') + ']';\
111− \ };\
112− \}" :: forall a. (a -> String) -> [a] -> String
133+ """
134+ function showArrayImpl(f) {
135+ return function(xs) {
136+ var ss = [];
137+ for (var i = 0, l = xs.length; i < l; i++) {
138+ ss[i] = f(xs[i]);
139+ }
140+ return '[' + ss.join(',') + ']';
141+ };
142+ }
143+ """ :: forall a. (a -> String) -> [a] -> String
113144
114145 instance showArray :: (Show a) => Show [a] where
115146 show = showArrayImpl show
@@ -179,55 +210,96 @@ module Prelude
179210 infixl 6 -
180211 infixl 6 +
181212
182− class Num a where
183− (+) :: a -> a -> a
184− (-) :: a -> a -> a
185− (*) :: a -> a -> a
213+ -- | Addition and multiplication
214+ class Semiring a where
215+ (+) :: a -> a -> a
216+ zero :: a
217+ (*) :: a -> a -> a
218+ one :: a
219+
220+ -- | Semiring with modulo operation and division where
221+ -- | ```a / b * b + (a `mod` b) = a```
222+ class (Semiring a) <= ModuloSemiring a where
186223 (/) :: a -> a -> a
187− (%) :: a -> a -> a
188− negate :: a -> a
189−
190− foreign import numAdd "function numAdd(n1) {\
191− \ return function(n2) {\
192− \ return n1 + n2;\
193− \ };\
194− \}" :: Number -> Number -> Number
195−
196− foreign import numSub "function numSub(n1) {\
197− \ return function(n2) {\
198− \ return n1 - n2;\
199− \ };\
200− \}" :: Number -> Number -> Number
201−
202− foreign import numMul "function numMul(n1) {\
203− \ return function(n2) {\
204− \ return n1 * n2;\
205− \ };\
206− \}" :: Number -> Number -> Number
207−
208− foreign import numDiv "function numDiv(n1) {\
209− \ return function(n2) {\
210− \ return n1 / n2;\
211− \ };\
212− \}" :: Number -> Number -> Number
213−
214− foreign import numMod "function numMod(n1) {\
215− \ return function(n2) {\
216− \ return n1 % n2;\
217− \ };\
218− \}" :: Number -> Number -> Number
219−
220− foreign import numNegate "function numNegate(n) {\
221− \ return -n;\
222− \}" :: Number -> Number
223−
224− instance numNumber :: Num Number where
224+ mod :: a -> a -> a
225+
226+ -- | Addition, multiplication, and subtraction
227+ class (Semiring a) <= Ring a where
228+ (-) :: a -> a -> a
229+
230+ negate :: forall a. (Ring a) => a -> a
231+ negate a = zero - a
232+
233+ -- | Ring where every nonzero element has a multiplicative inverse (possibly
234+ -- | a non-commutative field) so that ```a `mod` b = zero```
235+ class (Ring a, ModuloSemiring a) <= DivisionRing a
236+
237+ -- | A commutative field
238+ class (DivisionRing a) <= Num a
239+
240+ foreign import numAdd
241+ """
242+ function numAdd(n1) {
243+ return function(n2) {
244+ return n1 + n2;
245+ };
246+ }
247+ """ :: Number -> Number -> Number
248+
249+ foreign import numSub
250+ """
251+ function numSub(n1) {
252+ return function(n2) {
253+ return n1 - n2;
254+ };
255+ }
256+ """ :: Number -> Number -> Number
257+
258+ foreign import numMul
259+ """
260+ function numMul(n1) {
261+ return function(n2) {
262+ return n1 * n2;
263+ };
264+ }
265+ """ :: Number -> Number -> Number
266+
267+ foreign import numDiv
268+ """
269+ function numDiv(n1) {
270+ return function(n2) {
271+ return n1 / n2;
272+ };
273+ }
274+ """ :: Number -> Number -> Number
275+
276+ foreign import numMod
277+ """
278+ function numMod(n1) {
279+ return function(n2) {
280+ return n1 % n2;
281+ };
282+ }
283+ """ :: Number -> Number -> Number
284+
285+ (%) = numMod
286+
287+ instance semiringNumber :: Semiring Number where
225288 (+) = numAdd
226− (-) = numSub
289+ zero = 0
227290 (*) = numMul
291+ one = 1
292+
293+ instance ringNumber :: Ring Number where
294+ (-) = numSub
295+
296+ instance moduloSemiringNumber :: ModuloSemiring Number where
228297 (/) = numDiv
229− (%) = numMod
230− negate = numNegate
298+ mod _ _ = 0
299+
300+ instance divisionRingNumber :: DivisionRing Number
301+
302+ instance numNumber :: Num Number
231303
232304 newtype Unit = Unit {}
233305
@@ -242,18 +314,22 @@ module Prelude
242314 (/=) :: a -> a -> Boolean
243315
244316 foreign import refEq
245− "function refEq(r1) {\
246− \ return function(r2) {\
247− \ return r1 === r2;\
248− \ };\
249− \}" :: forall a. a -> a -> Boolean
317+ """
318+ function refEq(r1) {
319+ return function(r2) {
320+ return r1 === r2;
321+ };
322+ }
323+ """ :: forall a. a -> a -> Boolean
250324
251325 foreign import refIneq
252− "function refIneq(r1) {\
253− \ return function(r2) {\
254− \ return r1 !== r2;\
255− \ };\
256− \}" :: forall a. a -> a -> Boolean
326+ """
327+ function refIneq(r1) {
328+ return function(r2) {
329+ return r1 !== r2;
330+ };
331+ }
332+ """ :: forall a. a -> a -> Boolean
257333
258334 instance eqUnit :: Eq Unit where
259335 (==) (Unit {}) (Unit {}) = true
@@ -272,17 +348,19 @@ module Prelude
272348 (/=) = refIneq
273349
274350 foreign import eqArrayImpl
275− "function eqArrayImpl(f) {\
276− \ return function(xs) {\
277− \ return function(ys) {\
278− \ if (xs.length !== ys.length) return false;\
279− \ for (var i = 0; i < xs.length; i++) {\
280− \ if (!f(xs[i])(ys[i])) return false;\
281− \ }\
282− \ return true;\
283− \ };\
284− \ };\
285− \}" :: forall a. (a -> a -> Boolean) -> [a] -> [a] -> Boolean
351+ """
352+ function eqArrayImpl(f) {
353+ return function(xs) {
354+ return function(ys) {
355+ if (xs.length !== ys.length) return false;
356+ for (var i = 0; i < xs.length; i++) {
357+ if (!f(xs[i])(ys[i])) return false;
358+ }
359+ return true;
360+ };
361+ };
362+ }
363+ """ :: forall a. (a -> a -> Boolean) -> [a] -> [a] -> Boolean
286364
287365 instance eqArray :: (Eq a) => Eq [a] where
288366 (==) xs ys = eqArrayImpl (==) xs ys
@@ -334,17 +412,19 @@ module Prelude
334412 _ -> true
335413
336414 foreign import unsafeCompareImpl
337− "function unsafeCompareImpl(lt) {\
338− \ return function(eq) {\
339− \ return function(gt) {\
340− \ return function(x) {\
341− \ return function(y) {\
342− \ return x < y ? lt : x > y ? gt : eq;\
343− \ };\
344− \ };\
345− \ };\
346− \ };\
347− \}" :: forall a. Ordering -> Ordering -> Ordering -> a -> a -> Ordering
415+ """
416+ function unsafeCompareImpl(lt) {
417+ return function(eq) {
418+ return function(gt) {
419+ return function(x) {
420+ return function(y) {
421+ return x < y ? lt : x > y ? gt : eq;
422+ };
423+ };
424+ };
425+ };
426+ }
427+ """ :: forall a. Ordering -> Ordering -> Ordering -> a -> a -> Ordering
348428
349429 unsafeCompare :: forall a. a -> a -> Ordering
350430 unsafeCompare = unsafeCompareImpl LT EQ GT
@@ -385,45 +465,66 @@ module Prelude
385465 zshr :: b -> Number -> b
386466 complement :: b -> b
387467
388− foreign import numShl "function numShl(n1) {\
389− \ return function(n2) {\
390− \ return n1 << n2;\
391− \ };\
392− \}" :: Number -> Number -> Number
393−
394− foreign import numShr "function numShr(n1) {\
395− \ return function(n2) {\
396− \ return n1 >> n2;\
397− \ };\
398− \}" :: Number -> Number -> Number
399−
400− foreign import numZshr "function numZshr(n1) {\
401− \ return function(n2) {\
402− \ return n1 >>> n2;\
403− \ };\
404− \}" :: Number -> Number -> Number
405−
406− foreign import numAnd "function numAnd(n1) {\
407− \ return function(n2) {\
408− \ return n1 & n2;\
409− \ };\
410− \}" :: Number -> Number -> Number
411−
412− foreign import numOr "function numOr(n1) {\
413− \ return function(n2) {\
414− \ return n1 | n2;\
415− \ };\
416− \}" :: Number -> Number -> Number
417−
418− foreign import numXor "function numXor(n1) {\
419− \ return function(n2) {\
420− \ return n1 ^ n2;\
421− \ };\
422− \}" :: Number -> Number -> Number
423−
424− foreign import numComplement "function numComplement(n) {\
425− \ return ~n;\
426− \}" :: Number -> Number
468+ foreign import numShl
469+ """
470+ function numShl(n1) {
471+ return function(n2) {
472+ return n1 << n2;
473+ };
474+ }
475+ """ :: Number -> Number -> Number
476+
477+ foreign import numShr
478+ """
479+ function numShr(n1) {
480+ return function(n2) {
481+ return n1 >> n2;
482+ };
483+ }
484+ """ :: Number -> Number -> Number
485+
486+ foreign import numZshr
487+ """
488+ function numZshr(n1) {
489+ return function(n2) {
490+ return n1 >>> n2;
491+ };
492+ }
493+ """ :: Number -> Number -> Number
494+
495+ foreign import numAnd
496+ """
497+ function numAnd(n1) {
498+ return function(n2) {
499+ return n1 & n2;
500+ };
501+ }
502+ """ :: Number -> Number -> Number
503+
504+ foreign import numOr
505+ """
506+ function numOr(n1) {
507+ return function(n2) {
508+ return n1 | n2;
509+ };
510+ }
511+ """ :: Number -> Number -> Number
512+
513+ foreign import numXor
514+ """
515+ function numXor(n1) {
516+ return function(n2) {
517+ return n1 ^ n2;
518+ };
519+ }
520+ """ :: Number -> Number -> Number
521+
522+ foreign import numComplement
523+ """
524+ function numComplement(n) {
525+ return ~n;
526+ }
527+ """ :: Number -> Number
427528
428529 instance bitsNumber :: Bits Number where
429530 (.&.) = numAnd
@@ -442,21 +543,30 @@ module Prelude
442543 (||) :: b -> b -> b
443544 not :: b -> b
444545
445− foreign import boolAnd "function boolAnd(b1) {\
446− \ return function(b2) {\
447− \ return b1 && b2;\
448− \ };\
449− \}" :: Boolean -> Boolean -> Boolean
450−
451− foreign import boolOr "function boolOr(b1) {\
452− \ return function(b2) {\
453− \ return b1 || b2;\
454− \ };\
455− \}" :: Boolean -> Boolean -> Boolean
456−
457− foreign import boolNot "function boolNot(b) {\
458− \ return !b;\
459− \}" :: Boolean -> Boolean
546+ foreign import boolAnd
547+ """
548+ function boolAnd(b1) {
549+ return function(b2) {
550+ return b1 && b2;
551+ };
552+ }
553+ """ :: Boolean -> Boolean -> Boolean
554+
555+ foreign import boolOr
556+ """
557+ function boolOr(b1) {
558+ return function(b2) {
559+ return b1 || b2;
560+ };
561+ }
562+ """ :: Boolean -> Boolean -> Boolean
563+
564+ foreign import boolNot
565+ """
566+ function boolNot(b) {
567+ return !b;
568+ }
569+ """ :: Boolean -> Boolean
460570
461571 instance boolLikeBoolean :: BoolLike Boolean where
462572 (&&) = boolAnd
@@ -469,11 +579,13 @@ module Prelude
469579 (<>) :: a -> a -> a
470580
471581 foreign import concatString
472− "function concatString(s1) {\
473− \ return function(s2) {\
474− \ return s1 + s2;\
475− \ };\
476− \}" :: String -> String -> String
582+ """
583+ function concatString(s1) {
584+ return function(s2) {
585+ return s1 + s2;
586+ };
587+ }
588+ """ :: String -> String -> String
477589
478590 instance semigroupUnit :: Semigroup Unit where
479591 (<>) (Unit {}) (Unit {}) = Unit {}
@@ -507,293 +619,334 @@ module Data.Function where
507619 foreign import data Fn10 :: * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> * -> *
508620
509621 foreign import mkFn0
510− "function mkFn0(fn) {\
511− \ return function() {\
512− \ return fn({});\
513− \ };\
514− \}" :: forall a. (Unit -> a) -> Fn0 a
622+ """
623+ function mkFn0(fn) {
624+ return function() {
625+ return fn({});
626+ };
627+ }
628+ """ :: forall a. (Unit -> a) -> Fn0 a
515629
516630 foreign import mkFn1
517− "function mkFn1(fn) {\
518− \ return function(a) {\
519− \ return fn(a);\
520− \ };\
521− \}" :: forall a b. (a -> b) -> Fn1 a b
631+ """
632+ function mkFn1(fn) {
633+ return function(a) {
634+ return fn(a);
635+ };
636+ }
637+ """ :: forall a b. (a -> b) -> Fn1 a b
522638
523639 foreign import mkFn2
524− "function mkFn2(fn) {\
525− \ return function(a, b) {\
526− \ return fn(a)(b);\
527− \ };\
528− \}" :: forall a b c. (a -> b -> c) -> Fn2 a b c
640+ """
641+ function mkFn2(fn) {
642+ return function(a, b) {
643+ return fn(a)(b);
644+ };
645+ }
646+ """ :: forall a b c. (a -> b -> c) -> Fn2 a b c
529647
530648 foreign import mkFn3
531− "function mkFn3(fn) {\
532− \ return function(a, b, c) {\
533− \ return fn(a)(b)(c);\
534− \ };\
535− \}" :: forall a b c d. (a -> b -> c -> d) -> Fn3 a b c d
649+ """
650+ function mkFn3(fn) {
651+ return function(a, b, c) {
652+ return fn(a)(b)(c);
653+ };
654+ }
655+ """ :: forall a b c d. (a -> b -> c -> d) -> Fn3 a b c d
536656
537657 foreign import mkFn4
538− "function mkFn4(fn) {\
539− \ return function(a, b, c, d) {\
540− \ return fn(a)(b)(c)(d);\
541− \ };\
542− \}" :: forall a b c d e. (a -> b -> c -> d -> e) -> Fn4 a b c d e
658+ """
659+ function mkFn4(fn) {
660+ return function(a, b, c, d) {
661+ return fn(a)(b)(c)(d);
662+ };
663+ }
664+ """ :: forall a b c d e. (a -> b -> c -> d -> e) -> Fn4 a b c d e
543665
544666 foreign import mkFn5
545− "function mkFn5(fn) {\
546− \ return function(a, b, c, d, e) {\
547− \ return fn(a)(b)(c)(d)(e);\
548− \ };\
549− \}" :: forall a b c d e f. (a -> b -> c -> d -> e -> f) -> Fn5 a b c d e f
667+ """
668+ function mkFn5(fn) {
669+ return function(a, b, c, d, e) {
670+ return fn(a)(b)(c)(d)(e);
671+ };
672+ }
673+ """ :: forall a b c d e f. (a -> b -> c -> d -> e -> f) -> Fn5 a b c d e f
550674
551675 foreign import mkFn6
552− "function mkFn6(fn) {\
553− \ return function(a, b, c, d, e, f) {\
554− \ return fn(a)(b)(c)(d)(e)(f);\
555− \ };\
556− \}" :: forall a b c d e f g. (a -> b -> c -> d -> e -> f -> g) -> Fn6 a b c d e f g
676+ """
677+ function mkFn6(fn) {
678+ return function(a, b, c, d, e, f) {
679+ return fn(a)(b)(c)(d)(e)(f);
680+ };
681+ }
682+ """ :: forall a b c d e f g. (a -> b -> c -> d -> e -> f -> g) -> Fn6 a b c d e f g
557683
558684 foreign import mkFn7
559− "function mkFn7(fn) {\
560− \ return function(a, b, c, d, e, f, g) {\
561− \ return fn(a)(b)(c)(d)(e)(f)(g);\
562− \ };\
563− \}" :: forall a b c d e f g h. (a -> b -> c -> d -> e -> f -> g -> h) -> Fn7 a b c d e f g h
685+ """
686+ function mkFn7(fn) {
687+ return function(a, b, c, d, e, f, g) {
688+ return fn(a)(b)(c)(d)(e)(f)(g);
689+ };
690+ }
691+ """ :: forall a b c d e f g h. (a -> b -> c -> d -> e -> f -> g -> h) -> Fn7 a b c d e f g h
564692
565693 foreign import mkFn8
566− "function mkFn8(fn) {\
567− \ return function(a, b, c, d, e, f, g, h) {\
568− \ return fn(a)(b)(c)(d)(e)(f)(g)(h);\
569− \ };\
570− \}" :: forall a b c d e f g h i. (a -> b -> c -> d -> e -> f -> g -> h -> i) -> Fn8 a b c d e f g h i
694+ """
695+ function mkFn8(fn) {
696+ return function(a, b, c, d, e, f, g, h) {
697+ return fn(a)(b)(c)(d)(e)(f)(g)(h);
698+ };
699+ }
700+ """ :: forall a b c d e f g h i. (a -> b -> c -> d -> e -> f -> g -> h -> i) -> Fn8 a b c d e f g h i
571701
572702 foreign import mkFn9
573− "function mkFn9(fn) {\
574− \ return function(a, b, c, d, e, f, g, h, i) {\
575− \ return fn(a)(b)(c)(d)(e)(f)(g)(h)(i);\
576− \ };\
577− \}" :: forall a b c d e f g h i j. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j) -> Fn9 a b c d e f g h i j
703+ """
704+ function mkFn9(fn) {
705+ return function(a, b, c, d, e, f, g, h, i) {
706+ return fn(a)(b)(c)(d)(e)(f)(g)(h)(i);
707+ };
708+ }
709+ """ :: forall a b c d e f g h i j. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j) -> Fn9 a b c d e f g h i j
578710
579711 foreign import mkFn10
580− "function mkFn10(fn) {\
581− \ return function(a, b, c, d, e, f, g, h, i, j) {\
582− \ return fn(a)(b)(c)(d)(e)(f)(g)(h)(i)(j);\
583− \ };\
584− \}" :: forall a b c d e f g h i j k. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k) -> Fn10 a b c d e f g h i j k
712+ """
713+ function mkFn10(fn) {
714+ return function(a, b, c, d, e, f, g, h, i, j) {
715+ return fn(a)(b)(c)(d)(e)(f)(g)(h)(i)(j);
716+ };
717+ }
718+ """ :: forall a b c d e f g h i j k. (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k) -> Fn10 a b c d e f g h i j k
585719
586720 foreign import runFn0
587− "function runFn0(fn) {\
588− \ return fn();\
589− \}" :: forall a. Fn0 a -> a
721+ """
722+ function runFn0(fn) {
723+ return fn();
724+ }
725+ """ :: forall a. Fn0 a -> a
590726
591727 foreign import runFn1
592− "function runFn1(fn) {\
593− \ return function(a) {\
594− \ return fn(a);\
595− \ };\
596− \}" :: forall a b. Fn1 a b -> a -> b
728+ """
729+ function runFn1(fn) {
730+ return function(a) {
731+ return fn(a);
732+ };
733+ }
734+ """ :: forall a b. Fn1 a b -> a -> b
597735
598736 foreign import runFn2
599− "function runFn2(fn) {\
600− \ return function(a) {\
601− \ return function(b) {\
602− \ return fn(a, b);\
603− \ };\
604− \ };\
605− \}" :: forall a b c. Fn2 a b c -> a -> b -> c
737+ """
738+ function runFn2(fn) {
739+ return function(a) {
740+ return function(b) {
741+ return fn(a, b);
742+ };
743+ };
744+ }
745+ """ :: forall a b c. Fn2 a b c -> a -> b -> c
606746
607747 foreign import runFn3
608− "function runFn3(fn) {\
609− \ return function(a) {\
610− \ return function(b) {\
611− \ return function(c) {\
612− \ return fn(a, b, c);\
613− \ };\
614− \ };\
615− \ };\
616− \}" :: forall a b c d. Fn3 a b c d -> a -> b -> c -> d
748+ """
749+ function runFn3(fn) {
750+ return function(a) {
751+ return function(b) {
752+ return function(c) {
753+ return fn(a, b, c);
754+ };
755+ };
756+ };
757+ }
758+ """ :: forall a b c d. Fn3 a b c d -> a -> b -> c -> d
617759
618760 foreign import runFn4
619− "function runFn4(fn) {\
620− \ return function(a) {\
621− \ return function(b) {\
622− \ return function(c) {\
623− \ return function(d) {\
624− \ return fn(a, b, c, d);\
625− \ };\
626− \ };\
627− \ };\
628− \ };\
629− \}" :: forall a b c d e. Fn4 a b c d e -> a -> b -> c -> d -> e
761+ """
762+ function runFn4(fn) {
763+ return function(a) {
764+ return function(b) {
765+ return function(c) {
766+ return function(d) {
767+ return fn(a, b, c, d);
768+ };
769+ };
770+ };
771+ };
772+ }
773+ """ :: forall a b c d e. Fn4 a b c d e -> a -> b -> c -> d -> e
630774
631775 foreign import runFn5
632− "function runFn5(fn) {\
633− \ return function(a) {\
634− \ return function(b) {\
635− \ return function(c) {\
636− \ return function(d) {\
637− \ return function(e) {\
638− \ return fn(a, b, c, d, e);\
639− \ };\
640− \ };\
641− \ };\
642− \ };\
643− \ };\
644− \}" :: forall a b c d e f. Fn5 a b c d e f -> a -> b -> c -> d -> e -> f
776+ """
777+ function runFn5(fn) {
778+ return function(a) {
779+ return function(b) {
780+ return function(c) {
781+ return function(d) {
782+ return function(e) {
783+ return fn(a, b, c, d, e);
784+ };
785+ };
786+ };
787+ };
788+ };
789+ }
790+ """ :: forall a b c d e f. Fn5 a b c d e f -> a -> b -> c -> d -> e -> f
645791
646792 foreign import runFn6
647− "function runFn6(fn) {\
648− \ return function(a) {\
649− \ return function(b) {\
650− \ return function(c) {\
651− \ return function(d) {\
652− \ return function(e) {\
653− \ return function(f) {\
654− \ return fn(a, b, c, d, e, f);\
655− \ };\
656− \ };\
657− \ };\
658− \ };\
659− \ };\
660− \ };\
661− \}" :: forall a b c d e f g. Fn6 a b c d e f g -> a -> b -> c -> d -> e -> f -> g
793+ """
794+ function runFn6(fn) {
795+ return function(a) {
796+ return function(b) {
797+ return function(c) {
798+ return function(d) {
799+ return function(e) {
800+ return function(f) {
801+ return fn(a, b, c, d, e, f);
802+ };
803+ };
804+ };
805+ };
806+ };
807+ };
808+ }
809+ """ :: forall a b c d e f g. Fn6 a b c d e f g -> a -> b -> c -> d -> e -> f -> g
662810
663811 foreign import runFn7
664− "function runFn7(fn) {\
665− \ return function(a) {\
666− \ return function(b) {\
667− \ return function(c) {\
668− \ return function(d) {\
669− \ return function(e) {\
670− \ return function(f) {\
671− \ return function(g) {\
672− \ return fn(a, b, c, d, e, f, g);\
673− \ };\
674− \ };\
675− \ };\
676− \ };\
677− \ };\
678− \ };\
679− \ };\
680− \}" :: forall a b c d e f g h. Fn7 a b c d e f g h -> a -> b -> c -> d -> e -> f -> g -> h
812+ """
813+ function runFn7(fn) {
814+ return function(a) {
815+ return function(b) {
816+ return function(c) {
817+ return function(d) {
818+ return function(e) {
819+ return function(f) {
820+ return function(g) {
821+ return fn(a, b, c, d, e, f, g);
822+ };
823+ };
824+ };
825+ };
826+ };
827+ };
828+ };
829+ }
830+ """ :: forall a b c d e f g h. Fn7 a b c d e f g h -> a -> b -> c -> d -> e -> f -> g -> h
681831
682832 foreign import runFn8
683− "function runFn8(fn) {\
684− \ return function(a) {\
685− \ return function(b) {\
686− \ return function(c) {\
687− \ return function(d) {\
688− \ return function(e) {\
689− \ return function(f) {\
690− \ return function(g) {\
691− \ return function(h) {\
692− \ return fn(a, b, c, d, e, f, g, h);\
693− \ };\
694− \ };\
695− \ };\
696− \ };\
697− \ };\
698− \ };\
699− \ };\
700− \ };\
701− \}" :: forall a b c d e f g h i. Fn8 a b c d e f g h i -> a -> b -> c -> d -> e -> f -> g -> h -> i
833+ """
834+ function runFn8(fn) {
835+ return function(a) {
836+ return function(b) {
837+ return function(c) {
838+ return function(d) {
839+ return function(e) {
840+ return function(f) {
841+ return function(g) {
842+ return function(h) {
843+ return fn(a, b, c, d, e, f, g, h);
844+ };
845+ };
846+ };
847+ };
848+ };
849+ };
850+ };
851+ };
852+ }
853+ """ :: forall a b c d e f g h i. Fn8 a b c d e f g h i -> a -> b -> c -> d -> e -> f -> g -> h -> i
702854
703855 foreign import runFn9
704− "function runFn9(fn) {\
705− \ return function(a) {\
706− \ return function(b) {\
707− \ return function(c) {\
708− \ return function(d) {\
709− \ return function(e) {\
710− \ return function(f) {\
711− \ return function(g) {\
712− \ return function(h) {\
713− \ return function(i) {\
714− \ return fn(a, b, c, d, e, f, g, h, i);\
715− \ };\
716− \ };\
717− \ };\
718− \ };\
719− \ };\
720− \ };\
721− \ };\
722− \ };\
723− \ };\
724− \}" :: forall a b c d e f g h i j. Fn9 a b c d e f g h i j -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j
856+ """
857+ function runFn9(fn) {
858+ return function(a) {
859+ return function(b) {
860+ return function(c) {
861+ return function(d) {
862+ return function(e) {
863+ return function(f) {
864+ return function(g) {
865+ return function(h) {
866+ return function(i) {
867+ return fn(a, b, c, d, e, f, g, h, i);
868+ };
869+ };
870+ };
871+ };
872+ };
873+ };
874+ };
875+ };
876+ };
877+ }
878+ """ :: forall a b c d e f g h i j. Fn9 a b c d e f g h i j -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j
725879
726880 foreign import runFn10
727− "function runFn10(fn) {\
728− \ return function(a) {\
729− \ return function(b) {\
730− \ return function(c) {\
731− \ return function(d) {\
732− \ return function(e) {\
733− \ return function(f) {\
734− \ return function(g) {\
735− \ return function(h) {\
736− \ return function(i) {\
737− \ return function(j) {\
738− \ return fn(a, b, c, d, e, f, g, h, i, j);\
739− \ };\
740− \ };\
741− \ };\
742− \ };\
743− \ };\
744− \ };\
745− \ };\
746− \ };\
747− \ };\
748− \ };\
749− \}" :: forall a b c d e f g h i j k. Fn10 a b c d e f g h i j k -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k
750−
751−module Data.Eq where
752−
753− newtype Ref a = Ref a
754−
755− liftRef :: forall a b. (a -> a -> b) -> Ref a -> Ref a -> b
756− liftRef f (Ref x) (Ref y) = f x y
757−
758− instance eqRef :: Eq (Ref a) where
759− (==) = liftRef refEq
760− (/=) = liftRef refIneq
761−
762− instance functorRef :: Functor Ref where
763− (<$>) f (Ref x) = Ref (f x)
881+ """
882+ function runFn10(fn) {
883+ return function(a) {
884+ return function(b) {
885+ return function(c) {
886+ return function(d) {
887+ return function(e) {
888+ return function(f) {
889+ return function(g) {
890+ return function(h) {
891+ return function(i) {
892+ return function(j) {
893+ return fn(a, b, c, d, e, f, g, h, i, j);
894+ };
895+ };
896+ };
897+ };
898+ };
899+ };
900+ };
901+ };
902+ };
903+ };
904+ }
905+ """ :: forall a b c d e f g h i j k. Fn10 a b c d e f g h i j k -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k
764906
765907module Prelude.Unsafe where
766908
767909 foreign import unsafeIndex
768− "function unsafeIndex(xs) {\
769− \ return function(n) {\
770− \ return xs[n];\
771− \ };\
772− \}" :: forall a. [a] -> Number -> a
910+ """
911+ function unsafeIndex(xs) {
912+ return function(n) {
913+ return xs[n];
914+ };
915+ }
916+ """ :: forall a. [a] -> Number -> a
773917
774918module Control.Monad.Eff where
775919
776920 foreign import data Eff :: # ! -> * -> *
777921
778− foreign import returnE "function returnE(a) {\
779− \ return function() {\
780− \ return a;\
781− \ };\
782− \}" :: forall e a. a -> Eff e a
783−
784− foreign import bindE "function bindE(a) {\
785− \ return function(f) {\
786− \ return function() {\
787− \ return f(a())();\
788− \ };\
789− \ };\
790− \}" :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b
922+ foreign import returnE
923+ """
924+ function returnE(a) {
925+ return function() {
926+ return a;
927+ };
928+ }
929+ """ :: forall e a. a -> Eff e a
930+
931+ foreign import bindE
932+ """
933+ function bindE(a) {
934+ return function(f) {
935+ return function() {
936+ return f(a())();
937+ };
938+ };
939+ }
940+ """ :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b
791941
792942 type Pure a = forall e. Eff e a
793943
794− foreign import runPure "function runPure(f) {\
795− \ return f();\
796− \}" :: forall a. Pure a -> a
944+ foreign import runPure
945+ """
946+ function runPure(f) {
947+ return f();
948+ }
949+ """ :: forall a. Pure a -> a
797950
798951 instance functorEff :: Functor (Eff e) where
799952 (<$>) = liftA1
@@ -809,55 +962,69 @@ module Control.Monad.Eff where
809962
810963 instance monadEff :: Monad (Eff e)
811964
812− foreign import untilE "function untilE(f) {\
813− \ return function() {\
814− \ while (!f());\
815− \ return {};\
816− \ };\
817− \}" :: forall e. Eff e Boolean -> Eff e Unit
818−
819− foreign import whileE "function whileE(f) {\
820− \ return function(a) {\
821− \ return function() {\
822− \ while (f()) {\
823− \ a();\
824− \ }\
825− \ return {};\
826− \ };\
827− \ };\
828− \}" :: forall e a. Eff e Boolean -> Eff e a -> Eff e Unit
829−
830− foreign import forE "function forE(lo) {\
831− \ return function(hi) {\
832− \ return function(f) {\
833− \ return function() {\
834− \ for (var i = lo; i < hi; i++) {\
835− \ f(i)();\
836− \ }\
837− \ };\
838− \ };\
839− \ };\
840− \}" :: forall e. Number -> Number -> (Number -> Eff e Unit) -> Eff e Unit
841−
842−
843− foreign import foreachE "function foreachE(as) {\
844− \ return function(f) {\
845− \ return function() {\
846− \ for (var i = 0; i < as.length; i++) {\
847− \ f(as[i])();\
848− \ }\
849− \ };\
850− \ };\
851− \}" :: forall e a. [a] -> (a -> Eff e Unit) -> Eff e Unit
965+ foreign import untilE
966+ """
967+ function untilE(f) {
968+ return function() {
969+ while (!f());
970+ return {};
971+ };
972+ }
973+ """ :: forall e. Eff e Boolean -> Eff e Unit
974+
975+ foreign import whileE
976+ """
977+ function whileE(f) {
978+ return function(a) {
979+ return function() {
980+ while (f()) {
981+ a();
982+ }
983+ return {};
984+ };
985+ };
986+ }
987+ """ :: forall e a. Eff e Boolean -> Eff e a -> Eff e Unit
988+
989+ foreign import forE
990+ """
991+ function forE(lo) {
992+ return function(hi) {
993+ return function(f) {
994+ return function() {
995+ for (var i = lo; i < hi; i++) {
996+ f(i)();
997+ }
998+ };
999+ };
1000+ };
1001+ }
1002+ """ :: forall e. Number -> Number -> (Number -> Eff e Unit) -> Eff e Unit
1003+
1004+
1005+ foreign import foreachE
1006+ """
1007+ function foreachE(as) {
1008+ return function(f) {
1009+ return function() {
1010+ for (var i = 0; i < as.length; i++) {
1011+ f(as[i])();
1012+ }
1013+ };
1014+ };
1015+ }
1016+ """ :: forall e a. [a] -> (a -> Eff e Unit) -> Eff e Unit
8521017
8531018module Control.Monad.Eff.Unsafe where
8541019
8551020 import Control.Monad.Eff
8561021
8571022 foreign import unsafeInterleaveEff
858− "function unsafeInterleaveEff(f) {\
859− \ return f;\
860− \}" :: forall eff1 eff2 a. Eff eff1 a -> Eff eff2 a
1023+ """
1024+ function unsafeInterleaveEff(f) {
1025+ return f;
1026+ }
1027+ """ :: forall eff1 eff2 a. Eff eff1 a -> Eff eff2 a
8611028
8621029module Debug.Trace where
8631030
@@ -865,12 +1032,15 @@ module Debug.Trace where
8651032
8661033 foreign import data Trace :: !
8671034
868− foreign import trace "function trace(s) {\
869− \ return function() {\
870− \ console.log(s);\
871− \ return {};\
872− \ };\
873− \}" :: forall r. String -> Eff (trace :: Trace | r) Unit
1035+ foreign import trace
1036+ """
1037+ function trace(s) {
1038+ return function() {
1039+ console.log(s);
1040+ return {};
1041+ };
1042+ }
1043+ """ :: forall r. String -> Eff (trace :: Trace | r) Unit
8741044
8751045 print :: forall a r. (Show a) => a -> Eff (trace :: Trace | r) Unit
8761046 print o = trace (show o)
@@ -883,37 +1053,52 @@ module Control.Monad.ST where
8831053
8841054 foreign import data STRef :: * -> * -> *
8851055
886− foreign import newSTRef "function newSTRef(val) {\
887− \ return function() {\
888− \ return { value: val };\
889− \ };\
890− \}" :: forall a h r. a -> Eff (st :: ST h | r) (STRef h a)
891−
892− foreign import readSTRef "function readSTRef(ref) {\
893− \ return function() {\
894− \ return ref.value;\
895− \ };\
896− \}" :: forall a h r. STRef h a -> Eff (st :: ST h | r) a
897−
898− foreign import modifySTRef "function modifySTRef(ref) {\
899− \ return function(f) {\
900− \ return function() {\
901− \ return ref.value = f(ref.value);\
902− \ };\
903− \ };\
904− \}" :: forall a h r. STRef h a -> (a -> a) -> Eff (st :: ST h | r) a
905−
906− foreign import writeSTRef "function writeSTRef(ref) {\
907− \ return function(a) {\
908− \ return function() {\
909− \ return ref.value = a;\
910− \ };\
911− \ };\
912− \}" :: forall a h r. STRef h a -> a -> Eff (st :: ST h | r) a
913−
914− foreign import runST "function runST(f) {\
915− \ return f;\
916− \}" :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
1056+ foreign import newSTRef
1057+ """
1058+ function newSTRef(val) {
1059+ return function() {
1060+ return { value: val };
1061+ };
1062+ }
1063+ """ :: forall a h r. a -> Eff (st :: ST h | r) (STRef h a)
1064+
1065+ foreign import readSTRef
1066+ """
1067+ function readSTRef(ref) {
1068+ return function() {
1069+ return ref.value;
1070+ };
1071+ }
1072+ """ :: forall a h r. STRef h a -> Eff (st :: ST h | r) a
1073+
1074+ foreign import modifySTRef
1075+ """
1076+ function modifySTRef(ref) {
1077+ return function(f) {
1078+ return function() {
1079+ return ref.value = f(ref.value);
1080+ };
1081+ };
1082+ }
1083+ """ :: forall a h r. STRef h a -> (a -> a) -> Eff (st :: ST h | r) a
1084+
1085+ foreign import writeSTRef
1086+ """
1087+ function writeSTRef(ref) {
1088+ return function(a) {
1089+ return function() {
1090+ return ref.value = a;
1091+ };
1092+ };
1093+ }
1094+ """ :: forall a h r. STRef h a -> a -> Eff (st :: ST h | r) a
1095+
1096+ foreign import runST
1097+ """
1098+ function runST(f) {
1099+ return f;
1100+ }
1101+ """ :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
9171102
9181103 pureST :: forall a. (forall h r. Eff (st :: ST h | r) a) -> a
9191104 pureST st = runPure (runST st)
prelude/updateDocs.sh+1−1
@@ -1,5 +1,5 @@
11../dist/build/psc-docs/psc-docs --hierarchy-images prelude.purs > README.md
2−../dist/build/hierarchy/hierarchy prelude.purs -o prelude
2+../dist/build/psc-hierarchy/psc-hierarchy prelude.purs -o prelude
33
44mkdir -p images
55
psc-docs/Main.hs+111−105
@@ -18,39 +18,35 @@ import Control.Applicative
1818import Control.Monad
1919import Control.Monad.Writer
2020import Control.Arrow (first)
21−import Data.Function (on)
2221import Data.List
2322import Data.Maybe (fromMaybe)
2423import Data.Version (showVersion)
24+import Data.Foldable (traverse_)
2525
2626import Options.Applicative
2727
2828import qualified Language.PureScript as P
2929import qualified Paths_purescript as Paths
30−import qualified System.IO.UTF8 as U
3130import System.Exit (exitSuccess, exitFailure)
32−import System.IO (stderr)
33−
31+import System.IO (hPutStrLn, stderr)
3432
3533data PSCDocsOptions = PSCDocsOptions
36− { pscdIncludeHeir :: Bool
37− , pscdInputFiles :: [FilePath]
34+ { pscdInputFiles :: [FilePath]
3835 }
3936
40−
4137docgen :: PSCDocsOptions -> IO ()
42−docgen (PSCDocsOptions showHierarchy input) = do
38+docgen (PSCDocsOptions input) = do
4339 e <- P.parseModulesFromFiles (fromMaybe "") <$> mapM (fmap (first Just) . parseFile) (nub input)
4440 case e of
4541 Left err -> do
46− U.hPutStr stderr $ show err
42+ hPutStrLn stderr $ show err
4743 exitFailure
4844 Right ms -> do
49− U.putStrLn . runDocs $ (renderModules showHierarchy) (map snd ms)
45+ putStrLn . runDocs $ renderModules (map snd ms)
5046 exitSuccess
5147
5248parseFile :: FilePath -> IO (FilePath, String)
53−parseFile input = (,) input <$> U.readFile input
49+parseFile input = (,) input <$> readFile input
5450
5551type Docs = Writer [String] ()
5652
@@ -63,98 +59,126 @@ spacer = tell [""]
6359headerLevel :: Int -> String -> Docs
6460headerLevel level hdr = tell [replicate level '#' ++ ' ' : hdr]
6561
62+withIndent :: Int -> Docs -> Docs
63+withIndent indent = censor (map (replicate indent ' ' ++ ))
64+
6665atIndent :: Int -> String -> Docs
6766atIndent indent text =
6867 let ls = lines text in
69− forM_ ls $ \l -> tell [replicate indent ' ' ++ l]
68+ withIndent indent (tell ls)
69+
70+fenced :: String -> Docs
71+fenced text = fencedBlock (tell $ lines text)
72+
73+fencedBlock :: Docs -> Docs
74+fencedBlock inner = do
75+ tell ["``` purescript"]
76+ inner
77+ tell ["```"]
78+
79+ticks :: String -> String
80+ticks = ("`" ++) . (++ "`")
7081
71−renderModules :: Bool -> [P.Module] -> Docs
72−renderModules showHierarchy ms = do
82+renderModules :: [P.Module] -> Docs
83+renderModules ms = do
7384 headerLevel 1 "Module Documentation"
7485 spacer
75− mapM_ (renderModule showHierarchy) ms
76−
77−renderModule :: Bool -> P.Module -> Docs
78−renderModule showHierarchy mdl@(P.Module moduleName _ exps) =
79− let ds = P.exportedDeclarations mdl
80− hasTypes = any isTypeDeclaration ds
81− hasTypeclasses = any isTypeClassDeclaration ds
82− hasTypeclassInstances = any isTypeInstanceDeclaration ds
83− hasValues = any isValueDeclaration ds
84− in do
86+ mapM_ renderModule ms
87+
88+renderModule :: P.Module -> Docs
89+renderModule mdl@(P.Module moduleName _ exps) = do
8590 headerLevel 2 $ "Module " ++ P.runModuleName moduleName
8691 spacer
87− when hasTypes $ do
88− headerLevel 3 "Types"
89− spacer
90− renderTopLevel exps (filter isTypeDeclaration ds)
91− spacer
92− when hasTypeclasses $ do
93− headerLevel 3 "Type Classes"
94− spacer
95− when showHierarchy $ do
96− renderTypeclassImage moduleName
97− spacer
98− renderTopLevel exps (filter isTypeClassDeclaration ds)
99− spacer
100− when hasTypeclassInstances $ do
101− headerLevel 3 "Type Class Instances"
102− spacer
103− renderTopLevel exps (filter isTypeInstanceDeclaration ds)
104− spacer
105− when hasValues $ do
106− headerLevel 3 "Values"
107− spacer
108− renderTopLevel exps (filter isValueDeclaration ds)
109− spacer
92+ renderTopLevel exps (P.exportedDeclarations mdl)
93+ spacer
11094
11195renderTopLevel :: Maybe [P.DeclarationRef] -> [P.Declaration] -> Docs
112−renderTopLevel exps decls = forM_ (sortBy (compare `on` getName) decls) $ \decl -> do
113− renderDeclaration 4 exps decl
114− spacer
96+renderTopLevel exps decls = forM_ decls $ \decl ->
97+ when (canRenderDecl decl) $ do
98+ traverse_ (headerLevel 4) (ticks `fmap` getDeclarationTitle decl)
99+ spacer
100+ renderDeclaration exps decl
101+ spacer
115102
116103renderTypeclassImage :: P.ModuleName -> Docs
117104renderTypeclassImage name =
118105 let name' = P.runModuleName name
119106 in tell ["![" ++ name' ++ "](images/" ++ name' ++ ".png)"]
120107
121−renderDeclaration :: Int -> Maybe [P.DeclarationRef] -> P.Declaration -> Docs
122−renderDeclaration n _ (P.TypeDeclaration ident ty) =
123− atIndent n $ show ident ++ " :: " ++ prettyPrintType' ty
124−renderDeclaration n _ (P.ExternDeclaration _ ident _ ty) =
125− atIndent n $ show ident ++ " :: " ++ prettyPrintType' ty
126−renderDeclaration n exps (P.DataDeclaration dtype name args ctors) = do
108+getDeclarationTitle :: P.Declaration -> Maybe String
109+getDeclarationTitle (P.TypeDeclaration name _) = Just (show name)
110+getDeclarationTitle (P.ExternDeclaration _ name _ _) = Just (show name)
111+getDeclarationTitle (P.DataDeclaration _ name _ _) = Just (show name)
112+getDeclarationTitle (P.ExternDataDeclaration name _) = Just (show name)
113+getDeclarationTitle (P.TypeSynonymDeclaration name _ _) = Just (show name)
114+getDeclarationTitle (P.TypeClassDeclaration name _ _ _) = Just (show name)
115+getDeclarationTitle (P.TypeInstanceDeclaration name _ _ _ _) = Just (show name)
116+getDeclarationTitle (P.PositionedDeclaration _ _ d) = getDeclarationTitle d
117+getDeclarationTitle _ = Nothing
118+
119+renderDeclaration :: Maybe [P.DeclarationRef] -> P.Declaration -> Docs
120+renderDeclaration _ (P.TypeDeclaration ident ty) =
121+ fenced $ show ident ++ " :: " ++ prettyPrintType' ty
122+renderDeclaration _ (P.ExternDeclaration _ ident _ ty) =
123+ fenced $ show ident ++ " :: " ++ prettyPrintType' ty
124+renderDeclaration exps (P.DataDeclaration dtype name args ctors) = do
127125 let
128126 typeApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
129127 typeName = prettyPrintType' typeApp
130128 exported = filter (P.isDctorExported name exps . fst) ctors
131− atIndent n $ show dtype ++ " " ++ typeName ++ (if null exported then "" else " where")
132− forM_ exported $ \(ctor, tys) ->
133− let ctorTy = foldr P.function typeApp tys
134− in atIndent (n + 2) $ P.runProperName ctor ++ " :: " ++ prettyPrintType' ctorTy
135−renderDeclaration n _ (P.ExternDataDeclaration name kind) =
136− atIndent n $ "data " ++ P.runProperName name ++ " :: " ++ P.prettyPrintKind kind
137−renderDeclaration n _ (P.TypeSynonymDeclaration name args ty) = do
129+ fencedBlock $ do
130+ tell [show dtype ++ " " ++ typeName]
131+ zipWithM_ (\isFirst (ctor, tys) ->
132+ atIndent 2 $ (if isFirst then "= " else "| ") ++ P.runProperName ctor ++ " " ++ unwords (map P.prettyPrintTypeAtom tys))
133+ (True : repeat False) exported
134+renderDeclaration _ (P.ExternDataDeclaration name kind) =
135+ fenced $ "data " ++ P.runProperName name ++ " :: " ++ P.prettyPrintKind kind
136+renderDeclaration _ (P.TypeSynonymDeclaration name args ty) = do
138137 let
139138 typeApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
140− typeName = prettyPrintType' typeApp
141− atIndent n $ "type " ++ typeName ++ " = " ++ prettyPrintType' ty
142−renderDeclaration n exps (P.TypeClassDeclaration name args implies ds) = do
139+ typeName = prettyPrintType' typeApp
140+ fenced $ "type " ++ typeName ++ " = " ++ prettyPrintType' ty
141+renderDeclaration _ (P.TypeClassDeclaration name args implies ds) = do
143142 let impliesText = case implies of
144143 [] -> ""
145144 is -> "(" ++ intercalate ", " (map (\(pn, tys') -> show pn ++ " " ++ unwords (map P.prettyPrintTypeAtom tys')) is) ++ ") <= "
146145 classApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
147146 className = prettyPrintType' classApp
148− atIndent n $ "class " ++ impliesText ++ className ++ " where"
149− mapM_ (renderDeclaration (n + 2) exps) ds
150−renderDeclaration n _ (P.TypeInstanceDeclaration name constraints className tys _) = do
147+ fencedBlock $ do
148+ tell ["class " ++ impliesText ++ className ++ " where"]
149+ mapM_ renderClassMember ds
150+ where
151+ renderClassMember (P.PositionedDeclaration _ _ d) = renderClassMember d
152+ renderClassMember (P.TypeDeclaration ident ty) = atIndent 2 $ show ident ++ " :: " ++ prettyPrintType' ty
153+ renderClassMember _ = error "Invalid argument to renderClassMember."
154+renderDeclaration _ (P.TypeInstanceDeclaration name constraints className tys _) = do
151155 let constraintsText = case constraints of
152156 [] -> ""
153157 cs -> "(" ++ intercalate ", " (map (\(pn, tys') -> show pn ++ " " ++ unwords (map P.prettyPrintTypeAtom tys')) cs) ++ ") => "
154− atIndent n $ "instance " ++ show name ++ " :: " ++ constraintsText ++ show className ++ " " ++ unwords (map P.prettyPrintTypeAtom tys)
155−renderDeclaration n exps (P.PositionedDeclaration _ d) =
156− renderDeclaration n exps d
157−renderDeclaration _ _ _ = return ()
158+ fenced $ "instance " ++ show name ++ " :: " ++ constraintsText ++ show className ++ " " ++ unwords (map P.prettyPrintTypeAtom tys)
159+renderDeclaration exps (P.PositionedDeclaration _ com d) = do
160+ renderDeclaration exps d
161+ renderComments com
162+renderDeclaration _ _ = return ()
163+
164+renderComments :: [P.Comment] -> Docs
165+renderComments cs = do
166+ let raw = concatMap toLines cs
167+ when (all hasPipe raw) $ do
168+ spacer
169+ atIndent 0 . unlines . map stripPipes $ raw
170+ where
171+
172+ toLines (P.LineComment s) = [s]
173+ toLines (P.BlockComment s) = lines s
174+
175+ hasPipe s = case dropWhile (== ' ') s of { ('|':_) -> True; _ -> False }
176+
177+ stripPipes = dropPipe . dropWhile (== ' ')
178+
179+ dropPipe ('|':' ':s) = s
180+ dropPipe ('|':s) = s
181+ dropPipe s = s
158182
159183toTypeVar :: (String, Maybe P.Kind) -> P.Type
160184toTypeVar (s, Nothing) = P.TypeVar s
@@ -176,45 +200,27 @@ getName (P.ExternDataDeclaration name _) = P.runProperName name
176200getName (P.TypeSynonymDeclaration name _ _) = P.runProperName name
177201getName (P.TypeClassDeclaration name _ _ _) = P.runProperName name
178202getName (P.TypeInstanceDeclaration name _ _ _ _) = show name
179−getName (P.PositionedDeclaration _ d) = getName d
203+getName (P.PositionedDeclaration _ _ d) = getName d
180204getName _ = error "Invalid argument to getName"
181205
182−isValueDeclaration :: P.Declaration -> Bool
183−isValueDeclaration P.TypeDeclaration{} = True
184−isValueDeclaration P.ExternDeclaration{} = True
185−isValueDeclaration (P.PositionedDeclaration _ d) = isValueDeclaration d
186−isValueDeclaration _ = False
187−
188−isTypeDeclaration :: P.Declaration -> Bool
189−isTypeDeclaration P.DataDeclaration{} = True
190−isTypeDeclaration P.ExternDataDeclaration{} = True
191−isTypeDeclaration P.TypeSynonymDeclaration{} = True
192−isTypeDeclaration (P.PositionedDeclaration _ d) = isTypeDeclaration d
193−isTypeDeclaration _ = False
194−
195−isTypeClassDeclaration :: P.Declaration -> Bool
196−isTypeClassDeclaration P.TypeClassDeclaration{} = True
197−isTypeClassDeclaration (P.PositionedDeclaration _ d) = isTypeClassDeclaration d
198−isTypeClassDeclaration _ = False
199−
200−isTypeInstanceDeclaration :: P.Declaration -> Bool
201−isTypeInstanceDeclaration P.TypeInstanceDeclaration{} = True
202−isTypeInstanceDeclaration (P.PositionedDeclaration _ d) = isTypeInstanceDeclaration d
203−isTypeInstanceDeclaration _ = False
206+canRenderDecl :: P.Declaration -> Bool
207+canRenderDecl P.TypeDeclaration{} = True
208+canRenderDecl P.ExternDeclaration{} = True
209+canRenderDecl P.DataDeclaration{} = True
210+canRenderDecl P.ExternDataDeclaration{} = True
211+canRenderDecl P.TypeSynonymDeclaration{} = True
212+canRenderDecl P.TypeClassDeclaration{} = True
213+canRenderDecl P.TypeInstanceDeclaration{} = True
214+canRenderDecl (P.PositionedDeclaration _ _ d) = canRenderDecl d
215+canRenderDecl _ = False
204216
205217inputFile :: Parser FilePath
206218inputFile = strArgument $
207219 metavar "FILE"
208− <> help "The input .ps file(s)"
209−
210−includeHeirarcy :: Parser Bool
211−includeHeirarcy = switch $
212− long "hierarchy-images"
213− <> help "Include markdown for type class hierarchy images in the output."
220+ <> help "The input .purs file(s)"
214221
215222pscDocsOptions :: Parser PSCDocsOptions
216−pscDocsOptions = PSCDocsOptions <$> includeHeirarcy
217− <*> many inputFile
223+pscDocsOptions = PSCDocsOptions <$> many inputFile
218224
219225main :: IO ()
220226main = execParser opts >>= docgen
@@ -223,6 +229,6 @@ main = execParser opts >>= docgen
223229 infoModList = fullDesc <> headerInfo <> footerInfo
224230 headerInfo = header "psc-docs - Generate Markdown documentation from PureScript extern files"
225231 footerInfo = footer $ "psc-docs " ++ showVersion Paths.version
226−
232+
227233 version :: Parser (a -> a)
228234 version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
psc-make/Main.hs+37−31
@@ -17,9 +17,11 @@
1717module Main where
1818
1919import Control.Applicative
20−import Control.Monad.Error
20+import Control.Monad.Except
21+import Control.Monad.Reader
2122
2223import Data.Version (showVersion)
24+import Data.Traversable (traverse)
2325
2426import Options.Applicative as Opts
2527
@@ -31,7 +33,6 @@ import System.IO.Error (tryIOError)
3133
3234import qualified Language.PureScript as P
3335import qualified Paths_purescript as Paths
34−import qualified System.IO.UTF8 as U
3536
3637
3738data PSCMakeOptions = PSCMakeOptions
@@ -48,45 +49,43 @@ data InputOptions = InputOptions
4849
4950readInput :: InputOptions -> IO [(Either P.RebuildPolicy FilePath, String)]
5051readInput InputOptions{..} = do
51− content <- forM ioInputFiles $ \inFile -> (Right inFile, ) <$> U.readFile inFile
52+ content <- forM ioInputFiles $ \inFile -> (Right inFile, ) <$> readFile inFile
5253 return (if ioNoPrelude then content else (Left P.RebuildNever, P.prelude) : content)
5354
54−newtype Make a = Make { unMake :: ErrorT String IO a } deriving (Functor, Applicative, Monad, MonadIO, MonadError String)
55+newtype Make a = Make { unMake :: ReaderT (P.Options P.Make) (ExceptT String IO) a }
56+ deriving (Functor, Applicative, Monad, MonadIO, MonadError String, MonadReader (P.Options P.Make))
5557
56−runMake :: Make a -> IO (Either String a)
57−runMake = runErrorT . unMake
58+runMake :: P.Options P.Make -> Make a -> IO (Either String a)
59+runMake opts = runExceptT . flip runReaderT opts . unMake
5860
5961makeIO :: IO a -> Make a
60−makeIO = Make . ErrorT . fmap (either (Left . show) Right) . tryIOError
62+makeIO = Make . lift . ExceptT . fmap (either (Left . show) Right) . tryIOError
6163
6264instance P.MonadMake Make where
6365 getTimestamp path = makeIO $ do
6466 exists <- doesFileExist path
65− case exists of
66− True -> Just <$> getModificationTime path
67− False -> return Nothing
67+ traverse (const $ getModificationTime path) $ guard exists
6868 readTextFile path = makeIO $ do
69− U.putStrLn $ "Reading " ++ path
70− U.readFile path
69+ putStrLn $ "Reading " ++ path
70+ readFile path
7171 writeTextFile path text = makeIO $ do
7272 mkdirp path
73− U.putStrLn $ "Writing " ++ path
74− U.writeFile path text
75− liftError = either throwError return
76− progress = makeIO . U.putStrLn
73+ putStrLn $ "Writing " ++ path
74+ writeFile path text
75+ progress = makeIO . putStrLn
7776
7877compile :: PSCMakeOptions -> IO ()
7978compile (PSCMakeOptions input outputDir opts usePrefix) = do
8079 modules <- P.parseModulesFromFiles (either (const "") id) <$> readInput (InputOptions (P.optionsNoPrelude opts) input)
8180 case modules of
8281 Left err -> do
83− U.print err
82+ print err
8483 exitFailure
8584 Right ms -> do
86− e <- runMake $ P.make outputDir opts ms prefix
85+ e <- runMake opts $ P.make outputDir ms prefix
8786 case e of
8887 Left err -> do
89− U.putStrLn err
88+ putStrLn err
9089 exitFailure
9190 Right _ -> do
9291 exitSuccess
@@ -101,7 +100,7 @@ mkdirp = createDirectoryIfMissing True . takeDirectory
101100inputFile :: Parser FilePath
102101inputFile = strArgument $
103102 metavar "FILE"
104− <> help "The input .ps file(s)"
103+ <> help "The input .purs file(s)"
105104
106105outputDirectory :: Parser FilePath
107106outputDirectory = strOption $
@@ -112,12 +111,12 @@ outputDirectory = strOption $
112111 <> help "The output directory"
113112
114113noTco :: Parser Bool
115−noTco = switch $
114+noTco = switch $
116115 long "no-tco"
117116 <> help "Disable tail call optimizations"
118117
119118noPrelude :: Parser Bool
120−noPrelude = switch $
119+noPrelude = switch $
121120 long "no-prelude"
122121 <> help "Omit the Prelude"
123122
@@ -128,35 +127,42 @@ noMagicDo = switch $
128127
129128noOpts :: Parser Bool
130129noOpts = switch $
131− long "verbose-errors"
130+ long "no-opts"
132131 <> help "Skip the optimization phase."
133132
133+comments :: Parser Bool
134+comments = switch $
135+ short 'c'
136+ <> long "comments"
137+ <> help "Include comments in the generated code."
138+
134139verboseErrors :: Parser Bool
135140verboseErrors = switch $
136141 short 'v'
137− <> long "no-opts"
142+ <> long "verbose-errors"
138143 <> help "Display verbose error messages"
139144
140145noPrefix :: Parser Bool
141−noPrefix = switch $
146+noPrefix = switch $
142147 short 'p'
143148 <> long "no-prefix"
144149 <> help "Do not include comment header"
145150
146151
147152options :: Parser (P.Options P.Make)
148−options = P.Options <$> noPrelude
149− <*> noTco
153+options = P.Options <$> noPrelude
154+ <*> noTco
150155 <*> noMagicDo
151156 <*> pure Nothing
152157 <*> noOpts
158+ <*> comments
153159 <*> verboseErrors
154160 <*> pure P.MakeOptions
155161
156162pscMakeOptions :: Parser PSCMakeOptions
157−pscMakeOptions = PSCMakeOptions <$> many inputFile
158− <*> outputDirectory
159− <*> options
163+pscMakeOptions = PSCMakeOptions <$> many inputFile
164+ <*> outputDirectory
165+ <*> options
160166 <*> (not <$> noPrefix)
161167
162168main :: IO ()
@@ -166,6 +172,6 @@ main = execParser opts >>= compile
166172 infoModList = fullDesc <> headerInfo <> footerInfo
167173 headerInfo = header "psc-make - Compiles PureScript to Javascript"
168174 footerInfo = footer $ "psc-make " ++ showVersion Paths.version
169−
175+
170176 version :: Parser (a -> a)
171177 version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
psc/Main.hs+30−23
@@ -17,7 +17,8 @@
1717module Main where
1818
1919import Control.Applicative
20−import Control.Monad.Error
20+import Control.Monad.Except
21+import Control.Monad.Reader
2122
2223import Data.Maybe (fromMaybe)
2324import Data.Version (showVersion)
@@ -26,11 +27,10 @@ import Options.Applicative as Opts
2627import System.Directory (createDirectoryIfMissing)
2728import System.FilePath (takeDirectory)
2829import System.Exit (exitSuccess, exitFailure)
29−import System.IO (stderr)
30+import System.IO (hPutStrLn, stderr)
3031
3132import qualified Language.PureScript as P
3233import qualified Paths_purescript as Paths
33−import qualified System.IO.UTF8 as U
3434
3535
3636data PSCOptions = PSCOptions
@@ -51,7 +51,7 @@ data InputOptions = InputOptions
5151readInput :: InputOptions -> IO [(Maybe FilePath, String)]
5252readInput InputOptions{..}
5353 | ioUseStdIn = return . (Nothing ,) <$> getContents
54− | otherwise = do content <- forM ioInputFiles $ \inFile -> (Just inFile, ) <$> U.readFile inFile
54+ | otherwise = do content <- forM ioInputFiles $ \inFile -> (Just inFile, ) <$> readFile inFile
5555 return (if ioNoPrelude then content else (Nothing, P.prelude) : content)
5656
5757compile :: PSCOptions -> IO ()
@@ -59,19 +59,19 @@ compile (PSCOptions input opts stdin output externs usePrefix) = do
5959 modules <- P.parseModulesFromFiles (fromMaybe "") <$> readInput (InputOptions (P.optionsNoPrelude opts) stdin input)
6060 case modules of
6161 Left err -> do
62− U.hPutStr stderr $ show err
62+ hPutStrLn stderr $ show err
6363 exitFailure
6464 Right ms -> do
65− case P.compile opts (map snd ms) prefix of
65+ case P.compile (map snd ms) prefix `runReaderT` opts of
6666 Left err -> do
67− U.hPutStrLn stderr err
67+ hPutStrLn stderr err
6868 exitFailure
6969 Right (js, exts, _) -> do
7070 case output of
71− Just path -> mkdirp path >> U.writeFile path js
72− Nothing -> U.putStrLn js
71+ Just path -> mkdirp path >> writeFile path js
72+ Nothing -> putStrLn js
7373 case externs of
74− Just path -> mkdirp path >> U.writeFile path exts
74+ Just path -> mkdirp path >> writeFile path exts
7575 Nothing -> return ()
7676 exitSuccess
7777 where
@@ -116,28 +116,34 @@ runMain = optional $ noArgs <|> withArgs
116116 where
117117 defaultVal = "Main"
118118 noArgs = flag' defaultVal (long "main")
119− withArgs = strOption $
119+ withArgs = strOption $
120120 long "main"
121121 <> help (concat [
122122 "Generate code to run the main method in the specified module. ",
123123 "(no argument: \"", defaultVal, "\")"
124124 ])
125−
125+
126126noMagicDo :: Parser Bool
127127noMagicDo = switch $
128128 long "no-magic-do"
129129 <> help "Disable the optimization that overloads the do keyword to generate efficient code specifically for the Eff monad."
130−
130+
131131noTco :: Parser Bool
132−noTco = switch $
132+noTco = switch $
133133 long "no-tco"
134134 <> help "Disable tail call optimizations"
135135
136136noPrelude :: Parser Bool
137−noPrelude = switch $
137+noPrelude = switch $
138138 long "no-prelude"
139139 <> help "Omit the Prelude"
140140
141+comments :: Parser Bool
142+comments = switch $
143+ short 'c'
144+ <> long "comments"
145+ <> help "Include comments in the generated code."
146+
141147useStdIn :: Parser Bool
142148useStdIn = switch $
143149 short 's'
@@ -147,7 +153,7 @@ useStdIn = switch $
147153inputFile :: Parser FilePath
148154inputFile = strArgument $
149155 metavar "FILE"
150− <> help "The input .ps file(s)"
156+ <> help "The input .purs file(s)"
151157
152158outputFile :: Parser (Maybe FilePath)
153159outputFile = optional . strOption $
@@ -159,25 +165,26 @@ externsFile :: Parser (Maybe FilePath)
159165externsFile = optional . strOption $
160166 short 'e'
161167 <> long "externs"
162− <> help "The output .e.ps file"
168+ <> help "The output .e.purs file"
163169
164170noPrefix :: Parser Bool
165−noPrefix = switch $
171+noPrefix = switch $
166172 short 'p'
167173 <> long "no-prefix"
168174 <> help "Do not include comment header"
169175
170176options :: Parser (P.Options P.Compile)
171−options = P.Options <$> noPrelude
172− <*> noTco
177+options = P.Options <$> noPrelude
178+ <*> noTco
173179 <*> noMagicDo
174180 <*> runMain
175181 <*> noOpts
176182 <*> verboseErrors
183+ <*> comments
177184 <*> additionalOptions
178185 where
179− additionalOptions =
180− P.CompileOptions <$> browserNamespace
186+ additionalOptions =
187+ P.CompileOptions <$> browserNamespace
181188 <*> many dceModule
182189 <*> many codeGenModule
183190
@@ -196,7 +203,7 @@ main = execParser opts >>= compile
196203 infoModList = fullDesc <> headerInfo <> footerInfo
197204 headerInfo = header "psc - Compiles PureScript to Javascript"
198205 footerInfo = footer $ "psc " ++ showVersion Paths.version
199−
206+
200207 version :: Parser (a -> a)
201208 version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
202209
psci/Commands.hs+1−1
@@ -52,7 +52,7 @@ data Command
5252 -- |
5353 -- Binds a value to a name
5454 --
55− | Let (Expr -> Expr)
55+ | Let [Declaration]
5656 -- |
5757 -- Find the type of an expression
5858 --
psci/Main.hs+138−95
@@ -13,7 +13,11 @@
1313--
1414-----------------------------------------------------------------------------
1515
16−{-# LANGUAGE DataKinds, DoAndIfThenElse, FlexibleContexts, GeneralizedNewtypeDeriving #-}
16+{-# LANGUAGE DataKinds #-}
17+{-# LANGUAGE DoAndIfThenElse #-}
18+{-# LANGUAGE FlexibleContexts #-}
19+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
20+{-# LANGUAGE RecordWildCards #-}
1721
1822module Main where
1923
@@ -27,8 +31,8 @@ import qualified Data.Map as M
2731
2832import Control.Applicative
2933import Control.Monad
30−import Control.Monad.Error (ErrorT(..), MonadError)
31−import Control.Monad.Error.Class (MonadError(..))
34+import Control.Monad.Except (ExceptT(..), MonadError, runExceptT)
35+import Control.Monad.Reader (MonadReader, ReaderT, runReaderT)
3236import Control.Monad.Trans.Class
3337import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
3438import Control.Monad.Trans.State.Strict
@@ -42,7 +46,6 @@ import System.Exit
4246import System.FilePath (pathSeparator, takeDirectory, (</>), isPathSeparator)
4347import System.IO.Error (tryIOError)
4448import System.Process (readProcessWithExitCode)
45−import qualified System.IO.UTF8 as U (writeFile, putStrLn, print, readFile)
4649
4750import qualified Text.Parsec as Par (ParseError)
4851
@@ -54,11 +57,10 @@ import qualified Paths_purescript as Paths
5457import Commands as C
5558import Parser
5659
57−
5860data PSCiOptions = PSCiOptions
59− { psciSingleLineFlag :: Bool
60− , psciInputNodeFlags :: [String]
61+ { psciMultiLineMode :: Bool
6162 , psciInputFile :: [FilePath]
63+ , psciInputNodeFlags :: [String]
6264 }
6365
6466-- |
@@ -71,7 +73,7 @@ data PSCiState = PSCiState
7173 { psciImportedFilenames :: [FilePath]
7274 , psciImportedModuleNames :: [P.ModuleName]
7375 , psciLoadedModules :: [(Either P.RebuildPolicy FilePath, P.Module)]
74− , psciLetBindings :: [P.Expr -> P.Expr]
76+ , psciLetBindings :: [P.Declaration]
7577 , psciNodeFlags :: [String]
7678 }
7779
@@ -98,8 +100,8 @@ updateModules modules st = st { psciLoadedModules = psciLoadedModules st ++ modu
98100-- |
99101-- Updates the state to have more let bindings.
100102--
101−updateLets :: (P.Expr -> P.Expr) -> PSCiState -> PSCiState
102−updateLets name st = st { psciLetBindings = name : psciLetBindings st }
103+updateLets :: [P.Declaration] -> PSCiState -> PSCiState
104+updateLets ds st = st { psciLetBindings = psciLetBindings st ++ ds }
103105
104106-- File helpers
105107-- |
@@ -131,7 +133,7 @@ getHistoryFilename = do
131133--
132134loadModule :: FilePath -> IO (Either String [P.Module])
133135loadModule filename = do
134− content <- U.readFile filename
136+ content <- readFile filename
135137 return $ either (Left . show) (Right . map snd) $ P.parseModulesFromFiles id [(filename, content)]
136138
137139-- |
@@ -140,10 +142,20 @@ loadModule filename = do
140142loadAllModules :: [FilePath] -> IO (Either Par.ParseError [(Either P.RebuildPolicy FilePath, P.Module)])
141143loadAllModules files = do
142144 filesAndContent <- forM files $ \filename -> do
143− content <- U.readFile filename
145+ content <- readFile filename
144146 return (Right filename, content)
145147 return $ P.parseModulesFromFiles (either (const "") id) $ (Left P.RebuildNever, P.prelude) : filesAndContent
146148
149+-- |
150+-- Load all modules, updating the application state
151+--
152+loadAllImportedModules :: PSCI ()
153+loadAllImportedModules = do
154+ files <- PSCI . lift $ fmap psciImportedFilenames get
155+ modulesOrFirstError <- psciIO $ loadAllModules files
156+ case modulesOrFirstError of
157+ Left err -> psciIO $ print err
158+ Right modules -> PSCI . lift . modify $ \st -> st { psciLoadedModules = modules }
147159
148160-- |
149161-- Expands tilde in path.
@@ -175,8 +187,6 @@ prologueMessage = intercalate "\n"
175187 , " |_| "
176188 , ""
177189 , ":? shows help"
178− , ""
179− , "Expressions are terminated using Ctrl+D"
180190 ]
181191
182192-- |
@@ -187,27 +197,28 @@ quitMessage = "See ya!"
187197
188198-- Haskeline completions
189199
190−data CompletionContext = Command String | FilePath | Module | Identifier | Fixed [String] | Multiple [CompletionContext]
200+data CompletionContext = Command String | FilePath String | Module | Identifier
201+ | Type | Fixed [String] | Multiple [CompletionContext]
191202 deriving (Show)
192203
193204-- |
194205-- Decide what kind of completion we need based on input.
195−completionContext :: String -> Maybe CompletionContext
196−completionContext cmd@"" = Just $ Multiple [Command cmd, Identifier]
197−completionContext cmd@(':' : _ )
206+completionContext :: String -> String -> Maybe CompletionContext
207+completionContext cmd@"" _ = Just $ Multiple [Command cmd, Identifier]
208+completionContext cmd@(':' : _ ) _
198209 | cmd `elem` C.commands || cmd == ":" = Just $ Command cmd
199−completionContext (':' : c : _) = case c of
210+completionContext (':' : c : _) word = case c of
200211 'i' -> Just Module
201212 'b' -> Just Module
202− 'm' -> Just FilePath
213+ 'm' -> Just $ FilePath word
203214 'q' -> Nothing
204215 'r' -> Nothing
205216 '?' -> Nothing
206217 's' -> Just $ Fixed ["import", "loaded"]
207218 't' -> Just Identifier
208− 'k' -> Just Identifier
219+ 'k' -> Just Type
209220 _ -> Nothing
210−completionContext _ = Just Identifier
221+completionContext _ _ = Just Identifier
211222
212223-- |
213224-- Loads module, function, and file completions.
@@ -217,22 +228,23 @@ completion = completeWordWithPrev Nothing " \t\n\r" findCompletions
217228 where
218229 findCompletions :: String -> String -> StateT PSCiState IO [Completion]
219230 findCompletions prev word = do
220− let ctx = completionContext $ (dropWhile isSpace (reverse prev)) ++ word
231+ let ctx = completionContext ((dropWhile isSpace (reverse prev)) ++ word) word
221232 completions <- case ctx of
222233 Nothing -> return []
223234 (Just c) -> (mapMaybe $ either (\cand -> if word `isPrefixOf` cand
224235 then Just $ simpleCompletion cand
225236 else Nothing) Just)
226− <$> getCompletion c word
237+ <$> getCompletion c
227238 return $ sortBy sorter completions
228239
229− getCompletion :: CompletionContext -> String -> StateT PSCiState IO [Either String Completion]
230− getCompletion (Command s) _ = return $ (map Left) $ nub $ filter (isPrefixOf s) C.commands
231− getCompletion FilePath f = (map Right) <$> listFiles f
232− getCompletion Module _ = (map Left) <$> getModuleNames
233− getCompletion Identifier _ = (map Left) <$> getIdentNames
234− getCompletion (Fixed list) _ = return $ (map Left) list
235− getCompletion (Multiple contexts) f = concat <$> mapM (flip getCompletion $ f) contexts
240+ getCompletion :: CompletionContext -> StateT PSCiState IO [Either String Completion]
241+ getCompletion (Command s) = return $ (map Left) $ nub $ filter (isPrefixOf s) C.commands
242+ getCompletion (FilePath f) = (map Right) <$> listFiles f
243+ getCompletion Module = (map Left) <$> getModuleNames
244+ getCompletion Identifier = (map Left) <$> ((++) <$> getIdentNames <*> getDctorNames)
245+ getCompletion Type = (map Left) <$> getTypeNames
246+ getCompletion (Fixed list) = return $ (map Left) list
247+ getCompletion (Multiple contexts) = concat <$> mapM getCompletion contexts
236248
237249 getLoadedModules :: StateT PSCiState IO [P.Module]
238250 getLoadedModules = map snd . psciLoadedModules <$> get
@@ -240,30 +252,60 @@ completion = completeWordWithPrev Nothing " \t\n\r" findCompletions
240252 getModuleNames :: StateT PSCiState IO [String]
241253 getModuleNames = moduleNames <$> getLoadedModules
242254
255+ mapLoadedModulesAndQualify :: (Show a) => (P.Module -> [a]) -> StateT PSCiState IO [String]
256+ mapLoadedModulesAndQualify f = do
257+ ms <- getLoadedModules
258+ q <- sequence [qualifyIfNeeded m (f m) | m <- ms]
259+ return $ concat q
260+
243261 getIdentNames :: StateT PSCiState IO [String]
244− getIdentNames = identNames <$> getLoadedModules
245−
246− getDeclName :: Maybe [P.DeclarationRef] -> P.Declaration -> Maybe P.Ident
247− getDeclName exts (P.ValueDeclaration ident _ _ _) | isExported ident exts = Just ident
248− getDeclName exts (P.ExternDeclaration _ ident _ _) | isExported ident exts = Just ident
249− getDeclName exts (P.PositionedDeclaration _ d) = getDeclName exts d
250− getDeclName _ _ = Nothing
251−
252− isExported :: N.Ident -> Maybe [P.DeclarationRef] -> Bool
253− isExported ident = maybe True (any exports)
254− where
255− exports :: P.DeclarationRef -> Bool
256− exports (P.ValueRef ident') = ident == ident'
257− exports (P.PositionedDeclarationRef _ r) = exports r
258− exports _ = False
259−
260− identNames :: [P.Module] -> [String]
261− identNames ms = nub [ show qual
262− | P.Module moduleName ds exts <- ms
263− , ident <- mapMaybe (getDeclName exts) ds
264− , qual <- [ P.Qualified Nothing ident
265− , P.Qualified (Just moduleName) ident]
266− ]
262+ getIdentNames = mapLoadedModulesAndQualify identNames
263+
264+ getDctorNames :: StateT PSCiState IO [String]
265+ getDctorNames = mapLoadedModulesAndQualify dctorNames
266+
267+ getTypeNames :: StateT PSCiState IO [String]
268+ getTypeNames = mapLoadedModulesAndQualify typeDecls
269+
270+ qualifyIfNeeded :: (Show a) => P.Module -> [a] -> StateT PSCiState IO [String]
271+ qualifyIfNeeded m decls = do
272+ let name = P.getModuleName m
273+ imported <- psciImportedModuleNames <$> get
274+ let qualified = map (P.Qualified $ Just name) decls
275+ if name `elem` imported then
276+ return $ map show $ qualified ++ (map (P.Qualified Nothing) decls)
277+ else
278+ return $ map show qualified
279+
280+ typeDecls :: P.Module -> [N.ProperName]
281+ typeDecls m = mapMaybe getTypeName $ filter P.isDataDecl (P.exportedDeclarations m)
282+ where getTypeName :: P.Declaration -> Maybe N.ProperName
283+ getTypeName (P.TypeSynonymDeclaration name _ _) = Just name
284+ getTypeName (P.DataDeclaration _ name _ _) = Just name
285+ getTypeName (P.PositionedDeclaration _ _ d) = getTypeName d
286+ getTypeName _ = Nothing
287+
288+ identNames :: P.Module -> [N.Ident]
289+ identNames (P.Module _ ds exports) = nub [ ident | ident <- mapMaybe (getDeclName exports) (D.flattenDecls ds) ]
290+ where getDeclName :: Maybe [P.DeclarationRef] -> P.Declaration -> Maybe P.Ident
291+ getDeclName exts decl@(P.ValueDeclaration ident _ _ _) | P.isExported exts decl = Just ident
292+ getDeclName exts decl@(P.ExternDeclaration _ ident _ _) | P.isExported exts decl = Just ident
293+ getDeclName exts (P.PositionedDeclaration _ _ d) = getDeclName exts d
294+ getDeclName _ _ = Nothing
295+
296+ dctorNames :: P.Module -> [N.ProperName]
297+ dctorNames m = nub $ concat $ map (P.exportedDctors m) dnames
298+ where getDataDeclName :: P.Declaration -> Maybe N.ProperName
299+ getDataDeclName (P.DataDeclaration _ name _ _) = Just name
300+ getDataDeclName (P.PositionedDeclaration _ _ d) = getDataDeclName d
301+ getDataDeclName _ = Nothing
302+
303+ dnames :: [N.ProperName]
304+ dnames = (mapMaybe getDataDeclName onlyDataDecls)
305+
306+ onlyDataDecls :: [P.Declaration]
307+ onlyDataDecls = (filter P.isDataDecl (P.exportedDeclarations m))
308+
267309 moduleNames :: [P.Module] -> [String]
268310 moduleNames ms = nub [show moduleName | P.Module moduleName _ _ <- ms]
269311
@@ -275,7 +317,7 @@ completion = completeWordWithPrev Nothing " \t\n\r" findCompletions
275317-- | Compilation options.
276318--
277319options :: P.Options P.Make
278−options = P.Options False False False Nothing False False P.MakeOptions
320+options = P.Options False False False Nothing False False False P.MakeOptions
279321
280322-- |
281323-- PSCI monad
@@ -283,28 +325,26 @@ options = P.Options False False False Nothing False False P.MakeOptions
283325newtype PSCI a = PSCI { runPSCI :: InputT (StateT PSCiState IO) a } deriving (Functor, Applicative, Monad)
284326
285327psciIO :: IO a -> PSCI a
286−psciIO io = PSCI (lift (lift io))
328+psciIO io = PSCI . lift $ lift io
287329
288−newtype Make a = Make { unMake :: ErrorT String IO a } deriving (Functor, Applicative, Monad, MonadError String)
330+newtype Make a = Make { unMake :: ReaderT (P.Options P.Make) (ExceptT String IO) a }
331+ deriving (Functor, Applicative, Monad, MonadError String, MonadReader (P.Options P.Make))
289332
290333runMake :: Make a -> IO (Either String a)
291−runMake = runErrorT . unMake
334+runMake = runExceptT . flip runReaderT options . unMake
292335
293336makeIO :: IO a -> Make a
294−makeIO = Make . ErrorT . fmap (either (Left . show) Right) . tryIOError
337+makeIO = Make . lift . ExceptT . fmap (either (Left . show) Right) . tryIOError
295338
296339instance P.MonadMake Make where
297340 getTimestamp path = makeIO $ do
298341 exists <- doesFileExist path
299− if exists
300− then Just <$> getModificationTime path
301− else return Nothing
302− readTextFile path = makeIO $ U.readFile path
342+ traverse (const $ getModificationTime path) $ guard exists
343+ readTextFile path = makeIO $ readFile path
303344 writeTextFile path text = makeIO $ do
304345 mkdirp path
305− U.writeFile path text
306− liftError = either throwError return
307− progress s = unless (s == "Compiling $PSCI") $ makeIO . U.putStrLn $ s
346+ writeFile path text
347+ progress s = unless (s == "Compiling $PSCI") $ makeIO . putStrLn $ s
308348
309349mkdirp :: FilePath -> IO ()
310350mkdirp = createDirectoryIfMissing True . takeDirectory
@@ -319,13 +359,13 @@ createTemporaryModule exec PSCiState{psciImportedModuleNames = imports, psciLetB
319359 importDecl m = P.ImportDeclaration m P.Unqualified Nothing
320360 traceModule = P.ModuleName [P.ProperName "Debug", P.ProperName "Trace"]
321361 trace = P.Var (P.Qualified (Just traceModule) (P.Ident "print"))
322− itValue = foldl (\x f -> f x) val lets
323362 mainValue = P.App trace (P.Var (P.Qualified Nothing (P.Ident "it")))
324− itDecl = P.ValueDeclaration (P.Ident "it") P.Value [] $ Right itValue
363+ itDecl = P.ValueDeclaration (P.Ident "it") P.Value [] $ Right val
325364 mainDecl = P.ValueDeclaration (P.Ident "main") P.Value [] $ Right mainValue
326365 decls = if exec then [itDecl, mainDecl] else [itDecl]
327366 in
328− P.Module moduleName ((importDecl `map` imports) ++ decls) Nothing
367+ P.Module moduleName ((importDecl `map` imports) ++ lets ++ decls) Nothing
368+
329369
330370-- |
331371-- Makes a volatile module to hold a non-qualified type synonym for a fully-qualified data type declaration.
@@ -363,8 +403,8 @@ handleDeclaration :: P.Expr -> PSCI ()
363403handleDeclaration val = do
364404 st <- PSCI $ lift get
365405 let m = createTemporaryModule True st val
366− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
367406 let nodeArgs = psciNodeFlags st ++ [indexFile]
407+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
368408 case e of
369409 Left err -> PSCI $ outputStrLn err
370410 Right _ -> do
@@ -380,12 +420,12 @@ handleDeclaration val = do
380420-- Takes a let declaration and updates the environment, then run a make. If the declaration fails,
381421-- restore the pre-let environment.
382422--
383−handleLet :: (P.Expr -> P.Expr) -> PSCI ()
384−handleLet l = do
423+handleLet :: [P.Declaration] -> PSCI ()
424+handleLet ds = do
385425 st <- PSCI $ lift get
386− let st' = updateLets l st
426+ let st' = updateLets ds st
387427 let m = createTemporaryModule False st' (P.ObjectLiteral [])
388− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st' ++ [(Left P.RebuildAlways, m)]) []
428+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st' ++ [(Left P.RebuildAlways, m)]) []
389429 case e of
390430 Left err -> PSCI $ outputStrLn err
391431 Right _ -> PSCI $ lift (put st')
@@ -418,7 +458,7 @@ handleImport :: P.ModuleName -> PSCI ()
418458handleImport moduleName = do
419459 st <- updateImports moduleName <$> PSCI (lift get)
420460 let m = createTemporaryModuleForImports st
421− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
461+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
422462 case e of
423463 Left err -> PSCI $ outputStrLn err
424464 Right _ -> do
@@ -432,7 +472,7 @@ handleTypeOf :: P.Expr -> PSCI ()
432472handleTypeOf val = do
433473 st <- PSCI $ lift get
434474 let m = createTemporaryModule False st val
435− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
475+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
436476 case e of
437477 Left err -> PSCI $ outputStrLn err
438478 Right env' ->
@@ -466,7 +506,7 @@ handleBrowse :: P.ModuleName -> PSCI ()
466506handleBrowse moduleName = do
467507 st <- PSCI $ lift get
468508 let loadedModules = psciLoadedModules st
469− env <- psciIO . runMake $ P.make modulesDir options loadedModules []
509+ env <- psciIO . runMake $ P.make modulesDir loadedModules []
470510 case env of
471511 Left err -> PSCI $ outputStrLn err
472512 Right env' ->
@@ -482,7 +522,7 @@ handleKindOf typ = do
482522 st <- PSCI $ lift get
483523 let m = createTemporaryModuleForKind st typ
484524 mName = P.ModuleName [P.ProperName "$PSCI"]
485− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
525+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
486526 case e of
487527 Left err -> PSCI $ outputStrLn err
488528 Right env' ->
@@ -533,10 +573,12 @@ handleCommand (LoadFile filePath) = do
533573 PSCI . outputStrLn $ "Couldn't locate: " ++ filePath
534574handleCommand Reset = do
535575 files <- psciImportedFilenames <$> PSCI (lift get)
536− modulesOrFirstError <- psciIO $ loadAllModules files
537− case modulesOrFirstError of
538− Left err -> psciIO $ print err >> exitFailure
539− Right modules -> PSCI . lift $ put (PSCiState files defaultImports modules [] [])
576+ PSCI . lift . modify $ \st -> st
577+ { psciImportedFilenames = files
578+ , psciImportedModuleNames = defaultImports
579+ , psciLetBindings = []
580+ }
581+ loadAllImportedModules
540582handleCommand (TypeOf val) = handleTypeOf val
541583handleCommand (KindOf typ) = handleKindOf typ
542584handleCommand (Browse moduleName) = handleBrowse moduleName
@@ -550,9 +592,9 @@ loadUserConfig = do
550592 exists <- doesFileExist configFile
551593 if exists
552594 then do
553− ls <- lines <$> U.readFile configFile
595+ ls <- lines <$> readFile configFile
554596 case mapM parseCommand ls of
555− Left err -> U.print err >> exitFailure
597+ Left err -> print err >> exitFailure
556598 Right cs -> return $ Just cs
557599 else
558600 return Nothing
@@ -561,32 +603,33 @@ loadUserConfig = do
561603-- The PSCI main loop.
562604--
563605loop :: PSCiOptions -> IO ()
564−loop (PSCiOptions singleLineMode nflags files) = do
606+loop PSCiOptions{..} = do
565607 config <- loadUserConfig
566− modulesOrFirstError <- loadAllModules files
608+ modulesOrFirstError <- loadAllModules psciInputFile
567609 case modulesOrFirstError of
568610 Left err -> print err >> exitFailure
569611 Right modules -> do
570612 historyFilename <- getHistoryFilename
571613 let settings = defaultSettings { historyFile = Just historyFilename }
572− flip evalStateT (PSCiState files defaultImports modules [] nflags) . runInputT (setComplete completion settings) $ do
614+ flip evalStateT (PSCiState psciInputFile defaultImports modules [] psciInputNodeFlags) . runInputT (setComplete completion settings) $ do
573615 outputStrLn prologueMessage
574616 traverse_ (mapM_ (runPSCI . handleCommand)) config
575617 go
576618 where
577619 go :: InputT (StateT PSCiState IO) ()
578620 go = do
579− c <- getCommand singleLineMode
621+ c <- getCommand (not psciMultiLineMode)
580622 case c of
581623 Left err -> outputStrLn err >> go
582624 Right Nothing -> go
583625 Right (Just Quit) -> outputStrLn quitMessage
584− Right (Just c') -> runPSCI (handleCommand c') >> go
626+ Right (Just c') -> runPSCI (loadAllImportedModules >> handleCommand c') >> go
585627
586−singleLineFlag :: Parser Bool
587−singleLineFlag = switch $
588− long "single-line-mode"
589− <> Opts.help "Run in single-line mode"
628+multiLineMode :: Parser Bool
629+multiLineMode = switch $
630+ long "multi-line-mode"
631+ <> short 'm'
632+ <> Opts.help "Run in multi-line mode (use ^D to terminate commands)"
590633
591634inputFile :: Parser FilePath
592635inputFile = strArgument $
@@ -602,9 +645,9 @@ nodeFlagsFlag = option parser $
602645 parser = words <$> str
603646
604647psciOptions :: Parser PSCiOptions
605−psciOptions = PSCiOptions <$> singleLineFlag
606− <*> nodeFlagsFlag
648+psciOptions = PSCiOptions <$> multiLineMode
607649 <*> many inputFile
650+ <*> nodeFlagsFlag
608651
609652main :: IO ()
610653main = execParser opts >>= loop
psci/Parser.hs+5−5
@@ -34,8 +34,8 @@ import qualified Language.PureScript.Parser.Common as C (mark, same)
3434-- Parses PSCI metacommands or expressions input from the user.
3535--
3636parseCommand :: String -> Either String Command
37−parseCommand cmdString =
38− case splitCommand cmdString of
37+parseCommand cmdString =
38+ case splitCommand cmdString of
3939 Just ('?', _) -> return Help
4040 Just ('q', _) -> return Quit
4141 Just ('r', _) -> return Reset
@@ -52,7 +52,7 @@ parseCommand cmdString =
5252 parseRest p s = either (Left . show) Right $ do
5353 ts <- P.lex "" s
5454 P.runTokenParser "" (p <* eof) ts
55−
55+
5656 trimEnd :: String -> String
5757 trimEnd = reverse . dropWhile isSpace . reverse
5858
@@ -68,7 +68,7 @@ parseCommand cmdString =
6868 --
6969 psciExpression :: P.TokenParser Command
7070 psciExpression = Expression <$> P.parseValue
71−
71+
7272 -- |
7373 -- PSCI version of @let@.
7474 -- This is essentially let from do-notation.
@@ -76,7 +76,7 @@ parseCommand cmdString =
7676 -- we actually want the normal @let@.
7777 --
7878 psciLet :: P.TokenParser Command
79− psciLet = Let <$> (P.Let <$> (P.reserved "let" *> P.indented *> manyDecls))
79+ psciLet = Let <$> (P.reserved "let" *> P.indented *> manyDecls)
8080 where
8181 manyDecls :: P.TokenParser [P.Declaration]
8282 manyDecls = C.mark (many1 (C.same *> P.parseDeclaration))
purescript.cabal+20−17
@@ -1,5 +1,5 @@
11name: purescript
2−version: 0.6.2
2+version: 0.6.8
33cabal-version: >=1.8
44build-type: Simple
55license: MIT
@@ -31,10 +31,9 @@ library
3131 filepath -any,
3232 mtl >= 2.1.0 && < 2.3.0,
3333 parsec -any,
34− transformers >= 0.3 && < 0.5,
35− utf8-string -any,
34+ transformers >= 0.4.0 && < 0.5,
35+ utf8-string >= 1 && < 2,
3636 pattern-arrows >= 0.0.2 && < 0.1,
37− monad-unify >= 0.2.2 && < 0.3,
3837 file-embed >= 0.0.7 && < 0.0.8,
3938 time -any
4039 exposed-modules: Language.PureScript
@@ -66,6 +65,7 @@ library
6665 Language.PureScript.CoreFn.Meta
6766 Language.PureScript.CoreFn.Module
6867 Language.PureScript.CoreFn.Traversals
68+ Language.PureScript.Comments
6969 Language.PureScript.DeadCodeElimination
7070 Language.PureScript.Environment
7171 Language.PureScript.Errors
@@ -92,6 +92,7 @@ library
9292 Language.PureScript.Sugar.CaseDeclarations
9393 Language.PureScript.Sugar.DoNotation
9494 Language.PureScript.Sugar.Names
95+ Language.PureScript.Sugar.ObjectWildcards
9596 Language.PureScript.Sugar.Operators
9697 Language.PureScript.Sugar.TypeClasses
9798 Language.PureScript.Sugar.TypeDeclarations
@@ -109,67 +110,69 @@ library
109110 Language.PureScript.TypeChecker.Unify
110111 Language.PureScript.TypeClassDictionaries
111112 Language.PureScript.Types
113+
114+ Control.Monad.Unify
112115 exposed: True
113116 buildable: True
114117 hs-source-dirs: src
115118 other-modules: Paths_purescript
116− ghc-options: -Wall -fno-warn-warnings-deprecations -O2
119+ ghc-options: -Wall -O2
117120
118121executable psc
119122 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
120123 mtl -any, optparse-applicative >= 0.10.0, parsec -any, purescript -any,
121− transformers -any, utf8-string -any
124+ transformers -any
122125 main-is: Main.hs
123126 buildable: True
124127 hs-source-dirs: psc
125128 other-modules:
126− ghc-options: -Wall -fno-warn-warnings-deprecations -O2 -fno-warn-unused-do-bind
129+ ghc-options: -Wall -O2 -fno-warn-unused-do-bind
127130
128131executable psc-make
129132 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
130133 mtl -any, optparse-applicative >= 0.10.0, parsec -any, purescript -any,
131− transformers -any, utf8-string -any
134+ transformers -any
132135 main-is: Main.hs
133136 buildable: True
134137 hs-source-dirs: psc-make
135138 other-modules:
136− ghc-options: -Wall -fno-warn-warnings-deprecations -O2 -fno-warn-unused-do-bind
139+ ghc-options: -Wall -O2 -fno-warn-unused-do-bind
137140
138141executable psci
139142 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
140143 mtl -any, optparse-applicative >= 0.10.0, parsec -any,
141144 haskeline >= 0.7.0.0, purescript -any, transformers -any,
142− utf8-string -any, process -any
145+ process -any
143146
144147 main-is: Main.hs
145148 buildable: True
146149 hs-source-dirs: psci
147150 other-modules: Commands
148151 Parser
149− ghc-options: -Wall -fno-warn-warnings-deprecations -O2
152+ ghc-options: -Wall -O2
150153
151154executable psc-docs
152− build-depends: base >=4 && <5, purescript -any, utf8-string -any,
155+ build-depends: base >=4 && <5, purescript -any,
153156 optparse-applicative >= 0.10.0, process -any, mtl -any
154157 main-is: Main.hs
155158 buildable: True
156159 hs-source-dirs: psc-docs
157160 other-modules:
158− ghc-options: -Wall -fno-warn-warnings-deprecations -O2
161+ ghc-options: -Wall -O2
159162
160−executable hierarchy
161− build-depends: base >=4 && <5, purescript -any, utf8-string -any, optparse-applicative >= 0.10.0,
163+executable psc-hierarchy
164+ build-depends: base >=4 && <5, purescript -any, optparse-applicative >= 0.10.0,
162165 process -any, mtl -any, parsec -any, filepath -any, directory -any
163166 main-is: Main.hs
164167 buildable: True
165168 hs-source-dirs: hierarchy
166169 other-modules:
167− ghc-options: -Wall -fno-warn-warnings-deprecations -O2
170+ ghc-options: -Wall -O2
168171
169172test-suite tests
170173 build-depends: base >=4 && <5, containers -any, directory -any,
171174 filepath -any, mtl -any, parsec -any, purescript -any,
172− transformers -any, utf8-string -any, process -any
175+ transformers -any, process -any
173176 type: exitcode-stdio-1.0
174177 main-is: Main.hs
175178 buildable: True
src/Control/Monad/Unify.hsnew file+155
@@ -0,0 +1,155 @@
1+-----------------------------------------------------------------------------
2+--
3+-- Module : Control.Monad.Unify
4+-- Copyright : (c) Phil Freeman 2013
5+-- License : MIT
6+--
7+-- Maintainer : Phil Freeman <paf31@cantab.net>
8+-- Stability : experimental
9+-- Portability :
10+--
11+-- |
12+--
13+--
14+-----------------------------------------------------------------------------
15+
16+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
17+{-# LANGUAGE FlexibleInstances #-}
18+{-# LANGUAGE FlexibleContexts #-}
19+{-# LANGUAGE DeriveDataTypeable #-}
20+{-# LANGUAGE MultiParamTypeClasses #-}
21+{-# LANGUAGE FunctionalDependencies #-}
22+{-# LANGUAGE UndecidableInstances #-}
23+{-# LANGUAGE OverloadedStrings #-}
24+
25+module Control.Monad.Unify where
26+
27+import Data.String (IsString)
28+import Data.Monoid
29+
30+import Control.Applicative
31+import Control.Monad.State
32+import Control.Monad.Error.Class
33+
34+import Data.HashMap.Strict as M
35+
36+-- |
37+-- Untyped unification variables
38+--
39+type Unknown = Int
40+
41+-- |
42+-- A type which can contain unification variables
43+--
44+class Partial t where
45+ unknown :: Unknown -> t
46+ isUnknown :: t -> Maybe Unknown
47+ unknowns :: t -> [Unknown]
48+ ($?) :: Substitution t -> t -> t
49+
50+-- |
51+-- Identifies types which support unification
52+--
53+class (Partial t) => Unifiable m t | t -> m where
54+ (=?=) :: t -> t -> UnifyT t m ()
55+
56+-- |
57+-- A substitution maintains a mapping from unification variables to their values
58+--
59+data Substitution t = Substitution { runSubstitution :: M.HashMap Int t }
60+
61+instance (Partial t) => Monoid (Substitution t) where
62+ mempty = Substitution M.empty
63+ s1 `mappend` s2 = Substitution $
64+ M.map (s2 $?) (runSubstitution s1) `M.union`
65+ M.map (s1 $?) (runSubstitution s2)
66+
67+-- |
68+-- State required for type checking
69+--
70+data UnifyState t = UnifyState {
71+ -- |
72+ -- The next fresh unification variable
73+ --
74+ unifyNextVar :: Int
75+ -- |
76+ -- The current substitution
77+ --
78+ , unifyCurrentSubstitution :: Substitution t
79+ }
80+
81+-- |
82+-- An empty @UnifyState@
83+--
84+defaultUnifyState :: (Partial t) => UnifyState t
85+defaultUnifyState = UnifyState 0 mempty
86+
87+-- |
88+-- The type checking monad, which provides the state of the type checker, and error reporting capabilities
89+--
90+newtype UnifyT t m a = UnifyT { unUnify :: (StateT (UnifyState t) m) a }
91+ deriving (Functor, Monad, Applicative, Alternative, MonadPlus)
92+
93+instance (MonadState s m) => MonadState s (UnifyT t m) where
94+ get = UnifyT . lift $ get
95+ put = UnifyT . lift . put
96+
97+instance (MonadError e m) => MonadError e (UnifyT t m) where
98+ throwError = UnifyT . throwError
99+ catchError e f = UnifyT $ catchError (unUnify e) (unUnify . f)
100+
101+-- |
102+-- Run a computation in the Unify monad, failing with an error, or succeeding with a return value and the new next unification variable
103+--
104+runUnify :: UnifyState t -> UnifyT t m a -> m (a, UnifyState t)
105+runUnify s = flip runStateT s . unUnify
106+
107+-- |
108+-- Substitute a single unification variable
109+--
110+substituteOne :: (Partial t) => Unknown -> t -> Substitution t
111+substituteOne u t = Substitution $ M.singleton u t
112+
113+-- |
114+-- Replace a unification variable with the specified value in the current substitution
115+--
116+(=:=) :: (IsString e, Monad m, MonadError e m, Unifiable m t) => Unknown -> t -> UnifyT t m ()
117+(=:=) u t' = do
118+ st <- UnifyT get
119+ let sub = unifyCurrentSubstitution st
120+ let t = sub $? t'
121+ occursCheck u t
122+ let current = sub $? unknown u
123+ case isUnknown current of
124+ Just u1 | u1 == u -> return ()
125+ _ -> current =?= t
126+ UnifyT $ modify $ \s -> s { unifyCurrentSubstitution = substituteOne u t <> unifyCurrentSubstitution s }
127+
128+-- |
129+-- Perform the occurs check, to make sure a unification variable does not occur inside a value
130+--
131+occursCheck :: (IsString e, Monad m, MonadError e m, Partial t) => Unknown -> t -> UnifyT t m ()
132+occursCheck u t =
133+ case isUnknown t of
134+ Nothing -> when (u `elem` unknowns t) $ UnifyT . lift . throwError $ "Occurs check fails"
135+ _ -> return ()
136+
137+-- |
138+-- Generate a fresh untyped unification variable
139+--
140+fresh' :: (Monad m) => UnifyT t m Unknown
141+fresh' = do
142+ st <- UnifyT get
143+ UnifyT $ modify $ \s -> s { unifyNextVar = succ (unifyNextVar s) }
144+ return $ unifyNextVar st
145+
146+-- |
147+-- Generate a fresh unification variable at a specific type
148+--
149+fresh :: (Monad m, Partial t) => UnifyT t m t
150+fresh = do
151+ u <- fresh'
152+ return $ unknown u
153+
154+
155+
src/Language/PureScript.hs+43−37
@@ -13,7 +13,7 @@
1313--
1414-----------------------------------------------------------------------------
1515
16−{-# LANGUAGE DataKinds, QuasiQuotes, TemplateHaskell #-}
16+{-# LANGUAGE DataKinds, QuasiQuotes, TemplateHaskell, FlexibleContexts #-}
1717
1818module Language.PureScript (module P, compile, compile', RebuildPolicy(..), MonadMake(..), make, prelude) where
1919
@@ -22,17 +22,20 @@ import Data.Function (on)
2222import Data.List (sortBy, groupBy, intercalate)
2323import Data.Maybe (fromMaybe)
2424import Data.Time.Clock
25+import qualified Data.Traversable as T (traverse)
2526import qualified Data.ByteString.UTF8 as BU
2627import qualified Data.Map as M
2728import qualified Data.Set as S
2829
2930import Control.Applicative
3031import Control.Arrow ((&&&))
31−import Control.Monad.Error
32+import Control.Monad.Except
33+import Control.Monad.Reader
3234
3335import System.FilePath ((</>))
3436
3537import Language.PureScript.AST as P
38+import Language.PureScript.Comments as P
3639import Language.PureScript.CodeGen as P
3740import Language.PureScript.DeadCodeElimination as P
3841import Language.PureScript.Environment as P
@@ -70,42 +73,47 @@ import qualified Language.PureScript.Constants as C
7073--
7174-- * Pretty-print the generated Javascript
7275--
73−compile :: Options Compile -> [Module] -> [String] -> Either String (String, String, Environment)
76+compile :: (Functor m, Applicative m, MonadError String m, MonadReader (Options Compile) m)
77+ => [Module] -> [String] -> m (String, String, Environment)
7478compile = compile' initEnvironment
7579
76−compile' :: Environment -> Options Compile -> [Module] -> [String] -> Either String (String, String, Environment)
77−compile' env opts ms prefix = do
78− (sorted, _) <- sortModules $ map importPrim $ if optionsNoPrelude opts then ms else map importPrelude ms
80+compile' :: (Functor m, Applicative m, MonadError String m, MonadReader (Options Compile) m)
81+ => Environment -> [Module] -> [String] -> m (String, String, Environment)
82+compile' env ms prefix = do
83+ noPrelude <- asks optionsNoPrelude
84+ additional <- asks optionsAdditional
85+ mainModuleIdent <- asks (fmap moduleNameFromString . optionsMain)
86+ (sorted, _) <- sortModules $ map importPrim $ if noPrelude then ms else map importPrelude ms
7987 (desugared, nextVar) <- stringifyErrorStack True $ runSupplyT 0 $ desugar sorted
80− (elaborated, env') <- runCheck' opts env $ forM desugared $ typeCheckModule mainModuleIdent
88+ (elaborated, env') <- runCheck' env $ forM desugared $ typeCheckModule mainModuleIdent
8189 regrouped <- stringifyErrorStack True $ createBindingGroupsModule . collapseBindingGroupsModule $ elaborated
8290 let corefn = map (CoreFn.moduleToCoreFn env') regrouped
83− let entryPoints = moduleNameFromString `map` entryPointModules (optionsAdditional opts)
91+ let entryPoints = moduleNameFromString `map` entryPointModules additional
8492 let elim = if null entryPoints then corefn else eliminateDeadCode entryPoints corefn
8593 let renamed = renameInModules elim
86− let codeGenModuleNames = moduleNameFromString `map` codeGenModules (optionsAdditional opts)
94+ let codeGenModuleNames = moduleNameFromString `map` codeGenModules additional
8795 let modulesToCodeGen = if null codeGenModuleNames then renamed else filter (\(CoreFn.Module mn _ _ _ _) -> mn `elem` codeGenModuleNames) renamed
88− let js = evalSupply nextVar $ concat <$> mapM (moduleToJs opts) modulesToCodeGen
96+ js <- concat <$> (evalSupplyT nextVar $ T.traverse moduleToJs modulesToCodeGen)
8997 let exts = intercalate "\n" . map (`moduleToPs` env') $ regrouped
90− js' <- generateMain env' opts js
98+ js' <- generateMain env' js
9199 let pjs = unlines $ map ("// " ++) prefix ++ [prettyPrintJS js']
92100 return (pjs, exts, env')
93− where
94− mainModuleIdent = moduleNameFromString <$> optionsMain opts
95101
96−generateMain :: Environment -> Options Compile -> [JS] -> Either String [JS]
97−generateMain env opts js =
98− case moduleNameFromString <$> optionsMain opts of
102+generateMain :: (MonadError String m, MonadReader (Options Compile) m) => Environment -> [JS] -> m [JS]
103+generateMain env js = do
104+ main <- asks optionsMain
105+ additional <- asks optionsAdditional
106+ case moduleNameFromString <$> main of
99107 Just mmi -> do
100108 when ((mmi, Ident C.main) `M.notMember` names env) $
101− Left $ show mmi ++ "." ++ C.main ++ " is undefined"
102− return $ js ++ [JSApp (JSAccessor C.main (JSAccessor (moduleNameToJs mmi) (JSVar (browserNamespace (optionsAdditional opts))))) []]
109+ throwError $ show mmi ++ "." ++ C.main ++ " is undefined"
110+ return $ js ++ [JSApp (JSAccessor C.main (JSAccessor (moduleNameToJs mmi) (JSVar (browserNamespace additional)))) []]
103111 _ -> return js
104112
105113-- |
106114-- A type class which collects the IO actions we need to be able to run in "make" mode
107115--
108−class MonadMake m where
116+class (MonadReader (P.Options P.Make) m, MonadError String m) => MonadMake m where
109117 -- |
110118 -- Get a file timestamp
111119 --
@@ -121,11 +129,6 @@ class MonadMake m where
121129 --
122130 writeTextFile :: FilePath -> String -> m ()
123131
124− -- |
125− -- Report an error
126− --
127− liftError :: Either String a -> m a
128−
129132 -- |
130133 -- Respond to a progress update
131134 --
@@ -151,11 +154,13 @@ traverseEither f (Right y) = Right <$> f y
151154-- If timestamps have not changed, the externs file can be used to provide the module's types without
152155-- having to typecheck the module again.
153156--
154−make :: (Functor m, Applicative m, Monad m, MonadMake m) => FilePath -> Options Make -> [(Either RebuildPolicy FilePath, Module)] -> [String] -> m Environment
155−make outputDir opts ms prefix = do
157+make :: (Functor m, Applicative m, Monad m, MonadMake m)
158+ => FilePath -> [(Either RebuildPolicy FilePath, Module)] -> [String] -> m Environment
159+make outputDir ms prefix = do
160+ noPrelude <- asks optionsNoPrelude
156161 let filePathMap = M.fromList (map (\(fp, Module mn _ _) -> (mn, fp)) ms)
157162
158− (sorted, graph) <- liftError $ sortModules $ map importPrim $ if optionsNoPrelude opts then map snd ms else map (importPrelude . snd) ms
163+ (sorted, graph) <- sortModules $ map importPrim $ if noPrelude then map snd ms else map (importPrelude . snd) ms
159164
160165 toRebuild <- foldM (\s (Module moduleName' _ _) -> do
161166 let filePath = runModuleName moduleName'
@@ -175,15 +180,16 @@ make outputDir opts ms prefix = do
175180
176181 marked <- rebuildIfNecessary (reverseDependencies graph) toRebuild sorted
177182
178− (desugared, nextVar) <- liftError $ stringifyErrorStack True $ runSupplyT 0 $ zip (map fst marked) <$> desugar (map snd marked)
183+ (desugared, nextVar) <- stringifyErrorStack True $ runSupplyT 0 $ zip (map fst marked) <$> desugar (map snd marked)
179184
180− evalSupplyT nextVar (go initEnvironment desugared)
185+ evalSupplyT nextVar $ go initEnvironment desugared
181186
182187 where
183− go :: (Functor m, Applicative m, Monad m, MonadMake m) => Environment -> [(Bool, Module)] -> SupplyT m Environment
188+ go :: (Functor m, Applicative m, Monad m, MonadMake m)
189+ => Environment -> [(Bool, Module)] -> SupplyT m Environment
184190 go env [] = return env
185191 go env ((False, m) : ms') = do
186− (_, env') <- lift . liftError . runCheck' opts env $ typeCheckModule Nothing m
192+ (_, env') <- lift . runCheck' env $ typeCheckModule Nothing m
187193
188194 go env' ms'
189195 go env ((True, m@(Module moduleName' _ exps)) : ms') = do
@@ -193,15 +199,15 @@ make outputDir opts ms prefix = do
193199
194200 lift . progress $ "Compiling " ++ runModuleName moduleName'
195201
196− (Module _ elaborated _, env') <- lift . liftError . runCheck' opts env $ typeCheckModule Nothing m
202+ (Module _ elaborated _, env') <- lift . runCheck' env $ typeCheckModule Nothing m
197203
198− regrouped <- lift . liftError . stringifyErrorStack True . createBindingGroups moduleName' . collapseBindingGroups $ elaborated
204+ regrouped <- stringifyErrorStack True . createBindingGroups moduleName' . collapseBindingGroups $ elaborated
199205
200206 let mod' = Module moduleName' regrouped exps
201207 let corefn = CoreFn.moduleToCoreFn env' mod'
202208 let [renamed] = renameInModules [corefn]
203209
204− pjs <- prettyPrintJS <$> moduleToJs opts renamed
210+ pjs <- prettyPrintJS <$> moduleToJs renamed
205211 let js = unlines $ map ("// " ++) prefix ++ [pjs]
206212 let exts = unlines $ map ("-- " ++) prefix ++ [moduleToPs mod' env']
207213
@@ -219,10 +225,10 @@ make outputDir opts ms prefix = do
219225 rebuildIfNecessary graph toRebuild (Module moduleName' _ _ : ms') = do
220226 let externsFile = outputDir </> runModuleName moduleName' </> "externs.purs"
221227 externs <- readTextFile externsFile
222− externsModules <- liftError . fmap (map snd) . either (Left . show) Right $ P.parseModulesFromFiles id [(externsFile, externs)]
228+ externsModules <- fmap (map snd) . either (throwError . show) return $ P.parseModulesFromFiles id [(externsFile, externs)]
223229 case externsModules of
224230 [m'@(Module moduleName'' _ _)] | moduleName'' == moduleName' -> (:) (False, m') <$> rebuildIfNecessary graph toRebuild ms'
225− _ -> liftError . Left $ "Externs file " ++ externsFile ++ " was invalid"
231+ _ -> throwError $ "Externs file " ++ externsFile ++ " was invalid"
226232
227233reverseDependencies :: ModuleGraph -> M.Map ModuleName [ModuleName]
228234reverseDependencies g = combine [ (dep, mn) | (mn, deps) <- g, dep <- deps ]
@@ -239,7 +245,7 @@ addDefaultImport toImport m@(Module mn decls exps) =
239245 else Module mn (ImportDeclaration toImport Unqualified Nothing : decls) exps
240246 where
241247 isExistingImport (ImportDeclaration mn' _ _) | mn' == toImport = True
242− isExistingImport (PositionedDeclaration _ d) = isExistingImport d
248+ isExistingImport (PositionedDeclaration _ _ d) = isExistingImport d
243249 isExistingImport _ = False
244250
245251importPrim :: Module -> Module
src/Language/PureScript/AST/Binders.hs+3−2
@@ -20,6 +20,7 @@ import qualified Data.Data as D
2020
2121import Language.PureScript.AST.SourcePos
2222import Language.PureScript.Names
23+import Language.PureScript.Comments
2324
2425-- |
2526-- Data type for binders
@@ -68,7 +69,7 @@ data Binder
6869 -- |
6970 -- A binder with source position information
7071 --
71− | PositionedBinder SourceSpan Binder deriving (Show, D.Data, D.Typeable)
72+ | PositionedBinder SourceSpan [Comment] Binder deriving (Show, D.Data, D.Typeable)
7273
7374-- |
7475-- Collect all names introduced in binders in an expression
@@ -82,5 +83,5 @@ binderNames = go []
8283 go ns (ArrayBinder bs) = foldl go ns bs
8384 go ns (ConsBinder b1 b2) = go (go ns b1) b2
8485 go ns (NamedBinder name b) = go (name : ns) b
85− go ns (PositionedBinder _ b) = go ns b
86+ go ns (PositionedBinder _ _ b) = go ns b
8687 go ns _ = ns
src/Language/PureScript/AST/Declarations.hs+60−21
@@ -25,6 +25,7 @@ import Language.PureScript.Types
2525import Language.PureScript.Names
2626import Language.PureScript.Kinds
2727import Language.PureScript.TypeClassDictionaries
28+import Language.PureScript.Comments
2829import Language.PureScript.CodeGen.JS.AST
2930import Language.PureScript.Environment
3031
@@ -34,27 +35,32 @@ import Language.PureScript.Environment
3435--
3536data Module = Module ModuleName [Declaration] (Maybe [DeclarationRef]) deriving (Show, D.Data, D.Typeable)
3637
38+-- | Return a module's name.
39+getModuleName :: Module -> ModuleName
40+getModuleName (Module name _ _) = name
41+
3742-- |
3843-- Test if a declaration is exported, given a module's export list.
3944--
4045isExported :: Maybe [DeclarationRef] -> Declaration -> Bool
4146isExported Nothing _ = True
4247isExported _ TypeInstanceDeclaration{} = True
43−isExported exps (PositionedDeclaration _ d) = isExported exps d
48+isExported exps (PositionedDeclaration _ _ d) = isExported exps d
4449isExported (Just exps) decl = any (matches decl) exps
4550 where
4651 matches (TypeDeclaration ident _) (ValueRef ident') = ident == ident'
52+ matches (ValueDeclaration ident _ _ _) (ValueRef ident') = ident == ident'
4753 matches (ExternDeclaration _ ident _ _) (ValueRef ident') = ident == ident'
4854 matches (DataDeclaration _ ident _ _) (TypeRef ident' _) = ident == ident'
4955 matches (ExternDataDeclaration ident _) (TypeRef ident' _) = ident == ident'
5056 matches (TypeSynonymDeclaration ident _ _) (TypeRef ident' _) = ident == ident'
5157 matches (TypeClassDeclaration ident _ _ _) (TypeClassRef ident') = ident == ident'
52− matches (PositionedDeclaration _ d) r = d `matches` r
53− matches d (PositionedDeclarationRef _ r) = d `matches` r
58+ matches (PositionedDeclaration _ _ d) r = d `matches` r
59+ matches d (PositionedDeclarationRef _ _ r) = d `matches` r
5460 matches _ _ = False
5561
5662exportedDeclarations :: Module -> [Declaration]
57−exportedDeclarations (Module _ decls exps) = filter (isExported exps) decls
63+exportedDeclarations (Module _ decls exps) = filter (isExported exps) (flattenDecls decls)
5864
5965-- |
6066-- Test if a data constructor for a given type is exported, given a module's export list.
@@ -63,7 +69,7 @@ isDctorExported :: ProperName -> Maybe [DeclarationRef] -> ProperName -> Bool
6369isDctorExported _ Nothing _ = True
6470isDctorExported ident (Just exps) ctor = test `any` exps
6571 where
66− test (PositionedDeclarationRef _ d) = test d
72+ test (PositionedDeclarationRef _ _ d) = test d
6773 test (TypeRef ident' Nothing) = ident == ident'
6874 test (TypeRef ident' (Just ctors)) = ident == ident' && ctor `elem` ctors
6975 test _ = False
@@ -75,8 +81,9 @@ exportedDctors :: Module -> ProperName -> [ProperName]
7581exportedDctors (Module _ decls exps) ident =
7682 filter (isDctorExported ident exps) dctors
7783 where
78− dctors = concatMap getDctors decls
84+ dctors = concatMap getDctors (flattenDecls decls)
7985 getDctors (DataDeclaration _ _ _ ctors) = map fst ctors
86+ getDctors (PositionedDeclaration _ _ d) = getDctors d
8087 getDctors _ = []
8188
8289-- |
@@ -102,7 +109,7 @@ data DeclarationRef
102109 -- |
103110 -- A declaration reference with source position information
104111 --
105− | PositionedDeclarationRef SourceSpan DeclarationRef
112+ | PositionedDeclarationRef SourceSpan [Comment] DeclarationRef
106113 deriving (Show, D.Data, D.Typeable)
107114
108115instance Eq DeclarationRef where
@@ -110,8 +117,8 @@ instance Eq DeclarationRef where
110117 (ValueRef name) == (ValueRef name') = name == name'
111118 (TypeClassRef name) == (TypeClassRef name') = name == name'
112119 (TypeInstanceRef name) == (TypeInstanceRef name') = name == name'
113− (PositionedDeclarationRef _ r) == r' = r == r'
114− r == (PositionedDeclarationRef _ r') = r == r'
120+ (PositionedDeclarationRef _ _ r) == r' = r == r'
121+ r == (PositionedDeclarationRef _ _ r') = r == r'
115122 _ == _ = False
116123
117124-- |
@@ -192,7 +199,7 @@ data Declaration
192199 -- |
193200 -- A declaration with source position information
194201 --
195− | PositionedDeclaration SourceSpan Declaration
202+ | PositionedDeclaration SourceSpan [Comment] Declaration
196203 deriving (Show, D.Data, D.Typeable)
197204
198205-- |
@@ -200,7 +207,7 @@ data Declaration
200207--
201208isValueDecl :: Declaration -> Bool
202209isValueDecl ValueDeclaration{} = True
203−isValueDecl (PositionedDeclaration _ d) = isValueDecl d
210+isValueDecl (PositionedDeclaration _ _ d) = isValueDecl d
204211isValueDecl _ = False
205212
206213-- |
@@ -209,7 +216,7 @@ isValueDecl _ = False
209216isDataDecl :: Declaration -> Bool
210217isDataDecl DataDeclaration{} = True
211218isDataDecl TypeSynonymDeclaration{} = True
212−isDataDecl (PositionedDeclaration _ d) = isDataDecl d
219+isDataDecl (PositionedDeclaration _ _ d) = isDataDecl d
213220isDataDecl _ = False
214221
215222-- |
@@ -217,7 +224,7 @@ isDataDecl _ = False
217224--
218225isImportDecl :: Declaration -> Bool
219226isImportDecl ImportDeclaration{} = True
220−isImportDecl (PositionedDeclaration _ d) = isImportDecl d
227+isImportDecl (PositionedDeclaration _ _ d) = isImportDecl d
221228isImportDecl _ = False
222229
223230-- |
@@ -225,7 +232,7 @@ isImportDecl _ = False
225232--
226233isExternDataDecl :: Declaration -> Bool
227234isExternDataDecl ExternDataDeclaration{} = True
228−isExternDataDecl (PositionedDeclaration _ d) = isExternDataDecl d
235+isExternDataDecl (PositionedDeclaration _ _ d) = isExternDataDecl d
229236isExternDataDecl _ = False
230237
231238-- |
@@ -233,7 +240,7 @@ isExternDataDecl _ = False
233240--
234241isExternInstanceDecl :: Declaration -> Bool
235242isExternInstanceDecl ExternInstanceDeclaration{} = True
236−isExternInstanceDecl (PositionedDeclaration _ d) = isExternInstanceDecl d
243+isExternInstanceDecl (PositionedDeclaration _ _ d) = isExternInstanceDecl d
237244isExternInstanceDecl _ = False
238245
239246-- |
@@ -241,7 +248,7 @@ isExternInstanceDecl _ = False
241248--
242249isFixityDecl :: Declaration -> Bool
243250isFixityDecl FixityDeclaration{} = True
244−isFixityDecl (PositionedDeclaration _ d) = isFixityDecl d
251+isFixityDecl (PositionedDeclaration _ _ d) = isFixityDecl d
245252isFixityDecl _ = False
246253
247254-- |
@@ -249,7 +256,7 @@ isFixityDecl _ = False
249256--
250257isExternDecl :: Declaration -> Bool
251258isExternDecl ExternDeclaration{} = True
252−isExternDecl (PositionedDeclaration _ d) = isExternDecl d
259+isExternDecl (PositionedDeclaration _ _ d) = isExternDecl d
253260isExternDecl _ = False
254261
255262-- |
@@ -258,9 +265,17 @@ isExternDecl _ = False
258265isTypeClassDeclaration :: Declaration -> Bool
259266isTypeClassDeclaration TypeClassDeclaration{} = True
260267isTypeClassDeclaration TypeInstanceDeclaration{} = True
261−isTypeClassDeclaration (PositionedDeclaration _ d) = isTypeClassDeclaration d
268+isTypeClassDeclaration (PositionedDeclaration _ _ d) = isTypeClassDeclaration d
262269isTypeClassDeclaration _ = False
263270
271+-- |
272+-- Recursively flatten data binding groups in the list of declarations
273+flattenDecls :: [Declaration] -> [Declaration]
274+flattenDecls = concatMap flattenOne
275+ where flattenOne :: Declaration -> [Declaration]
276+ flattenOne (DataBindingGroupDeclaration decls) = concatMap flattenOne decls
277+ flattenOne d = [d]
278+
264279-- |
265280-- A guard is just a boolean-valued expression that appears alongside a set of binders
266281--
@@ -290,13 +305,18 @@ data Expr
290305 -- Binary operator application. During the rebracketing phase of desugaring, this data constructor
291306 -- will be removed.
292307 --
293− | BinaryNoParens (Qualified Ident) Expr Expr
308+ | BinaryNoParens Expr Expr Expr
294309 -- |
295310 -- Explicit parentheses. During the rebracketing phase of desugaring, this data constructor
296311 -- will be removed.
297312 --
298313 | Parens Expr
299314 -- |
315+ -- Operator section. This will be removed during desugaring and replaced with a partially applied
316+ -- operator or lambda to flip the arguments.
317+ --
318+ | OperatorSection Expr (Either Expr Expr)
319+ -- |
300320 -- An array literal
301321 --
302322 | ArrayLiteral [Expr]
@@ -305,6 +325,16 @@ data Expr
305325 --
306326 | ObjectLiteral [(String, Expr)]
307327 -- |
328+ -- An object constructor (object literal with underscores). This will be removed during
329+ -- desugaring and expanded into a lambda that returns an object literal.
330+ --
331+ | ObjectConstructor [(String, Maybe Expr)]
332+ -- |
333+ -- An object property getter (e.g. `_.x`). This will be removed during
334+ -- desugaring and expanded into a lambda that reads a property from an object.
335+ --
336+ | ObjectGetter String
337+ -- |
308338 -- An record property accessor expression
309339 --
310340 | Accessor String Expr
@@ -313,6 +343,11 @@ data Expr
313343 --
314344 | ObjectUpdate Expr [(String, Expr)]
315345 -- |
346+ -- Partial record updater. This will be removed during desugaring and
347+ -- expanded into a lambda that returns an object update.
348+ --
349+ | ObjectUpdater (Maybe Expr) [(String, Maybe Expr)]
350+ -- |
316351 -- Function introduction
317352 --
318353 | Abs (Either Ident Binder) Expr
@@ -363,13 +398,17 @@ data Expr
363398 --
364399 | TypeClassDictionary Bool Constraint [TypeClassDictionaryInScope]
365400 -- |
401+ -- A typeclass dictionary accessor, the implementation is left unspecified until CoreFn desugaring.
402+ --
403+ | TypeClassDictionaryAccessor (Qualified ProperName) Ident
404+ -- |
366405 -- A placeholder for a superclass dictionary to be turned into a TypeClassDictionary during typechecking
367406 --
368407 | SuperClassDictionary (Qualified ProperName) [Type]
369408 -- |
370409 -- A value with source position information
371410 --
372− | PositionedValue SourceSpan Expr deriving (Show, D.Data, D.Typeable)
411+ | PositionedValue SourceSpan [Comment] Expr deriving (Show, D.Data, D.Typeable)
373412
374413-- |
375414-- An alternative in a case statement
@@ -404,4 +443,4 @@ data DoNotationElement
404443 -- |
405444 -- A do notation element with source position information
406445 --
407− | PositionedDoNotationElement SourceSpan DoNotationElement deriving (Show, D.Data, D.Typeable)
446+ | PositionedDoNotationElement SourceSpan [Comment] DoNotationElement deriving (Show, D.Data, D.Typeable)
src/Language/PureScript/AST/SourcePos.hs+2−2
@@ -48,6 +48,6 @@ data SourceSpan = SourceSpan
4848 --
4949 , spanEnd :: SourcePos
5050 } deriving (D.Data, D.Typeable)
51−
51+
5252instance Show SourceSpan where
53− show sp = spanName sp ++ " " ++ show (spanStart sp) ++ " - " ++ show (spanEnd sp)
53+ show sp = spanName sp ++ " " ++ show (spanStart sp) ++ " - " ++ show (spanEnd sp)
src/Language/PureScript/AST/Traversals.hs+56−32
@@ -15,10 +15,11 @@
1515module Language.PureScript.AST.Traversals where
1616
1717import Data.Monoid (Monoid(..), mconcat)
18+import Data.Maybe (mapMaybe)
1819
1920import Control.Applicative
2021import Control.Monad
21−import Control.Arrow ((***), (+++))
22+import Control.Arrow ((***), (+++), second)
2223
2324import Language.PureScript.AST.Binders
2425import Language.PureScript.AST.Declarations
@@ -37,18 +38,22 @@ everywhereOnValues f g h = (f', g', h')
3738 f' (BindingGroupDeclaration ds) = f (BindingGroupDeclaration (map (\(name, nameKind, val) -> (name, nameKind, g' val)) ds))
3839 f' (TypeClassDeclaration name args implies ds) = f (TypeClassDeclaration name args implies (map f' ds))
3940 f' (TypeInstanceDeclaration name cs className args ds) = f (TypeInstanceDeclaration name cs className args (map f' ds))
40− f' (PositionedDeclaration pos d) = f (PositionedDeclaration pos (f' d))
41+ f' (PositionedDeclaration pos com d) = f (PositionedDeclaration pos com (f' d))
4142 f' other = f other
4243
4344 g' :: Expr -> Expr
4445 g' (UnaryMinus v) = g (UnaryMinus (g' v))
45− g' (BinaryNoParens op v1 v2) = g (BinaryNoParens op (g' v1) (g' v2))
46+ g' (BinaryNoParens op v1 v2) = g (BinaryNoParens (g' op) (g' v1) (g' v2))
4647 g' (Parens v) = g (Parens (g' v))
48+ g' (OperatorSection op (Left v)) = g (OperatorSection (g' op) (Left $ g' v))
49+ g' (OperatorSection op (Right v)) = g (OperatorSection (g' op) (Right $ g' v))
4750 g' (ArrayLiteral vs) = g (ArrayLiteral (map g' vs))
4851 g' (ObjectLiteral vs) = g (ObjectLiteral (map (fmap g') vs))
52+ g' (ObjectConstructor vs) = g (ObjectConstructor (map (second (fmap g')) vs))
4953 g' (TypeClassDictionaryConstructorApp name v) = g (TypeClassDictionaryConstructorApp name (g' v))
5054 g' (Accessor prop v) = g (Accessor prop (g' v))
5155 g' (ObjectUpdate obj vs) = g (ObjectUpdate (g' obj) (map (fmap g') vs))
56+ g' (ObjectUpdater obj vs) = g (ObjectUpdater (fmap g' obj) (map (second (fmap g')) vs))
5257 g' (Abs name v) = g (Abs name (g' v))
5358 g' (App v1 v2) = g (App (g' v1) (g' v2))
5459 g' (IfThenElse v1 v2 v3) = g (IfThenElse (g' v1) (g' v2) (g' v3))
@@ -56,7 +61,7 @@ everywhereOnValues f g h = (f', g', h')
5661 g' (TypedValue check v ty) = g (TypedValue check (g' v) ty)
5762 g' (Let ds v) = g (Let (map f' ds) (g' v))
5863 g' (Do es) = g (Do (map handleDoNotationElement es))
59− g' (PositionedValue pos v) = g (PositionedValue pos (g' v))
64+ g' (PositionedValue pos com v) = g (PositionedValue pos com (g' v))
6065 g' other = g other
6166
6267 h' :: Binder -> Binder
@@ -65,7 +70,7 @@ everywhereOnValues f g h = (f', g', h')
6570 h' (ArrayBinder bs) = h (ArrayBinder (map h' bs))
6671 h' (ConsBinder b1 b2) = h (ConsBinder (h' b1) (h' b2))
6772 h' (NamedBinder name b) = h (NamedBinder name (h' b))
68− h' (PositionedBinder pos b) = h (PositionedBinder pos (h' b))
73+ h' (PositionedBinder pos com b) = h (PositionedBinder pos com (h' b))
6974 h' other = h other
7075
7176 handleCaseAlternative :: CaseAlternative -> CaseAlternative
@@ -78,8 +83,7 @@ everywhereOnValues f g h = (f', g', h')
7883 handleDoNotationElement (DoNotationValue v) = DoNotationValue (g' v)
7984 handleDoNotationElement (DoNotationBind b v) = DoNotationBind (h' b) (g' v)
8085 handleDoNotationElement (DoNotationLet ds) = DoNotationLet (map f' ds)
81− handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos (handleDoNotationElement e)
82−
86+ handleDoNotationElement (PositionedDoNotationElement pos com e) = PositionedDoNotationElement pos com (handleDoNotationElement e)
8387
8488everywhereOnValuesTopDownM :: (Functor m, Applicative m, Monad m) =>
8589 (Declaration -> m Declaration) ->
@@ -93,17 +97,21 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
9397 f' (BindingGroupDeclaration ds) = BindingGroupDeclaration <$> mapM (\(name, nameKind, val) -> (,,) name nameKind <$> (g val >>= g')) ds
9498 f' (TypeClassDeclaration name args implies ds) = TypeClassDeclaration name args implies <$> mapM (f' <=< f) ds
9599 f' (TypeInstanceDeclaration name cs className args ds) = TypeInstanceDeclaration name cs className args <$> mapM (f' <=< f) ds
96− f' (PositionedDeclaration pos d) = PositionedDeclaration pos <$> (f d >>= f')
100+ f' (PositionedDeclaration pos com d) = PositionedDeclaration pos com <$> (f d >>= f')
97101 f' other = f other
98102
99103 g' (UnaryMinus v) = UnaryMinus <$> (g v >>= g')
100− g' (BinaryNoParens op v1 v2) = BinaryNoParens op <$> (g v1 >>= g') <*> (g v2 >>= g')
104+ g' (BinaryNoParens op v1 v2) = BinaryNoParens <$> (g op >>= g') <*> (g v1 >>= g') <*> (g v2 >>= g')
101105 g' (Parens v) = Parens <$> (g v >>= g')
106+ g' (OperatorSection op (Left v)) = OperatorSection <$> (g op >>= g') <*> (Left <$> (g v >>= g'))
107+ g' (OperatorSection op (Right v)) = OperatorSection <$> (g op >>= g') <*> (Right <$> (g v >>= g'))
102108 g' (ArrayLiteral vs) = ArrayLiteral <$> mapM (g' <=< g) vs
103109 g' (ObjectLiteral vs) = ObjectLiteral <$> mapM (sndM (g' <=< g)) vs
110+ g' (ObjectConstructor vs) = ObjectConstructor <$> mapM (sndM $ maybeM (g' <=< g)) vs
104111 g' (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> (g v >>= g')
105112 g' (Accessor prop v) = Accessor prop <$> (g v >>= g')
106113 g' (ObjectUpdate obj vs) = ObjectUpdate <$> (g obj >>= g') <*> mapM (sndM (g' <=< g)) vs
114+ g' (ObjectUpdater obj vs) = ObjectUpdater <$> (maybeM g obj >>= maybeM g') <*> mapM (sndM $ maybeM (g' <=< g)) vs
107115 g' (Abs name v) = Abs name <$> (g v >>= g')
108116 g' (App v1 v2) = App <$> (g v1 >>= g') <*> (g v2 >>= g')
109117 g' (IfThenElse v1 v2 v3) = IfThenElse <$> (g v1 >>= g') <*> (g v2 >>= g') <*> (g v3 >>= g')
@@ -111,7 +119,7 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
111119 g' (TypedValue check v ty) = TypedValue check <$> (g v >>= g') <*> pure ty
112120 g' (Let ds v) = Let <$> mapM (f' <=< f) ds <*> (g v >>= g')
113121 g' (Do es) = Do <$> mapM handleDoNotationElement es
114− g' (PositionedValue pos v) = PositionedValue pos <$> (g v >>= g')
122+ g' (PositionedValue pos com v) = PositionedValue pos com <$> (g v >>= g')
115123 g' other = g other
116124
117125 h' (ConstructorBinder ctor bs) = ConstructorBinder ctor <$> mapM (h' <=< h) bs
@@ -119,7 +127,7 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
119127 h' (ArrayBinder bs) = ArrayBinder <$> mapM (h' <=< h) bs
120128 h' (ConsBinder b1 b2) = ConsBinder <$> (h b1 >>= h') <*> (h b2 >>= h')
121129 h' (NamedBinder name b) = NamedBinder name <$> (h b >>= h')
122− h' (PositionedBinder pos b) = PositionedBinder pos <$> (h b >>= h')
130+ h' (PositionedBinder pos com b) = PositionedBinder pos com <$> (h b >>= h')
123131 h' other = h other
124132
125133 handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM (h' <=< h) bs
@@ -128,7 +136,7 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
128136 handleDoNotationElement (DoNotationValue v) = DoNotationValue <$> (g' <=< g) v
129137 handleDoNotationElement (DoNotationBind b v) = DoNotationBind <$> (h' <=< h) b <*> (g' <=< g) v
130138 handleDoNotationElement (DoNotationLet ds) = DoNotationLet <$> mapM (f' <=< f) ds
131− handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos <$> handleDoNotationElement e
139+ handleDoNotationElement (PositionedDoNotationElement pos com e) = PositionedDoNotationElement pos com <$> handleDoNotationElement e
132140
133141everywhereOnValuesM :: (Functor m, Applicative m, Monad m) =>
134142 (Declaration -> m Declaration) ->
@@ -142,17 +150,21 @@ everywhereOnValuesM f g h = (f', g', h')
142150 f' (BindingGroupDeclaration ds) = (BindingGroupDeclaration <$> mapM (\(name, nameKind, val) -> (,,) name nameKind <$> g' val) ds) >>= f
143151 f' (TypeClassDeclaration name args implies ds) = (TypeClassDeclaration name args implies <$> mapM f' ds) >>= f
144152 f' (TypeInstanceDeclaration name cs className args ds) = (TypeInstanceDeclaration name cs className args <$> mapM f' ds) >>= f
145− f' (PositionedDeclaration pos d) = (PositionedDeclaration pos <$> f' d) >>= f
153+ f' (PositionedDeclaration pos com d) = (PositionedDeclaration pos com <$> f' d) >>= f
146154 f' other = f other
147155
148156 g' (UnaryMinus v) = (UnaryMinus <$> g' v) >>= g
149− g' (BinaryNoParens op v1 v2) = (BinaryNoParens op <$> g' v1 <*> g' v2) >>= g
157+ g' (BinaryNoParens op v1 v2) = (BinaryNoParens <$> g' op <*> g' v1 <*> g' v2) >>= g
150158 g' (Parens v) = (Parens <$> g' v) >>= g
159+ g' (OperatorSection op (Left v)) = (OperatorSection <$> g' op <*> (Left <$> g' v)) >>= g
160+ g' (OperatorSection op (Right v)) = (OperatorSection <$> g' op <*> (Right <$> g' v)) >>= g
151161 g' (ArrayLiteral vs) = (ArrayLiteral <$> mapM g' vs) >>= g
152162 g' (ObjectLiteral vs) = (ObjectLiteral <$> mapM (sndM g') vs) >>= g
163+ g' (ObjectConstructor vs) = (ObjectConstructor <$> mapM (sndM $ maybeM g') vs) >>= g
153164 g' (TypeClassDictionaryConstructorApp name v) = (TypeClassDictionaryConstructorApp name <$> g' v) >>= g
154165 g' (Accessor prop v) = (Accessor prop <$> g' v) >>= g
155166 g' (ObjectUpdate obj vs) = (ObjectUpdate <$> g' obj <*> mapM (sndM g') vs) >>= g
167+ g' (ObjectUpdater obj vs) = (ObjectUpdater <$> maybeM g' obj <*> mapM (sndM $ maybeM g') vs) >>= g
156168 g' (Abs name v) = (Abs name <$> g' v) >>= g
157169 g' (App v1 v2) = (App <$> g' v1 <*> g' v2) >>= g
158170 g' (IfThenElse v1 v2 v3) = (IfThenElse <$> g' v1 <*> g' v2 <*> g' v3) >>= g
@@ -160,7 +172,7 @@ everywhereOnValuesM f g h = (f', g', h')
160172 g' (TypedValue check v ty) = (TypedValue check <$> g' v <*> pure ty) >>= g
161173 g' (Let ds v) = (Let <$> mapM f' ds <*> g' v) >>= g
162174 g' (Do es) = (Do <$> mapM handleDoNotationElement es) >>= g
163− g' (PositionedValue pos v) = (PositionedValue pos <$> g' v) >>= g
175+ g' (PositionedValue pos com v) = (PositionedValue pos com <$> g' v) >>= g
164176 g' other = g other
165177
166178 h' (ConstructorBinder ctor bs) = (ConstructorBinder ctor <$> mapM h' bs) >>= h
@@ -168,7 +180,7 @@ everywhereOnValuesM f g h = (f', g', h')
168180 h' (ArrayBinder bs) = (ArrayBinder <$> mapM h' bs) >>= h
169181 h' (ConsBinder b1 b2) = (ConsBinder <$> h' b1 <*> h' b2) >>= h
170182 h' (NamedBinder name b) = (NamedBinder name <$> h' b) >>= h
171− h' (PositionedBinder pos b) = (PositionedBinder pos <$> h' b) >>= h
183+ h' (PositionedBinder pos com b) = (PositionedBinder pos com <$> h' b) >>= h
172184 h' other = h other
173185
174186 handleCaseAlternative (CaseAlternative bs val) = CaseAlternative <$> mapM h' bs
@@ -177,7 +189,7 @@ everywhereOnValuesM f g h = (f', g', h')
177189 handleDoNotationElement (DoNotationValue v) = DoNotationValue <$> g' v
178190 handleDoNotationElement (DoNotationBind b v) = DoNotationBind <$> h' b <*> g' v
179191 handleDoNotationElement (DoNotationLet ds) = DoNotationLet <$> mapM f' ds
180− handleDoNotationElement (PositionedDoNotationElement pos e) = PositionedDoNotationElement pos <$> handleDoNotationElement e
192+ handleDoNotationElement (PositionedDoNotationElement pos com e) = PositionedDoNotationElement pos com <$> handleDoNotationElement e
181193
182194everythingOnValues :: (r -> r -> r) ->
183195 (Declaration -> r) ->
@@ -194,17 +206,21 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
194206 f' d@(BindingGroupDeclaration ds) = foldl (<>) (f d) (map (\(_, _, val) -> g' val) ds)
195207 f' d@(TypeClassDeclaration _ _ _ ds) = foldl (<>) (f d) (map f' ds)
196208 f' d@(TypeInstanceDeclaration _ _ _ _ ds) = foldl (<>) (f d) (map f' ds)
197− f' d@(PositionedDeclaration _ d1) = f d <> f' d1
209+ f' d@(PositionedDeclaration _ _ d1) = f d <> f' d1
198210 f' d = f d
199211
200212 g' v@(UnaryMinus v1) = g v <> g' v1
201− g' v@(BinaryNoParens _ v1 v2) = g v <> g' v1 <> g' v2
213+ g' v@(BinaryNoParens op v1 v2) = g v <> g op <> g' v1 <> g' v2
202214 g' v@(Parens v1) = g v <> g' v1
215+ g' v@(OperatorSection op (Left v1)) = g v <> g op <> g' v1
216+ g' v@(OperatorSection op (Right v1)) = g v <> g op <> g' v1
203217 g' v@(ArrayLiteral vs) = foldl (<>) (g v) (map g' vs)
204218 g' v@(ObjectLiteral vs) = foldl (<>) (g v) (map (g' . snd) vs)
219+ g' v@(ObjectConstructor vs) = foldl (<>) (g v) (map g' (mapMaybe snd vs))
205220 g' v@(TypeClassDictionaryConstructorApp _ v1) = g v <> g' v1
206221 g' v@(Accessor _ v1) = g v <> g' v1
207222 g' v@(ObjectUpdate obj vs) = foldl (<>) (g v <> g' obj) (map (g' . snd) vs)
223+ g' v@(ObjectUpdater obj vs) = foldl (<>) (maybe (g v) (\x -> g v <> g' x) obj) (map g' (mapMaybe snd vs))
208224 g' v@(Abs _ v1) = g v <> g' v1
209225 g' v@(App v1 v2) = g v <> g' v1 <> g' v2
210226 g' v@(IfThenElse v1 v2 v3) = g v <> g' v1 <> g' v2 <> g' v3
@@ -212,7 +228,7 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
212228 g' v@(TypedValue _ v1 _) = g v <> g' v1
213229 g' v@(Let ds v1) = foldl (<>) (g v) (map f' ds) <> g' v1
214230 g' v@(Do es) = foldl (<>) (g v) (map j' es)
215− g' v@(PositionedValue _ v1) = g v <> g' v1
231+ g' v@(PositionedValue _ _ v1) = g v <> g' v1
216232 g' v = g v
217233
218234 h' b@(ConstructorBinder _ bs) = foldl (<>) (h b) (map h' bs)
@@ -220,7 +236,7 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
220236 h' b@(ArrayBinder bs) = foldl (<>) (h b) (map h' bs)
221237 h' b@(ConsBinder b1 b2) = h b <> h' b1 <> h' b2
222238 h' b@(NamedBinder _ b1) = h b <> h' b1
223− h' b@(PositionedBinder _ b1) = h b <> h' b1
239+ h' b@(PositionedBinder _ _ b1) = h b <> h' b1
224240 h' b = h b
225241
226242 i' ca@(CaseAlternative bs (Right val)) = foldl (<>) (i ca) (map h' bs) <> g' val
@@ -229,7 +245,7 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
229245 j' e@(DoNotationValue v) = j e <> g' v
230246 j' e@(DoNotationBind b v) = j e <> h' b <> g' v
231247 j' e@(DoNotationLet ds) = foldl (<>) (j e) (map f' ds)
232− j' e@(PositionedDoNotationElement _ e1) = j e <> j' e1
248+ j' e@(PositionedDoNotationElement _ _ e1) = j e <> j' e1
233249
234250everythingWithContextOnValues ::
235251 s ->
@@ -255,19 +271,23 @@ everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'
255271 f' s (BindingGroupDeclaration ds) = foldl (<>) r0 (map (\(_, _, val) -> g'' s val) ds)
256272 f' s (TypeClassDeclaration _ _ _ ds) = foldl (<>) r0 (map (f'' s) ds)
257273 f' s (TypeInstanceDeclaration _ _ _ _ ds) = foldl (<>) r0 (map (f'' s) ds)
258− f' s (PositionedDeclaration _ d1) = f'' s d1
274+ f' s (PositionedDeclaration _ _ d1) = f'' s d1
259275 f' _ _ = r0
260276
261277 g'' s v = let (s', r) = g s v in r <> g' s' v
262278
263279 g' s (UnaryMinus v1) = g'' s v1
264− g' s (BinaryNoParens _ v1 v2) = g'' s v1 <> g'' s v2
280+ g' s (BinaryNoParens op v1 v2) = g'' s op <> g'' s v1 <> g'' s v2
265281 g' s (Parens v1) = g'' s v1
282+ g' s (OperatorSection op (Left v)) = g'' s op <> g'' s v
283+ g' s (OperatorSection op (Right v)) = g'' s op <> g'' s v
266284 g' s (ArrayLiteral vs) = foldl (<>) r0 (map (g'' s) vs)
267285 g' s (ObjectLiteral vs) = foldl (<>) r0 (map (g'' s . snd) vs)
286+ g' s (ObjectConstructor vs) = foldl (<>) r0 (map (g'' s) (mapMaybe snd vs))
268287 g' s (TypeClassDictionaryConstructorApp _ v1) = g'' s v1
269288 g' s (Accessor _ v1) = g'' s v1
270289 g' s (ObjectUpdate obj vs) = foldl (<>) (g'' s obj) (map (g'' s . snd) vs)
290+ g' s (ObjectUpdater obj vs) = foldl (<>) (maybe r0 (g'' s) obj) (map (g'' s) (mapMaybe snd vs))
271291 g' s (Abs _ v1) = g'' s v1
272292 g' s (App v1 v2) = g'' s v1 <> g'' s v2
273293 g' s (IfThenElse v1 v2 v3) = g'' s v1 <> g'' s v2 <> g'' s v3
@@ -275,7 +295,7 @@ everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'
275295 g' s (TypedValue _ v1 _) = g'' s v1
276296 g' s (Let ds v1) = foldl (<>) r0 (map (f'' s) ds) <> g'' s v1
277297 g' s (Do es) = foldl (<>) r0 (map (j'' s) es)
278− g' s (PositionedValue _ v1) = g'' s v1
298+ g' s (PositionedValue _ _ v1) = g'' s v1
279299 g' _ _ = r0
280300
281301 h'' s b = let (s', r) = h s b in r <> h' s' b
@@ -285,7 +305,7 @@ everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'
285305 h' s (ArrayBinder bs) = foldl (<>) r0 (map (h'' s) bs)
286306 h' s (ConsBinder b1 b2) = h'' s b1 <> h'' s b2
287307 h' s (NamedBinder _ b1) = h'' s b1
288− h' s (PositionedBinder _ b1) = h'' s b1
308+ h' s (PositionedBinder _ _ b1) = h'' s b1
289309 h' _ _ = r0
290310
291311 i'' s ca = let (s', r) = i s ca in r <> i' s' ca
@@ -298,7 +318,7 @@ everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'
298318 j' s (DoNotationValue v) = g'' s v
299319 j' s (DoNotationBind b v) = h'' s b <> g'' s v
300320 j' s (DoNotationLet ds) = foldl (<>) r0 (map (f'' s) ds)
301− j' s (PositionedDoNotationElement _ e1) = j'' s e1
321+ j' s (PositionedDoNotationElement _ _ e1) = j'' s e1
302322
303323everywhereWithContextOnValuesM :: (Functor m, Applicative m, Monad m) =>
304324 s ->
@@ -321,19 +341,23 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
321341 f' s (BindingGroupDeclaration ds) = BindingGroupDeclaration <$> mapM (thirdM (g'' s)) ds
322342 f' s (TypeClassDeclaration name args implies ds) = TypeClassDeclaration name args implies <$> mapM (f'' s) ds
323343 f' s (TypeInstanceDeclaration name cs className args ds) = TypeInstanceDeclaration name cs className args <$> mapM (f'' s) ds
324− f' s (PositionedDeclaration pos d1) = PositionedDeclaration pos <$> f'' s d1
344+ f' s (PositionedDeclaration pos com d1) = PositionedDeclaration pos com <$> f'' s d1
325345 f' _ other = return other
326346
327347 g'' s = uncurry g' <=< g s
328348
329349 g' s (UnaryMinus v) = UnaryMinus <$> g'' s v
330− g' s (BinaryNoParens op v1 v2) = BinaryNoParens op <$> g'' s v1 <*> g'' s v2
350+ g' s (BinaryNoParens op v1 v2) = BinaryNoParens <$> g'' s op <*> g'' s v1 <*> g'' s v2
331351 g' s (Parens v) = Parens <$> g'' s v
352+ g' s (OperatorSection op (Left v)) = OperatorSection <$> g'' s op <*> (Left <$> g'' s v)
353+ g' s (OperatorSection op (Right v)) = OperatorSection <$> g'' s op <*> (Right <$> g'' s v)
332354 g' s (ArrayLiteral vs) = ArrayLiteral <$> mapM (g'' s) vs
333355 g' s (ObjectLiteral vs) = ObjectLiteral <$> mapM (sndM (g'' s)) vs
356+ g' s (ObjectConstructor vs) = ObjectConstructor <$> mapM (sndM $ maybeM (g'' s)) vs
334357 g' s (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> g'' s v
335358 g' s (Accessor prop v) = Accessor prop <$> g'' s v
336359 g' s (ObjectUpdate obj vs) = ObjectUpdate <$> g'' s obj <*> mapM (sndM (g'' s)) vs
360+ g' s (ObjectUpdater obj vs) = ObjectUpdater <$> maybeM (g'' s) obj <*> mapM (sndM $ maybeM (g'' s)) vs
337361 g' s (Abs name v) = Abs name <$> g'' s v
338362 g' s (App v1 v2) = App <$> g'' s v1 <*> g'' s v2
339363 g' s (IfThenElse v1 v2 v3) = IfThenElse <$> g'' s v1 <*> g'' s v2 <*> g'' s v3
@@ -341,7 +365,7 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
341365 g' s (TypedValue check v ty) = TypedValue check <$> g'' s v <*> pure ty
342366 g' s (Let ds v) = Let <$> mapM (f'' s) ds <*> g'' s v
343367 g' s (Do es) = Do <$> mapM (j'' s) es
344− g' s (PositionedValue pos v) = PositionedValue pos <$> g'' s v
368+ g' s (PositionedValue pos com v) = PositionedValue pos com <$> g'' s v
345369 g' _ other = return other
346370
347371 h'' s = uncurry h' <=< h s
@@ -351,7 +375,7 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
351375 h' s (ArrayBinder bs) = ArrayBinder <$> mapM (h'' s) bs
352376 h' s (ConsBinder b1 b2) = ConsBinder <$> h'' s b1 <*> h'' s b2
353377 h' s (NamedBinder name b) = NamedBinder name <$> h'' s b
354− h' s (PositionedBinder pos b) = PositionedBinder pos <$> h'' s b
378+ h' s (PositionedBinder pos com b) = PositionedBinder pos com <$> h'' s b
355379 h' _ other = return other
356380
357381 i'' s = uncurry i' <=< i s
@@ -363,7 +387,7 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
363387 j' s (DoNotationValue v) = DoNotationValue <$> g'' s v
364388 j' s (DoNotationBind b v) = DoNotationBind <$> h'' s b <*> g'' s v
365389 j' s (DoNotationLet ds) = DoNotationLet <$> mapM (f'' s) ds
366− j' s (PositionedDoNotationElement pos e1) = PositionedDoNotationElement pos <$> j'' s e1
390+ j' s (PositionedDoNotationElement pos com e1) = PositionedDoNotationElement pos com <$> j'' s e1
367391
368392accumTypes :: (Monoid r) => (Type -> r) -> (Declaration -> r, Expr -> r, Binder -> r, CaseAlternative -> r, DoNotationElement -> r)
369393accumTypes f = everythingOnValues mappend forDecls forValues (const mempty) (const mempty) (const mempty)
src/Language/PureScript/CodeGen/Externs.hs+16−4
@@ -30,6 +30,7 @@ import Language.PureScript.Names
3030import Language.PureScript.Pretty
3131import Language.PureScript.TypeClassDictionaries
3232import Language.PureScript.Types
33+import Language.PureScript.Comments
3334
3435-- |
3536-- Generate foreign imports for all declarations in a module
@@ -44,13 +45,24 @@ moduleToPs (Module moduleName ds (Just exts)) env = intercalate "\n" . execWrite
4445
4546 declToPs :: Declaration -> Writer [String] ()
4647 declToPs (ImportDeclaration mn _ _) = tell ["import " ++ show mn ++ " ()"]
47− declToPs (FixityDeclaration (Fixity assoc prec) ident) =
48− tell [ unwords [ show assoc, show prec, ident ] ]
49− declToPs (PositionedDeclaration _ d) = declToPs d
48+ declToPs (FixityDeclaration (Fixity assoc prec) op) =
49+ case find exportsOp exts of
50+ Nothing -> return ()
51+ Just _ -> tell [ unwords [ show assoc, show prec, op ] ]
52+ where
53+ exportsOp :: DeclarationRef -> Bool
54+ exportsOp (PositionedDeclarationRef _ _ r) = exportsOp r
55+ exportsOp (ValueRef ident') = ident' == Op op
56+ exportsOp _ = False
57+ declToPs (PositionedDeclaration _ com d) = mapM commentToPs com >> declToPs d
5058 declToPs _ = return ()
5159
60+ commentToPs :: Comment -> Writer [String] ()
61+ commentToPs (LineComment s) = tell ["-- " ++ s]
62+ commentToPs (BlockComment s) = tell ["{- " ++ s ++ " -}"]
63+
5264 exportToPs :: DeclarationRef -> Writer [String] ()
53− exportToPs (PositionedDeclarationRef _ r) = exportToPs r
65+ exportToPs (PositionedDeclarationRef _ _ r) = exportToPs r
5466 exportToPs (TypeRef pn dctors) = do
5567 case Qualified (Just moduleName) pn `M.lookup` types env of
5668 Nothing -> error $ show pn ++ " has no kind in exportToPs"
src/Language/PureScript/CodeGen/JS.hs+88−69
@@ -13,22 +13,22 @@
1313--
1414-----------------------------------------------------------------------------
1515
16−{-# LANGUAGE GADTs #-}
16+{-# LANGUAGE GADTs, ViewPatterns, FlexibleContexts #-}
1717
1818module Language.PureScript.CodeGen.JS (
1919 module AST,
2020 module Common,
21− bindToJs,
2221 moduleToJs
2322) where
2423
25−import Data.Function (on)
26−import Data.List ((\\), delete, sortBy)
27−import Data.Maybe (catMaybes, mapMaybe)
24+import Data.List ((\\), delete)
25+import Data.Maybe (mapMaybe)
26+import qualified Data.Traversable as T (traverse)
2827
2928import Control.Applicative
3029import Control.Arrow ((&&&))
3130import Control.Monad (foldM, replicateM, forM)
31+import Control.Monad.Reader (MonadReader, asks, lift)
3232
3333import Language.PureScript.CodeGen.JS.AST as AST
3434import Language.PureScript.CodeGen.JS.Common as Common
@@ -44,16 +44,18 @@ import qualified Language.PureScript.Constants as C
4444-- Generate code in the simplified Javascript intermediate representation for all declarations in a
4545-- module.
4646--
47−moduleToJs :: (Functor m, Applicative m, Monad m) => Options mode -> Module Ann -> SupplyT m [JS]
48−moduleToJs opts (Module name imps exps foreigns decls) = do
49− let jsImports = map (importToJs opts) . delete (ModuleName [ProperName C.prim]) . (\\ [name]) $ imps
47+moduleToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
48+ => Module Ann -> SupplyT m [JS]
49+moduleToJs (Module name imps exps foreigns decls) = do
50+ additional <- lift $ asks optionsAdditional
51+ jsImports <- lift . T.traverse importToJs . delete (ModuleName [ProperName C.prim]) . (\\ [name]) $ imps
5052 let foreigns' = mapMaybe (\(_, js, _) -> js) foreigns
5153 jsDecls <- mapM (bindToJs name) decls
52− let optimized = concatMap (map $ optimize opts) $ catMaybes jsDecls
54+ optimized <- lift $ T.traverse (T.traverse optimize) jsDecls
5355 let isModuleEmpty = null exps
54− let moduleBody = JSStringLiteral "use strict" : jsImports ++ foreigns' ++ optimized
56+ let moduleBody = JSStringLiteral "use strict" : jsImports ++ foreigns' ++ concat optimized
5557 let exps' = JSObjectLiteral $ map (runIdent &&& JSVar . identToJs) exps
56− return $ case optionsAdditional opts of
58+ return $ case additional of
5759 MakeOptions -> moduleBody ++ [JSAssignment (JSAccessor "exports" (JSVar "module")) exps']
5860 CompileOptions ns _ _ | not isModuleEmpty ->
5961 [ JSVariableIntroduction ns
@@ -66,26 +68,39 @@ moduleToJs opts (Module name imps exps foreigns decls) = do
6668-- |
6769-- Generates Javascript code for a module import.
6870--
69−importToJs :: Options mode -> ModuleName -> JS
70−importToJs opts mn =
71− JSVariableIntroduction (moduleNameToJs mn) (Just moduleBody)
72− where
73− moduleBody = case optionsAdditional opts of
74− MakeOptions -> JSApp (JSVar "require") [JSStringLiteral (runModuleName mn)]
75− CompileOptions ns _ _ -> JSAccessor (moduleNameToJs mn) (JSVar ns)
71+importToJs :: (Monad m, MonadReader (Options mode) m) => ModuleName -> m JS
72+importToJs mn = do
73+ additional <- asks optionsAdditional
74+ let moduleBody = case additional of
75+ MakeOptions -> JSApp (JSVar "require") [JSStringLiteral (runModuleName mn)]
76+ CompileOptions ns _ _ -> JSAccessor (moduleNameToJs mn) (JSVar ns)
77+ return $ JSVariableIntroduction (moduleNameToJs mn) (Just moduleBody)
7678
7779-- |
7880-- Generate code in the simplified Javascript intermediate representation for a declaration
7981--
80−bindToJs :: (Functor m, Applicative m, Monad m) => ModuleName -> Bind Ann -> SupplyT m (Maybe [JS])
81−bindToJs mp (NonRec ident val) = do
82+bindToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
83+ => ModuleName -> Bind Ann -> SupplyT m [JS]
84+bindToJs mp (NonRec ident val) = return <$> nonRecToJS mp ident val
85+bindToJs mp (Rec vals) = forM vals (uncurry (nonRecToJS mp))
86+
87+-- |
88+-- Generate code in the simplified Javascript intermediate representation for a single non-recursive
89+-- declaration.
90+--
91+-- The main purpose of this function is to handle code generation for comments.
92+--
93+nonRecToJS :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
94+ => ModuleName -> Ident -> Expr Ann -> SupplyT m JS
95+nonRecToJS m i e@(extractAnn -> (_, com, _, _)) | not (null com) = do
96+ withoutComment <- lift $ asks optionsNoComments
97+ if withoutComment
98+ then nonRecToJS m i (modifyAnn removeComments e)
99+ else JSComment com <$> nonRecToJS m i (modifyAnn removeComments e)
100+nonRecToJS mp ident val = do
82101 js <- valueToJs mp val
83− return $ Just [JSVariableIntroduction (identToJs ident) (Just js)]
84−bindToJs mp (Rec vals) = do
85− jss <- forM vals $ \(ident, val) -> do
86− js <- valueToJs mp val
87− return $ JSVariableIntroduction (identToJs ident) (Just js)
88− return $ Just jss
102+ return $ JSVariableIntroduction (identToJs ident) (Just js)
103+
89104
90105-- |
91106-- Generate code in the simplified Javascript intermediate representation for a variable based on a
@@ -110,20 +125,21 @@ accessorString prop | identNeedsEscaping prop = JSIndexer (JSStringLiteral prop)
110125-- |
111126-- Generate code in the simplified Javascript intermediate representation for a value or expression.
112127--
113−valueToJs :: (Functor m, Applicative m, Monad m) => ModuleName -> Expr Ann -> SupplyT m JS
128+valueToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
129+ => ModuleName -> Expr Ann -> SupplyT m JS
114130valueToJs m (Literal _ l) =
115131 literalToValueJS m l
116−valueToJs m (Var (_, _, Just (IsConstructor _ 0)) name) =
132+valueToJs m (Var (_, _, _, Just (IsConstructor _ [])) name) =
117133 return $ JSAccessor "value" $ qualifiedToJS m id name
118−valueToJs m (Var (_, _, Just (IsConstructor _ _)) name) =
134+valueToJs m (Var (_, _, _, Just (IsConstructor _ _)) name) =
119135 return $ JSAccessor "create" $ qualifiedToJS m id name
120136valueToJs m (Accessor _ prop val) =
121137 accessorString prop <$> valueToJs m val
122138valueToJs m (ObjectUpdate _ o ps) = do
123139 obj <- valueToJs m o
124− sts <- mapM (sndM (valueToJs m)) ps
140+ sts <- mapM (sndM $ valueToJs m) ps
125141 extendObj obj sts
126−valueToJs _ e@(Abs (_, _, Just IsTypeClassConstructor) _ val) =
142+valueToJs _ e@(Abs (_, _, _, Just IsTypeClassConstructor) _ _) =
127143 let args = unAbs e
128144 in return $ JSFunction Nothing (map identToJs args) (JSBlock $ map assign args)
129145 where
@@ -140,10 +156,10 @@ valueToJs m e@App{} = do
140156 let (f, args) = unApp e []
141157 args' <- mapM (valueToJs m) args
142158 case f of
143− Var (_, _, Just IsNewtype) _ -> return (head args')
144− Var (_, _, Just (IsConstructor _ arity)) name | arity == length args ->
159+ Var (_, _, _, Just IsNewtype) _ -> return (head args')
160+ Var (_, _, _, Just (IsConstructor _ fields)) name | length args == length fields ->
145161 return $ JSUnary JSNew $ JSApp (qualifiedToJS m id name) args'
146− Var (_, _, Just IsTypeClassConstructor) name ->
162+ Var (_, _, _, Just IsTypeClassConstructor) name ->
147163 return $ JSUnary JSNew $ JSApp (qualifiedToJS m id name) args'
148164 _ -> flip (foldl (\fn a -> JSApp fn [a])) args' <$> valueToJs m f
149165 where
@@ -156,38 +172,33 @@ valueToJs m (Case _ values binders) = do
156172 vals <- mapM (valueToJs m) values
157173 bindersToJs m binders vals
158174valueToJs m (Let _ ds val) = do
159− decls <- concat . catMaybes <$> mapM (bindToJs m) ds
175+ decls <- concat <$> mapM (bindToJs m) ds
160176 ret <- valueToJs m val
161177 return $ JSApp (JSFunction Nothing [] (JSBlock (decls ++ [JSReturn ret]))) []
162−valueToJs _ (Constructor (_, _, Just IsNewtype) _ (ProperName ctor) _) =
178+valueToJs _ (Constructor (_, _, _, Just IsNewtype) _ (ProperName ctor) _) =
163179 return $ JSVariableIntroduction ctor (Just $
164180 JSObjectLiteral [("create",
165181 JSFunction Nothing ["value"]
166182 (JSBlock [JSReturn $ JSVar "value"]))])
167−valueToJs _ (Constructor _ _ (ProperName ctor) 0) =
183+valueToJs _ (Constructor _ _ (ProperName ctor) []) =
168184 return $ iife ctor [ JSFunction (Just ctor) [] (JSBlock [])
169185 , JSAssignment (JSAccessor "value" (JSVar ctor))
170186 (JSUnary JSNew $ JSApp (JSVar ctor) []) ]
171−valueToJs _ (Constructor _ _ (ProperName ctor) arity) =
172− return $ iife ctor [ makeConstructor ctor arity
173− , JSAssignment (JSAccessor "create" (JSVar ctor)) (go ctor 0 arity [])
174− ]
175− where
176− makeConstructor :: String -> Int -> JS
177− makeConstructor ctorName n =
178− let args = [ "value" ++ show index | index <- [0..n-1] ]
179− body = [ JSAssignment (JSAccessor arg (JSVar "this")) (JSVar arg) | arg <- args ]
180− in JSFunction (Just ctorName) args (JSBlock body)
181− go :: String -> Int -> Int -> [JS] -> JS
182− go pn _ 0 values = JSUnary JSNew $ JSApp (JSVar pn) (reverse values)
183− go pn index n values =
184− JSFunction Nothing ["value" ++ show index]
185− (JSBlock [JSReturn (go pn (index + 1) (n - 1) (JSVar ("value" ++ show index) : values))])
186−
187+valueToJs _ (Constructor _ _ (ProperName ctor) fields) =
188+ let constructor =
189+ let body = [ JSAssignment (JSAccessor (identToJs f) (JSVar "this")) (var f) | f <- fields ]
190+ in JSFunction (Just ctor) (identToJs `map` fields) (JSBlock body)
191+ createFn =
192+ let body = JSUnary JSNew $ JSApp (JSVar ctor) (var `map` fields)
193+ in foldr (\f inner -> JSFunction Nothing [identToJs f] (JSBlock [JSReturn inner])) body fields
194+ in return $ iife ctor [ constructor
195+ , JSAssignment (JSAccessor "create" (JSVar ctor)) createFn
196+ ]
187197iife :: String -> [JS] -> JS
188198iife v exprs = JSApp (JSFunction Nothing [] (JSBlock $ exprs ++ [JSReturn $ JSVar v])) []
189199
190−literalToValueJS :: (Functor m, Applicative m, Monad m) => ModuleName -> Literal (Expr Ann) -> SupplyT m JS
200+literalToValueJS :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
201+ => ModuleName -> Literal (Expr Ann) -> SupplyT m JS
191202literalToValueJS _ (NumericLiteral n) = return $ JSNumericLiteral n
192203literalToValueJS _ (StringLiteral s) = return $ JSStringLiteral s
193204literalToValueJS _ (BooleanLiteral b) = return $ JSBooleanLiteral b
@@ -234,7 +245,8 @@ qualifiedToJS _ f (Qualified _ a) = JSVar $ identToJs (f a)
234245-- Generate code in the simplified Javascript intermediate representation for pattern match binders
235246-- and guards.
236247--
237−bindersToJs :: (Functor m, Applicative m, Monad m) => ModuleName -> [CaseAlternative Ann] -> [JS] -> SupplyT m JS
248+bindersToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
249+ => ModuleName -> [CaseAlternative Ann] -> [JS] -> SupplyT m JS
238250bindersToJs m binders vals = do
239251 valNames <- replicateM (length vals) freshName
240252 let assignments = zipWith JSVariableIntroduction valNames (map Just vals)
@@ -244,14 +256,16 @@ bindersToJs m binders vals = do
244256 return $ JSApp (JSFunction Nothing [] (JSBlock (assignments ++ concat jss ++ [JSThrow $ JSUnary JSNew $ JSApp (JSVar "Error") [JSStringLiteral "Failed pattern match"]])))
245257 []
246258 where
247− go :: (Functor m, Applicative m, Monad m) => [String] -> [JS] -> [Binder Ann] -> SupplyT m [JS]
259+ go :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
260+ => [String] -> [JS] -> [Binder Ann] -> SupplyT m [JS]
248261 go _ done [] = return done
249262 go (v:vs) done' (b:bs) = do
250263 done'' <- go vs done' bs
251264 binderToJs m v done'' b
252265 go _ _ _ = error "Invalid arguments to bindersToJs"
253266
254− guardsToJs :: (Functor m, Applicative m, Monad m) => Either [(Guard Ann, Expr Ann)] (Expr Ann) -> SupplyT m [JS]
267+ guardsToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
268+ => Either [(Guard Ann, Expr Ann)] (Expr Ann) -> SupplyT m [JS]
255269 guardsToJs (Left gs) = forM gs $ \(cond, val) -> do
256270 cond' <- valueToJs m cond
257271 done <- valueToJs m val
@@ -262,16 +276,17 @@ bindersToJs m binders vals = do
262276-- Generate code in the simplified Javascript intermediate representation for a pattern match
263277-- binder.
264278--
265−binderToJs :: (Functor m, Applicative m, Monad m) => ModuleName -> String -> [JS] -> Binder Ann -> SupplyT m [JS]
279+binderToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
280+ => ModuleName -> String -> [JS] -> Binder Ann -> SupplyT m [JS]
266281binderToJs _ _ done (NullBinder{}) = return done
267282binderToJs m varName done (LiteralBinder _ l) =
268283 literalToBinderJS m varName done l
269284binderToJs _ varName done (VarBinder _ ident) =
270285 return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : done)
271−binderToJs m varName done (ConstructorBinder (_, _, Just IsNewtype) _ _ [b]) =
286+binderToJs m varName done (ConstructorBinder (_, _, _, Just IsNewtype) _ _ [b]) =
272287 binderToJs m varName done b
273−binderToJs m varName done (ConstructorBinder (_, _, Just (IsConstructor ctorType _)) _ ctor bs) = do
274− js <- go 0 done bs
288+binderToJs m varName done (ConstructorBinder (_, _, _, Just (IsConstructor ctorType fields)) _ ctor bs) = do
289+ js <- go (zip fields bs) done
275290 return $ case ctorType of
276291 ProductType -> js
277292 SumType ->
@@ -279,13 +294,14 @@ binderToJs m varName done (ConstructorBinder (_, _, Just (IsConstructor ctorType
279294 (JSBlock js)
280295 Nothing]
281296 where
282− go :: (Functor m, Applicative m, Monad m) => Integer -> [JS] -> [Binder Ann] -> SupplyT m [JS]
283− go _ done' [] = return done'
284− go index done' (binder:bs') = do
297+ go :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
298+ => [(Ident, Binder Ann)] -> [JS] -> SupplyT m [JS]
299+ go [] done' = return done'
300+ go ((field, binder) : remain) done' = do
285301 argVar <- freshName
286− done'' <- go (index + 1) done' bs'
302+ done'' <- go remain done'
287303 js <- binderToJs m argVar done'' binder
288− return (JSVariableIntroduction argVar (Just (JSAccessor ("value" ++ show index) (JSVar varName))) : js)
304+ return (JSVariableIntroduction argVar (Just (JSAccessor (identToJs field) (JSVar varName))) : js)
289305binderToJs m varName done binder@(ConstructorBinder _ _ ctor _) | isCons ctor = do
290306 let (headBinders, tailBinder) = uncons [] binder
291307 numberOfHeadBinders = fromIntegral $ length headBinders
@@ -309,7 +325,8 @@ binderToJs m varName done (NamedBinder _ ident binder) = do
309325 js <- binderToJs m varName done binder
310326 return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : js)
311327
312−literalToBinderJS :: (Functor m, Applicative m, Monad m) => ModuleName -> String -> [JS] -> Literal (Binder Ann) -> SupplyT m [JS]
328+literalToBinderJS :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
329+ => ModuleName -> String -> [JS] -> Literal (Binder Ann) -> SupplyT m [JS]
313330literalToBinderJS _ varName done (NumericLiteral num) =
314331 return [JSIfElse (JSBinary EqualTo (JSVar varName) (JSNumericLiteral num)) (JSBlock done) Nothing]
315332literalToBinderJS _ varName done (StringLiteral str) =
@@ -320,7 +337,8 @@ literalToBinderJS _ varName done (BooleanLiteral False) =
320337 return [JSIfElse (JSUnary Not (JSVar varName)) (JSBlock done) Nothing]
321338literalToBinderJS m varName done (ObjectLiteral bs) = go done bs
322339 where
323− go :: (Functor m, Applicative m, Monad m) => [JS] -> [(String, Binder Ann)] -> SupplyT m [JS]
340+ go :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
341+ => [JS] -> [(String, Binder Ann)] -> SupplyT m [JS]
324342 go done' [] = return done'
325343 go done' ((prop, binder):bs') = do
326344 propVar <- freshName
@@ -331,7 +349,8 @@ literalToBinderJS m varName done (ArrayLiteral bs) = do
331349 js <- go done 0 bs
332350 return [JSIfElse (JSBinary EqualTo (JSAccessor "length" (JSVar varName)) (JSNumericLiteral (Left (fromIntegral $ length bs)))) (JSBlock js) Nothing]
333351 where
334− go :: (Functor m, Applicative m, Monad m) => [JS] -> Integer -> [Binder Ann] -> SupplyT m [JS]
352+ go :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
353+ => [JS] -> Integer -> [Binder Ann] -> SupplyT m [JS]
335354 go done' _ [] = return done'
336355 go done' index (binder:bs') = do
337356 elVar <- freshName
src/Language/PureScript/CodeGen/JS/AST.hs+10−1
@@ -19,6 +19,8 @@ module Language.PureScript.CodeGen.JS.AST where
1919
2020import Data.Data
2121
22+import Language.PureScript.Comments
23+
2224-- |
2325-- Built-in unary operators
2426--
@@ -240,7 +242,11 @@ data JS
240242 -- |
241243 -- Raw Javascript (generated when parsing fails for an inline foreign import declaration)
242244 --
243− | JSRaw String deriving (Show, Eq, Data, Typeable)
245+ | JSRaw String
246+ -- |
247+ -- Commented Javascript
248+ --
249+ | JSComment [Comment] JS deriving (Show, Eq, Data, Typeable)
244250
245251--
246252-- Traversals
@@ -271,6 +277,7 @@ everywhereOnJS f = go
271277 go (JSTypeOf js) = f (JSTypeOf (go js))
272278 go (JSLabel name js) = f (JSLabel name (go js))
273279 go (JSInstanceOf j1 j2) = f (JSInstanceOf (go j1) (go j2))
280+ go (JSComment com j) = f (JSComment com (go j))
274281 go other = f other
275282
276283everywhereOnJSTopDown :: (JS -> JS) -> JS -> JS
@@ -298,6 +305,7 @@ everywhereOnJSTopDown f = go . f
298305 go (JSTypeOf j) = JSTypeOf (go (f j))
299306 go (JSLabel name j) = JSLabel name (go (f j))
300307 go (JSInstanceOf j1 j2) = JSInstanceOf (go (f j1)) (go (f j2))
308+ go (JSComment com j) = JSComment com (go (f j))
301309 go other = f other
302310
303311everythingOnJS :: (r -> r -> r) -> (JS -> r) -> JS -> r
@@ -325,4 +333,5 @@ everythingOnJS (<>) f = go
325333 go j@(JSTypeOf j1) = f j <> go j1
326334 go j@(JSLabel _ j1) = f j <> go j1
327335 go j@(JSInstanceOf j1 j2) = f j <> go j1 <> go j2
336+ go j@(JSComment _ j1) = f j <> go j1
328337 go other = f other
src/Language/PureScript/CodeGen/JS/Common.hs+42−2
@@ -135,7 +135,47 @@ nameIsJsReserved name =
135135 , "volatile"
136136 , "while"
137137 , "with"
138− , "yield" ]
138+ , "yield" ] || properNameIsJsReserved name
139139
140140moduleNameToJs :: ModuleName -> String
141−moduleNameToJs (ModuleName pns) = intercalate "_" (runProperName `map` pns)
141+moduleNameToJs (ModuleName pns) =
142+ let name = intercalate "_" (runProperName `map` pns)
143+ in if properNameIsJsReserved name then "$$" ++ name else name
144+
145+-- |
146+-- Checks whether a proper name is reserved in Javascript.
147+--
148+properNameIsJsReserved :: String -> Bool
149+properNameIsJsReserved name =
150+ name `elem` [ "Infinity"
151+ , "NaN"
152+ , "Object"
153+ , "Function"
154+ , "Boolean"
155+ , "Error"
156+ , "EvalError"
157+ , "InternalError"
158+ , "RangeError"
159+ , "ReferenceError"
160+ , "SyntaxError"
161+ , "TypeError"
162+ , "URIError"
163+ , "Number"
164+ , "Math"
165+ , "Date"
166+ , "String"
167+ , "RegExp"
168+ , "Array"
169+ , "Int8Array"
170+ , "Uint8Array"
171+ , "Uint8ClampedArray"
172+ , "Int16Array"
173+ , "Uint16Array"
174+ , "Int32Array"
175+ , "Uint32Array"
176+ , "Float32Array"
177+ , "Float64Array"
178+ , "ArrayBuffer"
179+ , "DataView"
180+ , "JSON"
181+ , "Intl" ]
src/Language/PureScript/CodeGen/JS/Optimizer.hs+29−19
@@ -31,10 +31,14 @@
3131--
3232-----------------------------------------------------------------------------
3333
34+{-# LANGUAGE FlexibleContexts #-}
35+
3436module Language.PureScript.CodeGen.JS.Optimizer (
3537 optimize
3638) where
3739
40+import Control.Monad.Reader (MonadReader, ask, asks)
41+
3842import Language.PureScript.CodeGen.JS.AST
3943import Language.PureScript.Options
4044import qualified Language.PureScript.Constants as C
@@ -49,28 +53,34 @@ import Language.PureScript.CodeGen.JS.Optimizer.Blocks
4953-- |
5054-- Apply a series of optimizer passes to simplified Javascript code
5155--
52−optimize :: Options mode -> JS -> JS
53−optimize opts | optionsNoOptimizations opts = id
54− | otherwise = untilFixedPoint (applyAll
55− [ collapseNestedBlocks
56− , collapseNestedIfs
57− , tco opts
58− , magicDo opts
59− , removeCodeAfterReturnStatements
60− , removeUnusedArg
61− , removeUndefinedApp
62− , unThunk
63− , etaConvert
64− , evaluateIifes
65− , inlineVariables
66− , inlineOperator (C.prelude, (C.$)) $ \f x -> JSApp f [x]
67− , inlineOperator (C.prelude, (C.#)) $ \x f -> JSApp f [x]
68− , inlineOperator (C.preludeUnsafe, C.unsafeIndex) $ flip JSIndexer
69− , inlineCommonOperators ])
56+optimize :: (Monad m, MonadReader (Options mode) m) => JS -> m JS
57+optimize js = do
58+ noOpt <- asks optionsNoOptimizations
59+ if noOpt then return js else optimize' js
60+
61+optimize' :: (Monad m, MonadReader (Options mode) m) => JS -> m JS
62+optimize' js = do
63+ opts <- ask
64+ return $ untilFixedPoint (applyAll
65+ [ collapseNestedBlocks
66+ , collapseNestedIfs
67+ , tco opts
68+ , magicDo opts
69+ , removeCodeAfterReturnStatements
70+ , removeUnusedArg
71+ , removeUndefinedApp
72+ , unThunk
73+ , etaConvert
74+ , evaluateIifes
75+ , inlineVariables
76+ , inlineValues
77+ , inlineOperator (C.prelude, (C.$)) $ \f x -> JSApp f [x]
78+ , inlineOperator (C.prelude, (C.#)) $ \x f -> JSApp f [x]
79+ , inlineOperator (C.preludeUnsafe, C.unsafeIndex) $ flip JSIndexer
80+ , inlineCommonOperators ]) js
7081
7182untilFixedPoint :: (Eq a) => (a -> a) -> a -> a
7283untilFixedPoint f = go
7384 where
7485 go a = let a' = f a in
7586 if a' == a then a' else go a'
76−
src/Language/PureScript/CodeGen/JS/Optimizer/Inliner.hs+28−18
@@ -15,6 +15,7 @@
1515
1616module Language.PureScript.CodeGen.JS.Optimizer.Inliner (
1717 inlineVariables,
18+ inlineValues,
1819 inlineOperator,
1920 inlineCommonOperators,
2021 etaConvert,
@@ -79,6 +80,15 @@ inlineVariables = everywhereOnJS $ removeFromBlock go
7980 go (map (replaceIdent var js) sts)
8081 go (s:sts) = s : go sts
8182
83+inlineValues :: JS -> JS
84+inlineValues = everywhereOnJS convert
85+ where
86+ convert :: JS -> JS
87+ convert (JSApp fn [dict]) | isPreludeDict C.semiringNumber dict && isPreludeFn C.zero fn = JSNumericLiteral (Left 0)
88+ convert (JSApp fn [dict]) | isPreludeDict C.semiringNumber dict && isPreludeFn C.one fn = JSNumericLiteral (Left 1)
89+ convert (JSApp (JSApp fn [x]) [y]) | isPreludeFn (C.%) fn = JSBinary Modulus x y
90+ convert other = other
91+
8292inlineOperator :: (String, String) -> (JS -> JS -> JS) -> JS -> JS
8393inlineOperator (m, op) f = everywhereOnJS convert
8494 where
@@ -91,12 +101,11 @@ inlineOperator (m, op) f = everywhereOnJS convert
91101
92102inlineCommonOperators :: JS -> JS
93103inlineCommonOperators = applyAll $
94− [ binary C.numNumber (C.+) Add
95− , binary C.numNumber (C.-) Subtract
96− , binary C.numNumber (C.*) Multiply
97− , binary C.numNumber (C./) Divide
98− , binary C.numNumber (C.%) Modulus
99− , unary C.numNumber C.negate Negate
104+ [ binary C.semiringNumber (C.+) Add
105+ , binary C.semiringNumber (C.*) Multiply
106+ , binary C.ringNumber (C.-) Subtract
107+ , unary C.ringNumber C.negate Negate
108+ , binary C.moduloSemiringNumber (C./) Divide
100109
101110 , binary C.ordNumber (C.<) LessThan
102111 , binary C.ordNumber (C.>) GreaterThan
@@ -131,29 +140,20 @@ inlineCommonOperators = applyAll $
131140 binary dictName opString op = everywhereOnJS convert
132141 where
133142 convert :: JS -> JS
134− convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isOp fn && isOpDict dictName dict = JSBinary op x y
143+ convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isPreludeDict dictName dict && isPreludeFn opString fn = JSBinary op x y
135144 convert other = other
136− isOp (JSAccessor longForm (JSAccessor prelude (JSVar _))) = prelude == C.prelude && longForm == identToJs (Op opString)
137− isOp (JSIndexer (JSStringLiteral op') (JSVar prelude)) = prelude == C.prelude && opString == op'
138− isOp _ = False
139145 binaryFunction :: String -> String -> BinaryOperator -> JS -> JS
140146 binaryFunction dictName fnName op = everywhereOnJS convert
141147 where
142148 convert :: JS -> JS
143− convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isOp fn && isOpDict dictName dict = JSBinary op x y
149+ convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isPreludeFn fnName fn && isPreludeDict dictName dict = JSBinary op x y
144150 convert other = other
145− isOp (JSAccessor fnName' (JSVar prelude)) = prelude == C.prelude && fnName == fnName'
146− isOp _ = False
147151 unary :: String -> String -> UnaryOperator -> JS -> JS
148152 unary dictName fnName op = everywhereOnJS convert
149153 where
150154 convert :: JS -> JS
151− convert (JSApp (JSApp fn [dict]) [x]) | isOp fn && isOpDict dictName dict = JSUnary op x
155+ convert (JSApp (JSApp fn [dict]) [x]) | isPreludeFn fnName fn && isPreludeDict dictName dict = JSUnary op x
152156 convert other = other
153− isOp (JSAccessor fnName' (JSVar prelude)) = prelude == C.prelude && fnName' == fnName
154− isOp _ = False
155− isOpDict dictName (JSAccessor prop (JSVar prelude)) = prelude == C.prelude && prop == dictName
156− isOpDict _ _ = False
157157 mkFn :: Int -> JS -> JS
158158 mkFn 0 = everywhereOnJS convert
159159 where
@@ -189,3 +189,13 @@ inlineCommonOperators = applyAll $
189189 go 0 acc (JSApp runFnN [fn]) | isNFn C.runFn n runFnN && length acc == n = Just (JSApp fn acc)
190190 go m acc (JSApp lhs [arg]) = go (m - 1) (arg : acc) lhs
191191 go _ _ _ = Nothing
192+
193+isPreludeDict :: String -> JS -> Bool
194+isPreludeDict dictName (JSAccessor prop (JSVar prelude)) = prelude == C.prelude && prop == dictName
195+isPreludeDict _ _ = False
196+
197+isPreludeFn :: String -> JS -> Bool
198+isPreludeFn fnName (JSAccessor fnName' (JSVar prelude)) = prelude == C.prelude && fnName' == fnName
199+isPreludeFn fnName (JSIndexer (JSStringLiteral fnName') (JSVar prelude)) = prelude == C.prelude && fnName' == fnName
200+isPreludeFn fnName (JSAccessor longForm (JSAccessor prelude (JSVar _))) = prelude == C.prelude && longForm == identToJs (Op fnName)
201+isPreludeFn _ _ = False
src/Language/PureScript/Comments.hsnew file+25
@@ -0,0 +1,25 @@
1+-----------------------------------------------------------------------------
2+--
3+-- Module : Language.PureScript.Parser.Comments
4+-- Copyright : (c) Phil Freeman 2015
5+-- License : MIT
6+--
7+-- Maintainer : Phil Freeman <paf31@cantab.net>
8+-- Stability : experimental
9+-- Portability :
10+--
11+-- |
12+-- Defines the types of source code comments
13+--
14+-----------------------------------------------------------------------------
15+
16+{-# LANGUAGE DeriveDataTypeable #-}
17+
18+module Language.PureScript.Comments where
19+
20+import qualified Data.Data as D
21+
22+data Comment
23+ = LineComment String
24+ | BlockComment String
25+ deriving (Show, Eq, Ord, D.Data, D.Typeable)
src/Language/PureScript/Constants.hs+15
@@ -105,6 +105,12 @@ not = "not"
105105
106106-- Prelude Values
107107
108+zero :: String
109+zero = "zero"
110+
111+one :: String
112+one = "one"
113+
108114return :: String
109115return = "return"
110116
@@ -163,6 +169,15 @@ applicativeEffDictionary = "applicativeEff"
163169bindEffDictionary :: String
164170bindEffDictionary = "bindEff"
165171
172+semiringNumber :: String
173+semiringNumber = "semiringNumber"
174+
175+ringNumber :: String
176+ringNumber = "ringNumber"
177+
178+moduloSemiringNumber :: String
179+moduloSemiringNumber = "moduloSemiringNumber"
180+
166181numNumber :: String
167182numNumber = "numNumber"
168183
src/Language/PureScript/CoreFn/Ann.hs+9−2
@@ -17,14 +17,21 @@ module Language.PureScript.CoreFn.Ann where
1717import Language.PureScript.AST.SourcePos
1818import Language.PureScript.CoreFn.Meta
1919import Language.PureScript.Types
20+import Language.PureScript.Comments
2021
2122-- |
2223-- Type alias for basic annotations
2324--
24−type Ann = (Maybe SourceSpan, Maybe Type, Maybe Meta)
25+type Ann = (Maybe SourceSpan, [Comment], Maybe Type, Maybe Meta)
2526
2627-- |
2728-- Initial annotation with no metadata
2829--
2930nullAnn :: Ann
30−nullAnn = (Nothing, Nothing, Nothing)
31+nullAnn = (Nothing, [], Nothing, Nothing)
32+
33+-- |
34+-- Remove the comments from an annotation
35+--
36+removeComments :: Ann -> Ann
37+removeComments (ss, _, ty, meta) = (ss, [], ty, meta)
src/Language/PureScript/CoreFn/Binders.hs+2−1
@@ -13,6 +13,7 @@
1313-----------------------------------------------------------------------------
1414
1515{-# LANGUAGE DeriveDataTypeable #-}
16+{-# LANGUAGE DeriveFunctor #-}
1617
1718module Language.PureScript.CoreFn.Binders where
1819
@@ -44,4 +45,4 @@ data Binder a
4445 -- |
4546 -- A binder which binds its input to an identifier
4647 --
47− | NamedBinder a Ident (Binder a) deriving (Show, D.Data, D.Typeable)
48+ | NamedBinder a Ident (Binder a) deriving (Show, D.Data, D.Typeable, Functor)
src/Language/PureScript/CoreFn/Desugar.hs+150−143
@@ -33,22 +33,161 @@ import Language.PureScript.Environment
3333import Language.PureScript.Names
3434import Language.PureScript.Sugar.TypeClasses (typeClassMemberName, superClassDictionaryNames)
3535import Language.PureScript.Types
36+import Language.PureScript.Comments
3637import qualified Language.PureScript.AST as A
37−import qualified Language.PureScript.Constants as C
3838
3939-- |
4040-- Desugars a module from AST to CoreFn representation.
4141--
4242moduleToCoreFn :: Environment -> A.Module -> Module Ann
43+moduleToCoreFn _ (A.Module _ _ Nothing) =
44+ error "Module exports were not elaborated before moduleToCoreFn"
4345moduleToCoreFn env (A.Module mn decls (Just exps)) =
4446 let imports = nub $ mapMaybe importToCoreFn decls ++ findQualModules decls
4547 exps' = nub $ concatMap exportToCoreFn exps
4648 externs = nub $ mapMaybe externToCoreFn decls
47− decls' = concatMap (declToCoreFn env Nothing) decls
49+ decls' = concatMap (declToCoreFn Nothing []) decls
4850 in Module mn imports exps' externs decls'
49−moduleToCoreFn _ (A.Module{}) =
50− error "Module exports were not elaborated before moduleToCoreFn"
5151
52+ where
53+
54+ -- |
55+ -- Desugars member declarations from AST to CoreFn representation.
56+ --
57+ declToCoreFn :: Maybe SourceSpan -> [Comment] -> A.Declaration -> [Bind Ann]
58+ declToCoreFn ss com (A.DataDeclaration Newtype _ _ [(ctor, _)]) =
59+ [NonRec (properToIdent ctor) $
60+ Abs (ss, com, Nothing, Just IsNewtype) (Ident "x") (Var nullAnn $ Qualified Nothing (Ident "x"))]
61+ declToCoreFn _ _ d@(A.DataDeclaration Newtype _ _ _) =
62+ error $ "Found newtype with multiple constructors: " ++ show d
63+ declToCoreFn ss com (A.DataDeclaration Data tyName _ ctors) =
64+ flip map ctors $ \(ctor, _) ->
65+ let (_, _, _, fields) = lookupConstructor env (Qualified (Just mn) ctor)
66+ in NonRec (properToIdent ctor) $ Constructor (ss, com, Nothing, Nothing) tyName ctor fields
67+ declToCoreFn ss _ (A.DataBindingGroupDeclaration ds) = concatMap (declToCoreFn ss []) ds
68+ declToCoreFn ss com (A.ValueDeclaration name _ _ (Right e)) =
69+ [NonRec name (exprToCoreFn ss com Nothing e)]
70+ declToCoreFn ss _ (A.BindingGroupDeclaration ds) =
71+ [Rec $ map (\(name, _, e) -> (name, exprToCoreFn ss [] Nothing e)) ds]
72+ declToCoreFn ss com (A.TypeClassDeclaration name _ supers members) =
73+ [NonRec (properToIdent name) $ mkTypeClassConstructor ss com supers members]
74+ declToCoreFn _ com (A.PositionedDeclaration ss com1 d) =
75+ declToCoreFn (Just ss) (com ++ com1) d
76+ declToCoreFn _ _ _ = []
77+
78+ -- |
79+ -- Desugars expressions from AST to CoreFn representation.
80+ --
81+ exprToCoreFn :: Maybe SourceSpan -> [Comment] -> Maybe Type -> A.Expr -> Expr Ann
82+ exprToCoreFn ss com ty (A.NumericLiteral v) =
83+ Literal (ss, com, ty, Nothing) (NumericLiteral v)
84+ exprToCoreFn ss com ty (A.StringLiteral v) =
85+ Literal (ss, com, ty, Nothing) (StringLiteral v)
86+ exprToCoreFn ss com ty (A.BooleanLiteral v) =
87+ Literal (ss, com, ty, Nothing) (BooleanLiteral v)
88+ exprToCoreFn ss com ty (A.ArrayLiteral vs) =
89+ Literal (ss, com, ty, Nothing) (ArrayLiteral $ map (exprToCoreFn ss [] Nothing) vs)
90+ exprToCoreFn ss com ty (A.ObjectLiteral vs) =
91+ Literal (ss, com, ty, Nothing) (ObjectLiteral $ map (second (exprToCoreFn ss [] Nothing)) vs)
92+ exprToCoreFn ss com ty (A.Accessor name v) =
93+ Accessor (ss, com, ty, Nothing) name (exprToCoreFn ss [] Nothing v)
94+ exprToCoreFn ss com ty (A.ObjectUpdate obj vs) =
95+ ObjectUpdate (ss, com, ty, Nothing) (exprToCoreFn ss [] Nothing obj) $ map (second (exprToCoreFn ss [] Nothing)) vs
96+ exprToCoreFn ss com ty (A.Abs (Left name) v) =
97+ Abs (ss, com, ty, Nothing) name (exprToCoreFn ss [] Nothing v)
98+ exprToCoreFn _ _ _ (A.Abs _ _) =
99+ error "Abs with Binder argument was not desugared before exprToCoreFn mn"
100+ exprToCoreFn ss com ty (A.App v1 v2) =
101+ App (ss, com, ty, Nothing) (exprToCoreFn ss [] Nothing v1) (exprToCoreFn ss [] Nothing v2)
102+ exprToCoreFn ss com ty (A.Var ident) =
103+ Var (ss, com, ty, Nothing) ident
104+ exprToCoreFn ss com ty (A.IfThenElse v1 v2 v3) =
105+ Case (ss, com, ty, Nothing) [exprToCoreFn ss [] Nothing v1]
106+ [ CaseAlternative [LiteralBinder nullAnn $ BooleanLiteral True]
107+ (Right $ exprToCoreFn Nothing [] Nothing v2)
108+ , CaseAlternative [LiteralBinder nullAnn $ BooleanLiteral False]
109+ (Right $ exprToCoreFn Nothing [] Nothing v3) ]
110+ exprToCoreFn ss com ty (A.Constructor name) =
111+ Var (ss, com, ty, Just $ getConstructorMeta name) $ fmap properToIdent name
112+ exprToCoreFn ss com ty (A.Case vs alts) =
113+ Case (ss, com, ty, Nothing) (map (exprToCoreFn ss [] Nothing) vs) (map (altToCoreFn ss) alts)
114+ exprToCoreFn ss com _ (A.TypedValue _ v ty) =
115+ exprToCoreFn ss com (Just ty) v
116+ exprToCoreFn ss com ty (A.Let ds v) =
117+ Let (ss, com, ty, Nothing) (concatMap (declToCoreFn ss []) ds) (exprToCoreFn ss [] Nothing v)
118+ exprToCoreFn ss com _ (A.TypeClassDictionaryConstructorApp name (A.TypedValue _ (A.ObjectLiteral vs) _)) =
119+ let args = map (exprToCoreFn ss [] Nothing . snd) $ sortBy (compare `on` fst) vs
120+ ctor = Var (ss, [], Nothing, Just IsTypeClassConstructor) (fmap properToIdent name)
121+ in foldl (App (ss, com, Nothing, Nothing)) ctor args
122+ exprToCoreFn ss com ty (A.TypeClassDictionaryAccessor _ ident) =
123+ Abs (ss, com, ty, Nothing) (Ident "dict")
124+ (Accessor nullAnn (runIdent ident) (Var nullAnn $ Qualified Nothing (Ident "dict")))
125+ exprToCoreFn _ com ty (A.PositionedValue ss com1 v) =
126+ exprToCoreFn (Just ss) (com ++ com1) ty v
127+ exprToCoreFn _ _ _ e =
128+ error $ "Unexpected value in exprToCoreFn mn: " ++ show e
129+
130+ -- |
131+ -- Desugars case alternatives from AST to CoreFn representation.
132+ --
133+ altToCoreFn :: Maybe SourceSpan -> A.CaseAlternative -> CaseAlternative Ann
134+ altToCoreFn ss (A.CaseAlternative bs vs) = CaseAlternative (map (binderToCoreFn ss []) bs) (go vs)
135+ where
136+ go :: Either [(A.Guard, A.Expr)] A.Expr -> Either [(Guard Ann, Expr Ann)] (Expr Ann)
137+ go (Left ges) = Left $ map (exprToCoreFn ss [] Nothing *** exprToCoreFn ss [] Nothing) ges
138+ go (Right e) = Right (exprToCoreFn ss [] Nothing e)
139+
140+ -- |
141+ -- Desugars case binders from AST to CoreFn representation.
142+ --
143+ binderToCoreFn :: Maybe SourceSpan -> [Comment] -> A.Binder -> Binder Ann
144+ binderToCoreFn ss com (A.NullBinder) =
145+ NullBinder (ss, com, Nothing, Nothing)
146+ binderToCoreFn ss com (A.BooleanBinder b) =
147+ LiteralBinder (ss, com, Nothing, Nothing) (BooleanLiteral b)
148+ binderToCoreFn ss com (A.StringBinder s) =
149+ LiteralBinder (ss, com, Nothing, Nothing) (StringLiteral s)
150+ binderToCoreFn ss com (A.NumberBinder n) =
151+ LiteralBinder (ss, com, Nothing, Nothing) (NumericLiteral n)
152+ binderToCoreFn ss com (A.VarBinder name) =
153+ VarBinder (ss, com, Nothing, Nothing) name
154+ binderToCoreFn ss com (A.ConstructorBinder dctor@(Qualified mn' _) bs) =
155+ let (_, tctor, _, _) = lookupConstructor env dctor
156+ in ConstructorBinder (ss, com, Nothing, Just $ getConstructorMeta dctor) (Qualified mn' tctor) dctor (map (binderToCoreFn ss []) bs)
157+ binderToCoreFn ss com (A.ObjectBinder bs) =
158+ LiteralBinder (ss, com, Nothing, Nothing) (ObjectLiteral $ map (second (binderToCoreFn ss [])) bs)
159+ binderToCoreFn ss com (A.ArrayBinder bs) =
160+ LiteralBinder (ss, com, Nothing, Nothing) (ArrayLiteral $ map (binderToCoreFn ss []) bs)
161+ binderToCoreFn ss com (A.ConsBinder b1 b2) =
162+ let arrCtor = Qualified (Just $ ModuleName [ProperName "Prim"]) (ProperName "Array")
163+ in ConstructorBinder (ss, com, Nothing, Nothing) arrCtor arrCtor $ map (binderToCoreFn ss []) [b1, b2]
164+ binderToCoreFn ss com (A.NamedBinder name b) =
165+ NamedBinder (ss, com, Nothing, Nothing) name (binderToCoreFn ss [] b)
166+ binderToCoreFn _ com (A.PositionedBinder ss com1 b) =
167+ binderToCoreFn (Just ss) (com ++ com1) b
168+
169+ -- |
170+ -- Gets metadata for data constructors.
171+ --
172+ getConstructorMeta :: Qualified ProperName -> Meta
173+ getConstructorMeta ctor =
174+ case lookupConstructor env ctor of
175+ (Newtype, _, _, _) -> IsNewtype
176+ dc@(Data, _, _, fields) ->
177+ let constructorType = if numConstructors (ctor, dc) == 1 then ProductType else SumType
178+ in IsConstructor constructorType fields
179+ where
180+ numConstructors :: (Qualified ProperName, (DataDeclType, ProperName, Type, [Ident])) -> Int
181+ numConstructors ty = length $ filter (((==) `on` typeConstructor) ty) $ M.toList $ dataConstructors env
182+ typeConstructor :: (Qualified ProperName, (DataDeclType, ProperName, Type, [Ident])) -> (ModuleName, ProperName)
183+ typeConstructor (Qualified (Just mn') _, (_, tyCtor, _, _)) = (mn', tyCtor)
184+ typeConstructor _ = error "Invalid argument to typeConstructor"
185+
186+-- |
187+-- Find module names from qualified references to values. This is used to
188+-- ensure instances are imported from any module that is referenced by the
189+-- current module, not just from those that are imported explicitly (#667).
190+--
52191findQualModules :: [A.Declaration] -> [ModuleName]
53192findQualModules decls =
54193 let (f, _, _, _, _) = everythingOnValues (++) (const []) fqValues (const []) (const []) (const [])
@@ -63,7 +202,7 @@ findQualModules decls =
63202--
64203importToCoreFn :: A.Declaration -> Maybe ModuleName
65204importToCoreFn (A.ImportDeclaration name _ _) = Just name
66−importToCoreFn (A.PositionedDeclaration _ d) = importToCoreFn d
205+importToCoreFn (A.PositionedDeclaration _ _ d) = importToCoreFn d
67206importToCoreFn _ = Nothing
68207
69208-- |
@@ -72,7 +211,7 @@ importToCoreFn _ = Nothing
72211externToCoreFn :: A.Declaration -> Maybe ForeignDecl
73212externToCoreFn (A.ExternDeclaration _ name js ty) = Just (name, js, ty)
74213externToCoreFn (A.ExternInstanceDeclaration name _ _ _) = Just (name, Nothing, tyObject)
75−externToCoreFn (A.PositionedDeclaration _ d) = externToCoreFn d
214+externToCoreFn (A.PositionedDeclaration _ _ d) = externToCoreFn d
76215externToCoreFn _ = Nothing
77216
78217-- |
@@ -85,158 +224,26 @@ exportToCoreFn (A.TypeRef _ (Just dctors)) = map properToIdent dctors
85224exportToCoreFn (A.ValueRef name) = [name]
86225exportToCoreFn (A.TypeClassRef name) = [properToIdent name]
87226exportToCoreFn (A.TypeInstanceRef name) = [name]
88−exportToCoreFn (A.PositionedDeclarationRef _ d) = exportToCoreFn d
227+exportToCoreFn (A.PositionedDeclarationRef _ _ d) = exportToCoreFn d
89228exportToCoreFn _ = []
90229
91−-- |
92−-- Desugars member declarations from AST to CoreFn representation.
93−--
94−declToCoreFn :: Environment -> Maybe SourceSpan -> A.Declaration -> [Bind Ann]
95−declToCoreFn _ ss (A.DataDeclaration Newtype _ _ [(ctor, _)]) =
96− [NonRec (properToIdent ctor) $
97− Abs (ss, Nothing, Just IsNewtype) (Ident "x") (Var nullAnn $ Qualified Nothing (Ident "x"))]
98−declToCoreFn _ _ d@(A.DataDeclaration Newtype _ _ _) =
99− error $ "Found newtype with multiple constructors: " ++ show d
100−declToCoreFn _ ss (A.DataDeclaration Data tyName _ ctors) =
101− flip map ctors $ \(ctor, tys) ->
102− NonRec (properToIdent ctor) $ Constructor (ss, Nothing, Nothing) tyName ctor (length tys)
103−declToCoreFn env ss (A.DataBindingGroupDeclaration ds) = concatMap (declToCoreFn env ss) ds
104−declToCoreFn env ss (A.ValueDeclaration name _ _ (Right e)) =
105− [NonRec name (exprToCoreFn env ss Nothing e)]
106−declToCoreFn env ss (A.BindingGroupDeclaration ds) =
107− [Rec $ map (\(name, _, e) -> (name, exprToCoreFn env ss Nothing e)) ds]
108−declToCoreFn _ ss (A.TypeClassDeclaration name _ supers members) =
109− [NonRec (properToIdent name) $ mkTypeClassConstructor ss supers members]
110−declToCoreFn env _ (A.PositionedDeclaration ss d) =
111− declToCoreFn env (Just ss) d
112−declToCoreFn _ _ _ = []
113−
114230-- |
115231-- Makes a typeclass dictionary constructor function. The returned expression
116232-- is a function that accepts the superclass instances and member
117233-- implementations and returns a record for the instance dictionary.
118234--
119−mkTypeClassConstructor :: Maybe SourceSpan -> [Constraint] -> [A.Declaration] -> Expr Ann
120−mkTypeClassConstructor ss [] [] = Literal (ss, Nothing, Just IsTypeClassConstructor) (ObjectLiteral [])
121−mkTypeClassConstructor ss supers members =
235+mkTypeClassConstructor :: Maybe SourceSpan -> [Comment] -> [Constraint] -> [A.Declaration] -> Expr Ann
236+mkTypeClassConstructor ss com [] [] = Literal (ss, com, Nothing, Just IsTypeClassConstructor) (ObjectLiteral [])
237+mkTypeClassConstructor ss com supers members =
122238 let args@(a:as) = sort $ map typeClassMemberName members ++ superClassDictionaryNames supers
123239 props = [ (arg, Var nullAnn $ Qualified Nothing (Ident arg)) | arg <- args ]
124240 dict = Literal nullAnn (ObjectLiteral props)
125− in Abs (ss, Nothing, Just IsTypeClassConstructor)
241+ in Abs (ss, com, Nothing, Just IsTypeClassConstructor)
126242 (Ident a)
127243 (foldr (Abs nullAnn . Ident) dict as)
128244
129−-- |
130−-- Desugars expressions from AST to CoreFn representation.
131−--
132−exprToCoreFn :: Environment -> Maybe SourceSpan -> Maybe Type -> A.Expr -> Expr Ann
133−exprToCoreFn _ ss ty (A.NumericLiteral v) =
134− Literal (ss, ty, Nothing) (NumericLiteral v)
135−exprToCoreFn _ ss ty (A.StringLiteral v) =
136− Literal (ss, ty, Nothing) (StringLiteral v)
137−exprToCoreFn _ ss ty (A.BooleanLiteral v) =
138− Literal (ss, ty, Nothing) (BooleanLiteral v)
139−exprToCoreFn env ss ty (A.ArrayLiteral vs) =
140− Literal (ss, ty, Nothing) (ArrayLiteral $ map (exprToCoreFn env ss Nothing) vs)
141−exprToCoreFn env ss ty (A.ObjectLiteral vs) =
142− Literal (ss, ty, Nothing) (ObjectLiteral $ map (second (exprToCoreFn env ss Nothing)) vs)
143−exprToCoreFn env ss ty (A.Accessor name v) =
144− Accessor (ss, ty, Nothing) name (exprToCoreFn env ss Nothing v)
145−exprToCoreFn env ss ty (A.ObjectUpdate obj vs) =
146− ObjectUpdate (ss, ty, Nothing) (exprToCoreFn env ss Nothing obj) $ map (second (exprToCoreFn env ss Nothing)) vs
147−exprToCoreFn env ss ty (A.Abs (Left name) v) =
148− Abs (ss, ty, Nothing) name (exprToCoreFn env ss Nothing v)
149−exprToCoreFn _ _ _ (A.Abs _ _) =
150− error "Abs with Binder argument was not desugared before exprToCoreFn"
151−exprToCoreFn env ss ty (A.App v1 v2) =
152− App (ss, ty, Nothing) (exprToCoreFn env ss Nothing v1) (exprToCoreFn env ss Nothing v2)
153−exprToCoreFn _ ss ty (A.Var ident) =
154− Var (ss, ty, Nothing) ident
155−exprToCoreFn env ss ty (A.IfThenElse v1 v2 v3) =
156− Case (ss, ty, Nothing) [exprToCoreFn env ss Nothing v1]
157− [ CaseAlternative [LiteralBinder nullAnn $ BooleanLiteral True]
158− (Right $ exprToCoreFn env Nothing Nothing v2)
159− , CaseAlternative [LiteralBinder nullAnn $ BooleanLiteral False]
160− (Right $ exprToCoreFn env Nothing Nothing v3) ]
161−exprToCoreFn env ss ty (A.Constructor name) =
162− Var (ss, ty, Just $ getConstructorMeta env name) $ fmap properToIdent name
163−exprToCoreFn env ss ty (A.Case vs alts) =
164− Case (ss, ty, Nothing) (map (exprToCoreFn env ss Nothing) vs) (map (altToCoreFn env ss) alts)
165−exprToCoreFn env ss _ (A.TypedValue _ v ty) =
166− exprToCoreFn env ss (Just ty) v
167−exprToCoreFn env ss ty (A.Let ds v) =
168− Let (ss, ty, Nothing) (concatMap (declToCoreFn env ss) ds) (exprToCoreFn env ss Nothing v)
169−exprToCoreFn env ss ty (A.TypeClassDictionaryConstructorApp name (A.TypedValue _ (A.ObjectLiteral vs) _)) =
170− let args = map (exprToCoreFn env ss Nothing . snd) $ sortBy (compare `on` fst) vs
171− ctor = Var (ss, Nothing, Just IsTypeClassConstructor) (fmap properToIdent name)
172− in foldl (App (ss, Nothing, Nothing)) ctor args
173−exprToCoreFn env _ ty (A.PositionedValue ss v) =
174− exprToCoreFn env (Just ss) ty v
175−exprToCoreFn _ _ _ e =
176− error $ "Unexpected value in exprToCoreFn: " ++ show e
177−
178−-- |
179−-- Desugars case alternatives from AST to CoreFn representation.
180−--
181−altToCoreFn :: Environment -> Maybe SourceSpan -> A.CaseAlternative -> CaseAlternative Ann
182−altToCoreFn env ss (A.CaseAlternative bs vs) = CaseAlternative (map (binderToCoreFn env ss) bs) (go vs)
183− where
184− go :: Either [(A.Guard, A.Expr)] A.Expr -> Either [(Guard Ann, Expr Ann)] (Expr Ann)
185− go (Left ges) = Left $ map (exprToCoreFn env ss Nothing *** exprToCoreFn env ss Nothing) ges
186− go (Right e) = Right (exprToCoreFn env ss Nothing e)
187−
188−-- |
189−-- Desugars case binders from AST to CoreFn representation.
190−--
191−binderToCoreFn :: Environment -> Maybe SourceSpan -> A.Binder -> Binder Ann
192−binderToCoreFn _ ss (A.NullBinder) =
193− NullBinder (ss, Nothing, Nothing)
194−binderToCoreFn _ ss (A.BooleanBinder b) =
195− LiteralBinder (ss, Nothing, Nothing) (BooleanLiteral b)
196−binderToCoreFn _ ss (A.StringBinder s) =
197− LiteralBinder (ss, Nothing, Nothing) (StringLiteral s)
198−binderToCoreFn _ ss (A.NumberBinder n) =
199− LiteralBinder (ss, Nothing, Nothing) (NumericLiteral n)
200−binderToCoreFn _ ss (A.VarBinder name) =
201− VarBinder (ss, Nothing, Nothing) name
202−binderToCoreFn env ss (A.ConstructorBinder dctor@(Qualified mn _) bs) =
203− let (_, tctor, _) = lookupConstructor env dctor
204− in ConstructorBinder (ss, Nothing, Just $ getConstructorMeta env dctor) (Qualified mn tctor) dctor (map (binderToCoreFn env ss) bs)
205−binderToCoreFn env ss (A.ObjectBinder bs) =
206− LiteralBinder (ss, Nothing, Nothing) (ObjectLiteral $ map (second (binderToCoreFn env ss)) bs)
207−binderToCoreFn env ss (A.ArrayBinder bs) =
208− LiteralBinder (ss, Nothing, Nothing) (ArrayLiteral $ map (binderToCoreFn env ss) bs)
209−binderToCoreFn env ss (A.ConsBinder b1 b2) =
210− let arrCtor = Qualified (Just $ ModuleName [ProperName "Prim"]) (ProperName "Array")
211− in ConstructorBinder (ss, Nothing, Nothing) arrCtor arrCtor $ map (binderToCoreFn env ss) [b1, b2]
212−binderToCoreFn env ss (A.NamedBinder name b) =
213− NamedBinder (ss, Nothing, Nothing) name (binderToCoreFn env ss b)
214−binderToCoreFn env _ (A.PositionedBinder ss b) =
215− binderToCoreFn env (Just ss) b
216−
217245-- |
218246-- Converts a ProperName to an Ident.
219247--
220248properToIdent :: ProperName -> Ident
221249properToIdent = Ident . runProperName
222−
223−-- |
224−-- Gets metadata for data constructors.
225−--
226−getConstructorMeta :: Environment -> Qualified ProperName -> Meta
227−getConstructorMeta env ctor =
228− case lookupConstructor env ctor of
229− (Newtype, _, _) -> IsNewtype
230− dc@(Data, _, ty) ->
231− let constructorType = if numConstructors (ctor, dc) == 1 then ProductType else SumType
232− in IsConstructor constructorType (getArity ty)
233− where
234− getArity :: Type -> Int
235− getArity (TypeApp (TypeApp f _) t) | f == tyFunction = getArity t + 1
236− getArity (ForAll _ ty _) = getArity ty
237− getArity _ = 0
238− numConstructors :: (Qualified ProperName, (DataDeclType, ProperName, Type)) -> Int
239− numConstructors ty = length $ filter (((==) `on` typeConstructor) ty) $ M.toList $ dataConstructors env
240− typeConstructor :: (Qualified ProperName, (DataDeclType, ProperName, Type)) -> (ModuleName, ProperName)
241− typeConstructor (Qualified (Just mn) _, (_, tyCtor, _)) = (mn, tyCtor)
242− typeConstructor _ = error "Invalid argument to typeConstructor"
src/Language/PureScript/CoreFn/Expr.hs+42−5
@@ -13,14 +13,16 @@
1313-----------------------------------------------------------------------------
1414
1515{-# LANGUAGE DeriveDataTypeable #-}
16+{-# LANGUAGE DeriveFunctor #-}
1617
1718module Language.PureScript.CoreFn.Expr where
1819
20+import Control.Arrow ((***))
21+
1922import qualified Data.Data as D
2023
2124import Language.PureScript.CoreFn.Binders
2225import Language.PureScript.CoreFn.Literals
23−import Language.PureScript.CoreFn.Meta
2426import Language.PureScript.Names
2527
2628-- |
@@ -32,9 +34,9 @@ data Expr a
3234 --
3335 = Literal a (Literal (Expr a))
3436 -- |
35− -- A data constructor (type name, constructor name, arity)
37+ -- A data constructor (type name, constructor name, field names)
3638 --
37− | Constructor a ProperName ProperName Arity
39+ | Constructor a ProperName ProperName [Ident]
3840 -- |
3941 -- A record property accessor
4042 --
@@ -62,7 +64,7 @@ data Expr a
6264 -- |
6365 -- A let binding
6466 --
65− | Let a [Bind a] (Expr a) deriving (Show, D.Data, D.Typeable)
67+ | Let a [Bind a] (Expr a) deriving (Show, D.Data, D.Typeable, Functor)
6668
6769-- |
6870-- A let or module binding.
@@ -75,7 +77,7 @@ data Bind a
7577 -- |
7678 -- Mutually recursive binding group for several values
7779 --
78− | Rec [(Ident, Expr a)] deriving (Show, D.Data, D.Typeable)
80+ | Rec [(Ident, Expr a)] deriving (Show, D.Data, D.Typeable, Functor)
7981
8082-- |
8183-- A guard is just a boolean-valued expression that appears alongside a set of binders
@@ -95,3 +97,38 @@ data CaseAlternative a = CaseAlternative
9597 --
9698 , caseAlternativeResult :: Either [(Guard a, Expr a)] (Expr a)
9799 } deriving (Show, D.Data, D.Typeable)
100+
101+instance Functor CaseAlternative where
102+
103+ fmap f (CaseAlternative cabs car) = CaseAlternative
104+ (fmap (fmap f) $ cabs)
105+ (either (Left . fmap (fmap f *** fmap f)) (Right . fmap f) car)
106+
107+-- |
108+-- Extract the annotation from a term
109+--
110+extractAnn :: Expr a -> a
111+extractAnn (Literal a _) = a
112+extractAnn (Constructor a _ _ _) = a
113+extractAnn (Accessor a _ _) = a
114+extractAnn (ObjectUpdate a _ _) = a
115+extractAnn (Abs a _ _) = a
116+extractAnn (App a _ _) = a
117+extractAnn (Var a _) = a
118+extractAnn (Case a _ _) = a
119+extractAnn (Let a _ _) = a
120+
121+
122+-- |
123+-- Modify the annotation on a term
124+--
125+modifyAnn :: (a -> a) -> Expr a -> Expr a
126+modifyAnn f (Literal a b) = Literal (f a) b
127+modifyAnn f (Constructor a b c d) = Constructor (f a) b c d
128+modifyAnn f (Accessor a b c) = Accessor (f a) b c
129+modifyAnn f (ObjectUpdate a b c) = ObjectUpdate (f a) b c
130+modifyAnn f (Abs a b c) = Abs (f a) b c
131+modifyAnn f (App a b c) = App (f a) b c
132+modifyAnn f (Var a b) = Var (f a) b
133+modifyAnn f (Case a b c) = Case (f a) b c
134+modifyAnn f (Let a b c) = Let (f a) b c
src/Language/PureScript/CoreFn/Literals.hs+2−1
@@ -13,6 +13,7 @@
1313-----------------------------------------------------------------------------
1414
1515{-# LANGUAGE DeriveDataTypeable #-}
16+{-# LANGUAGE DeriveFunctor #-}
1617
1718module Language.PureScript.CoreFn.Literals where
1819
@@ -42,4 +43,4 @@ data Literal a
4243 -- |
4344 -- An object literal
4445 --
45− | ObjectLiteral [(String, a)] deriving (Show, D.Data, D.Typeable)
46+ | ObjectLiteral [(String, a)] deriving (Show, D.Data, D.Typeable, Functor)
src/Language/PureScript/CoreFn/Meta.hs+3−6
@@ -18,6 +18,8 @@ module Language.PureScript.CoreFn.Meta where
1818
1919import qualified Data.Data as D
2020
21+import Language.PureScript.Names
22+
2123-- |
2224-- Metadata annotations
2325--
@@ -25,7 +27,7 @@ data Meta
2527 -- |
2628 -- The contained value is a data constructor
2729 --
28− = IsConstructor ConstructorType Arity
30+ = IsConstructor ConstructorType [Ident]
2931 -- |
3032 -- The contained value is a newtype
3133 --
@@ -35,11 +37,6 @@ data Meta
3537 --
3638 | IsTypeClassConstructor deriving (Show, D.Data, D.Typeable)
3739
38−-- |
39−-- Type alias for constructor arity
40−--
41−type Arity = Int
42−
4340-- |
4441-- Data constructor metadata
4542--
src/Language/PureScript/Environment.hs+10−5
@@ -41,7 +41,7 @@ data Environment = Environment {
4141 -- |
4242 -- Data constructors currently in scope, along with their associated data type constructors
4343 --
44− , dataConstructors :: M.Map (Qualified ProperName) (DataDeclType, ProperName, Type)
44+ , dataConstructors :: M.Map (Qualified ProperName) (DataDeclType, ProperName, Type, [Ident])
4545 -- |
4646 -- Type synonyms currently in scope
4747 --
@@ -136,7 +136,12 @@ data TypeKind
136136 -- |
137137 -- A local type variable
138138 --
139− | LocalTypeVariable deriving (Show, Eq, Data, Typeable)
139+ | LocalTypeVariable
140+ -- |
141+ -- A scoped type variable
142+ --
143+ | ScopedTypeVar
144+ deriving (Show, Eq, Data, Typeable)
140145
141146-- |
142147-- The type ('data' or 'newtype') of a data type declaration
@@ -223,7 +228,7 @@ primTypes = M.fromList [ (primName "Function" , (FunKind Star (FunKind Star Star
223228-- |
224229-- Finds information about data constructors from the current environment.
225230--
226−lookupConstructor :: Environment -> Qualified ProperName -> (DataDeclType, ProperName, Type)
231+lookupConstructor :: Environment -> Qualified ProperName -> (DataDeclType, ProperName, Type, [Ident])
227232lookupConstructor env ctor =
228233 fromMaybe (error "Data constructor not found") $ ctor `M.lookup` dataConstructors env
229234
@@ -232,5 +237,5 @@ lookupConstructor env ctor =
232237--
233238isNewtypeConstructor :: Environment -> Qualified ProperName -> Bool
234239isNewtypeConstructor e ctor = case lookupConstructor e ctor of
235− (Newtype, _, _) -> True
236− (Data, _, _) -> False
240+ (Newtype, _, _, _) -> True
241+ (Data, _, _, _) -> False
src/Language/PureScript/Errors.hs+28−15
@@ -17,10 +17,11 @@
1717module Language.PureScript.Errors where
1818
1919import Data.Either (lefts, rights)
20+import Data.String (IsString(..))
2021import Data.List (intersperse, intercalate)
2122import Data.Monoid
2223
23−import Control.Monad.Error
24+import Control.Monad.Except
2425import Control.Applicative ((<$>))
2526
2627import Language.PureScript.AST
@@ -67,15 +68,14 @@ data ErrorStack
6768 = ErrorStack { runErrorStack :: [CompileError] }
6869 | MultipleErrors [ErrorStack] deriving (Show)
6970
70−instance Monoid ErrorStack where
71− mempty = ErrorStack []
72− mappend (ErrorStack xs) (ErrorStack ys) = ErrorStack (xs ++ ys)
73− mappend (MultipleErrors es) x = MultipleErrors [ e <> x | e <- es ]
74− mappend x (MultipleErrors es) = MultipleErrors [ x <> e | e <- es ]
71+-- TODO: Remove strMsg, the IsString instance, and unnecessary
72+-- OverloadedStrings pragmas. See #745
73+-- | Create an ErrorStack from a string
74+strMsg :: String -> ErrorStack
75+strMsg s = ErrorStack [CompileError s Nothing Nothing]
7576
76−instance Error ErrorStack where
77− strMsg s = ErrorStack [CompileError s Nothing Nothing]
78− noMsg = ErrorStack []
77+instance IsString ErrorStack where
78+ fromString = strMsg
7979
8080prettyPrintErrorStack :: Bool -> ErrorStack -> String
8181prettyPrintErrorStack printFullStack (ErrorStack es) =
@@ -95,8 +95,8 @@ prettyPrintErrorStack printFullStack (ErrorStack es) =
9595prettyPrintErrorStack printFullStack (MultipleErrors es) =
9696 unlines $ intersperse "" $ "Multiple errors:" : map (prettyPrintErrorStack printFullStack) es
9797
98−stringifyErrorStack :: Bool -> Either ErrorStack a -> Either String a
99−stringifyErrorStack printFullStack = either (Left . prettyPrintErrorStack printFullStack) Right
98+stringifyErrorStack :: (MonadError String m) => Bool -> Either ErrorStack a -> m a
99+stringifyErrorStack printFullStack = either (throwError . prettyPrintErrorStack printFullStack) return
100100
101101isErrorNonEmpty :: CompileError -> Bool
102102isErrorNonEmpty = not . null . compileErrorMessage
@@ -107,10 +107,13 @@ showError (CompileError msg (Just (ExprError val)) _) = "Error in expression " +
107107showError (CompileError msg (Just (TypeError ty)) _) = "Error in type " ++ prettyPrintType ty ++ ":\n" ++ msg
108108
109109mkErrorStack :: String -> Maybe ErrorSource -> ErrorStack
110−mkErrorStack msg t = ErrorStack [CompileError msg t Nothing]
110+mkErrorStack msg t = ErrorStack [mkCompileError msg t]
111111
112−positionError :: SourceSpan -> ErrorStack
113−positionError pos = ErrorStack [CompileError "" Nothing (Just pos)]
112+mkCompileError :: String -> Maybe ErrorSource -> CompileError
113+mkCompileError msg t = CompileError msg t Nothing
114+
115+positionError :: SourceSpan -> CompileError
116+positionError pos = CompileError "" Nothing (Just pos)
114117
115118-- |
116119-- Rethrow an error with a more detailed error message in the case of failure
@@ -122,7 +125,7 @@ rethrow f = flip catchError $ \e -> throwError (f e)
122125-- Rethrow an error with source position information
123126--
124127rethrowWithPosition :: (MonadError ErrorStack m) => SourceSpan -> m a -> m a
125−rethrowWithPosition pos = rethrow (positionError pos <>)
128+rethrowWithPosition pos = rethrow (positionError pos `combineErrors`)
126129
127130-- |
128131-- Collect errors in in parallel
@@ -138,3 +141,13 @@ parU xs f = forM xs (withError . f) >>= collectErrors
138141 [err] -> throwError err
139142 [] -> return $ rights es
140143 errs -> throwError $ MultipleErrors errs
144+
145+-- |
146+-- Add an extra error string onto the top of each error stack in a list of possibly many errors
147+--
148+combineErrors :: CompileError -> ErrorStack -> ErrorStack
149+combineErrors ce err = go (ErrorStack [ce]) err
150+ where
151+ go (ErrorStack xs) (ErrorStack ys) = ErrorStack (xs ++ ys)
152+ go (MultipleErrors es) x = MultipleErrors [ go e x | e <- es ]
153+ go x (MultipleErrors es) = MultipleErrors [ go x e | e <- es ]
src/Language/PureScript/ModuleDependencies.hs+7−7
@@ -12,11 +12,15 @@
1212--
1313-----------------------------------------------------------------------------
1414
15+{-# LANGUAGE FlexibleContexts #-}
16+
1517module Language.PureScript.ModuleDependencies (
1618 sortModules,
1719 ModuleGraph
1820) where
1921
22+import Control.Monad.Except
23+
2024import Data.Graph
2125import Data.List (nub)
2226import Data.Maybe (mapMaybe)
@@ -35,7 +39,7 @@ type ModuleGraph = [(ModuleName, [ModuleName])]
3539--
3640-- Reports an error if the module graph contains a cycle.
3741--
38−sortModules :: [Module] -> Either String ([Module], ModuleGraph)
42+sortModules :: (MonadError String m) => [Module] -> m ([Module], ModuleGraph)
3943sortModules ms = do
4044 let verts = map (\m@(Module _ ds _) -> (m, getModuleName m, nub (concatMap usedModules ds))) ms
4145 ms' <- mapM toModule $ stronglyConnComp verts
@@ -54,7 +58,6 @@ usedModules = let (f, _, _, _, _) = everythingOnValues (++) forDecls forValues (
5458
5559 forValues :: Expr -> [ModuleName]
5660 forValues (Var (Qualified (Just mn) _)) = [mn]
57− forValues (BinaryNoParens (Qualified (Just mn) _) _ _) = [mn]
5861 forValues (Constructor (Qualified (Just mn) _)) = [mn]
5962 forValues (TypedValue _ _ ty) = forTypes ty
6063 forValues _ = []
@@ -64,13 +67,10 @@ usedModules = let (f, _, _, _, _) = everythingOnValues (++) forDecls forValues (
6467 forTypes (ConstrainedType cs _) = mapMaybe (\(Qualified mn _, _) -> mn) cs
6568 forTypes _ = []
6669
67−getModuleName :: Module -> ModuleName
68−getModuleName (Module mn _ _) = mn
69−
7070-- |
7171-- Convert a strongly connected component of the module graph to a module
7272--
73−toModule :: SCC Module -> Either String Module
73+toModule :: (MonadError String m) => SCC Module -> m Module
7474toModule (AcyclicSCC m) = return m
7575toModule (CyclicSCC [m]) = return m
76−toModule (CyclicSCC ms) = Left $ "Cycle in module dependencies: " ++ show (map getModuleName ms)
76+toModule (CyclicSCC ms) = throwError $ "Cycle in module dependencies: " ++ show (map getModuleName ms)
src/Language/PureScript/Options.hs+5−2
@@ -69,6 +69,9 @@ data Options mode = Options {
6969 -- Verbose error message
7070 --
7171 , optionsVerboseErrors :: Bool
72+ -- |
73+ -- Remove the comments from the generated js
74+ , optionsNoComments :: Bool
7275 -- |
7376 -- Specify the namespace that PureScript modules will be exported to when running in the
7477 -- browser.
@@ -80,10 +83,10 @@ data Options mode = Options {
8083-- Default compiler options
8184--
8285defaultCompileOptions :: Options Compile
83−defaultCompileOptions = Options False False False Nothing False False (CompileOptions "PS" [] [])
86+defaultCompileOptions = Options False False False Nothing False False False (CompileOptions "PS" [] [])
8487
8588-- |
8689-- Default make options
8790--
8891defaultMakeOptions :: Options Make
89−defaultMakeOptions = Options False False False Nothing False False MakeOptions
92+defaultMakeOptions = Options False False False Nothing False False False MakeOptions
src/Language/PureScript/Parser.hs+1−1
@@ -32,4 +32,4 @@ import Language.PureScript.Parser.Types as P
3232import Language.PureScript.Parser.State as P
3333import Language.PureScript.Parser.Kinds as P
3434import Language.PureScript.Parser.Lexer as P
35−import Language.PureScript.Parser.Declarations as P
35+import Language.PureScript.Parser.Declarations as P
src/Language/PureScript/Parser/Common.hs+7−6
@@ -20,6 +20,7 @@ module Language.PureScript.Parser.Common where
2020import Control.Applicative
2121import Control.Monad (guard)
2222
23+import Language.PureScript.Comments
2324import Language.PureScript.Parser.Lexer
2425import Language.PureScript.Parser.State
2526import Language.PureScript.Names
@@ -87,12 +88,6 @@ buildPostfixParser fs first = do
8788 Nothing -> return a
8889 Just a' -> go a'
8990
90−-- |
91−-- Parse an identifier in backticks or an operator
92−--
93−parseIdentInfix :: TokenParser (Qualified Ident)
94−parseIdentInfix = P.between tick tick (parseQualified (Ident <$> identifier)) <|> (parseQualified (Op <$> symbol))
95−
9691-- |
9792-- Mark the current indentation level
9893--
@@ -126,6 +121,12 @@ indented = checkIndentation (>) P.<?> "indentation"
126121same :: P.Parsec s ParseState ()
127122same = checkIndentation (==) P.<?> "no indentation"
128123
124+-- |
125+-- Read the comments from the the next token, without consuming it
126+--
127+readComments :: P.Parsec [PositionedToken] u [Comment]
128+readComments = P.lookAhead $ ptComments <$> P.anyToken
129+
129130-- |
130131-- Run a parser
131132--
src/Language/PureScript/Parser/Declarations.hs+42−12
@@ -35,11 +35,13 @@ import Control.Applicative
3535import Control.Arrow ((+++))
3636
3737import Language.PureScript.Kinds
38−import Language.PureScript.Parser.Common
3938import Language.PureScript.AST
39+import Language.PureScript.Comments
40+import Language.PureScript.Parser.Common
4041import Language.PureScript.Parser.Types
4142import Language.PureScript.Parser.Kinds
4243import Language.PureScript.Parser.Lexer
44+import Language.PureScript.Names
4345import Language.PureScript.CodeGen.JS.AST
4446import Language.PureScript.Environment
4547
@@ -50,13 +52,14 @@ import qualified Text.Parsec.Expr as P
5052-- |
5153-- Read source position information
5254--
53−withSourceSpan :: (SourceSpan -> a -> a) -> P.Parsec s u a -> P.Parsec s u a
55+withSourceSpan :: (SourceSpan -> [Comment] -> a -> a) -> P.Parsec [PositionedToken] u a -> P.Parsec [PositionedToken] u a
5456withSourceSpan f p = do
5557 start <- P.getPosition
58+ comments <- C.readComments
5659 x <- p
5760 end <- P.getPosition
5861 let sp = SourceSpan (P.sourceName start) (toSourcePos start) (toSourcePos end)
59− return $ f sp x
62+ return $ f sp comments x
6063 where
6164 toSourcePos pos = SourcePos (P.sourceLine pos) (P.sourceColumn pos)
6265
@@ -283,11 +286,13 @@ parseArrayLiteral :: TokenParser Expr
283286parseArrayLiteral = ArrayLiteral <$> squares (commaSep parseValue)
284287
285288parseObjectLiteral :: TokenParser Expr
286−parseObjectLiteral = ObjectLiteral <$> braces (commaSep parseIdentifierAndValue)
289+parseObjectLiteral = ObjectConstructor <$> braces (commaSep parseIdentifierAndValue)
287290
288−parseIdentifierAndValue :: TokenParser (String, Expr)
291+parseIdentifierAndValue :: TokenParser (String, Maybe Expr)
289292parseIdentifierAndValue = (,) <$> (C.indented *> (lname <|> stringLiteral) <* C.indented <* colon)
290− <*> (C.indented *> parseValue)
293+ <*> (C.indented *> val)
294+ where
295+ val = (Just <$> parseValue) <|> (underscore *> pure Nothing)
291296
292297parseAbs :: TokenParser Expr
293298parseAbs = do
@@ -341,6 +346,7 @@ parseValueAtom = P.choice
341346 , P.try parseBooleanLiteral
342347 , parseArrayLiteral
343348 , P.try parseObjectLiteral
349+ , P.try parseObjectGetter
344350 , parseAbs
345351 , P.try parseConstructor
346352 , P.try parseVar
@@ -348,13 +354,28 @@ parseValueAtom = P.choice
348354 , parseIfThenElse
349355 , parseDo
350356 , parseLet
351− , Parens <$> parens parseValue ]
357+ , P.try $ Parens <$> parens parseValue
358+ , parseOperatorSection
359+ , P.try parseObjectUpdaterWildcard ]
360+
361+-- |
362+-- Parse an expression in backticks or an operator
363+--
364+parseInfixExpr :: TokenParser Expr
365+parseInfixExpr = P.between tick tick parseValue
366+ <|> Var <$> parseQualified (Op <$> symbol)
352367
353−parsePropertyUpdate :: TokenParser (String, Expr)
368+parseOperatorSection :: TokenParser Expr
369+parseOperatorSection = parens $ left <|> right
370+ where
371+ right = OperatorSection <$> parseInfixExpr <* indented <*> (Right <$> parseValueAtom)
372+ left = flip OperatorSection <$> (Left <$> parseValueAtom) <* indented <*> parseInfixExpr
373+
374+parsePropertyUpdate :: TokenParser (String, Maybe Expr)
354375parsePropertyUpdate = do
355376 name <- lname <|> stringLiteral
356377 _ <- C.indented *> equals
357− value <- C.indented *> parseValue
378+ value <- C.indented *> (underscore *> pure Nothing) <|> (Just <$> parseValue)
358379 return (name, value)
359380
360381parseAccessor :: Expr -> TokenParser Expr
@@ -379,6 +400,9 @@ parseDoNotationElement = P.choice
379400 , parseDoNotationLet
380401 , P.try (DoNotationValue <$> parseValue) ]
381402
403+parseObjectGetter :: TokenParser Expr
404+parseObjectGetter = ObjectGetter <$> (underscore *> C.indented *> dot *> C.indented *> (lname <|> stringLiteral))
405+
382406-- |
383407-- Parse a value
384408--
@@ -390,17 +414,23 @@ parseValue = withSourceSpan PositionedValue
390414 where
391415 indexersAndAccessors = C.buildPostfixParser postfixTable1 parseValueAtom
392416 postfixTable1 = [ parseAccessor
393− , \v -> P.try $ flip ObjectUpdate <$> (C.indented *> braces (commaSep1 (C.indented *> parsePropertyUpdate))) <*> pure v ]
417+ , P.try . parseUpdaterBody . Just ]
394418 postfixTable2 = [ \v -> P.try (flip App <$> (C.indented *> indexersAndAccessors)) <*> pure v
395419 , \v -> flip (TypedValue True) <$> (P.try (C.indented *> doubleColon) *> parsePolyType) <*> pure v
396420 ]
397421 operators = [ [ P.Prefix (P.try (C.indented *> symbol' "-") >> return UnaryMinus)
398422 ]
399− , [ P.Infix (P.try (C.indented *> C.parseIdentInfix P.<?> "operator") >>= \ident ->
423+ , [ P.Infix (P.try (C.indented *> parseInfixExpr P.<?> "infix expression") >>= \ident ->
400424 return (BinaryNoParens ident)) P.AssocRight
401425 ]
402426 ]
403427
428+parseUpdaterBody :: Maybe Expr -> TokenParser Expr
429+parseUpdaterBody v = ObjectUpdater v <$> (C.indented *> braces (commaSep1 (C.indented *> parsePropertyUpdate)))
430+
431+parseObjectUpdaterWildcard :: TokenParser Expr
432+parseObjectUpdaterWildcard = underscore *> C.indented *> parseUpdaterBody Nothing
433+
404434parseStringBinder :: TokenParser Binder
405435parseStringBinder = StringBinder <$> stringLiteral
406436
@@ -435,7 +465,7 @@ parseNamedBinder = NamedBinder <$> (C.parseIdent <* C.indented <* at)
435465 <*> (C.indented *> parseBinder)
436466
437467parseNullBinder :: TokenParser Binder
438−parseNullBinder = reserved "_" *> return NullBinder
468+parseNullBinder = underscore *> return NullBinder
439469
440470parseIdentifierAndBinder :: TokenParser (String, Binder)
441471parseIdentifierAndBinder = do
src/Language/PureScript/Parser/Lexer.hs+44−34
@@ -15,11 +15,12 @@
1515
1616{-# LANGUAGE TupleSections #-}
1717
18−module Language.PureScript.Parser.Lexer
18+module Language.PureScript.Parser.Lexer
1919 ( PositionedToken(..)
2020 , Token()
2121 , TokenParser()
2222 , lex
23+ , anyToken
2324 , token
2425 , match
2526 , lparen
@@ -33,8 +34,8 @@ module Language.PureScript.Parser.Lexer
3334 , squares
3435 , indent
3536 , indentAt
36− , larrow
37− , rarrow
37+ , larrow
38+ , rarrow
3839 , lfatArrow
3940 , rfatArrow
4041 , colon
@@ -46,6 +47,7 @@ module Language.PureScript.Parser.Lexer
4647 , comma
4748 , semi
4849 , at
50+ , underscore
4951 , semiSep
5052 , semiSep1
5153 , commaSep
@@ -70,21 +72,19 @@ module Language.PureScript.Parser.Lexer
7072
7173import Prelude hiding (lex)
7274
75+import Data.Char (isSpace)
76+
7377import Control.Monad (void, guard)
7478import Data.Functor.Identity
7579
7680import Control.Applicative
7781
7882import Language.PureScript.Parser.State
83+import Language.PureScript.Comments
7984
8085import qualified Text.Parsec as P
8186import qualified Text.Parsec.Token as PT
8287
83−data Comment
84− = LineComment String
85− | BlockComment String
86− deriving (Show, Eq, Ord)
87−
8888data Token
8989 = LParen
9090 | RParen
@@ -106,6 +106,7 @@ data Token
106106 | Comma
107107 | Semi
108108 | At
109+ | Underscore
109110 | LName String
110111 | UName String
111112 | Qualifier String
@@ -113,7 +114,7 @@ data Token
113114 | StringLiteral String
114115 | Number (Either Integer Double)
115116 deriving (Show, Eq, Ord)
116−
117+
117118prettyPrintToken :: Token -> String
118119prettyPrintToken LParen = "("
119120prettyPrintToken RParen = ")"
@@ -134,6 +135,7 @@ prettyPrintToken Dot = "."
134135prettyPrintToken Comma = ","
135136prettyPrintToken Semi = ";"
136137prettyPrintToken At = "@"
138+prettyPrintToken Underscore = "_"
137139prettyPrintToken (Indent n) = "indentation at level " ++ show n
138140prettyPrintToken (LName s) = show s
139141prettyPrintToken (UName s) = show s
@@ -147,19 +149,19 @@ data PositionedToken = PositionedToken
147149 , ptToken :: Token
148150 , ptComments :: [Comment]
149151 } deriving (Eq)
150−
152+
151153instance Show PositionedToken where
152154 show = show . ptToken
153155
154156lex :: FilePath -> String -> Either P.ParseError [PositionedToken]
155157lex filePath input = P.parse parseTokens filePath input
156−
158+
157159parseTokens :: P.Parsec String u [PositionedToken]
158160parseTokens = whitespace *> P.many parsePositionedToken <* P.skipMany parseComment <* P.eof
159161
160162whitespace :: P.Parsec String u ()
161−whitespace = P.skipMany (P.oneOf " \t\r\n")
162−
163+whitespace = P.skipMany (P.satisfy isSpace)
164+
163165parseComment :: P.Parsec String u Comment
164166parseComment = (BlockComment <$> blockComment <|> LineComment <$> lineComment) <* whitespace
165167 where
@@ -178,11 +180,11 @@ parsePositionedToken = P.try $ do
178180
179181parseToken :: P.Parsec String u Token
180182parseToken = P.choice
181− [ P.try $ P.string "<-" *> P.notFollowedBy symbolChar *> pure LArrow
183+ [ P.try $ P.string "<-" *> P.notFollowedBy symbolChar *> pure LArrow
182184 , P.try $ P.string "<=" *> P.notFollowedBy symbolChar *> pure LFatArrow
183− , P.try $ P.string "->" *> P.notFollowedBy symbolChar *> pure RArrow
184− , P.try $ P.string "=>" *> P.notFollowedBy symbolChar *> pure RFatArrow
185− , P.try $ P.string "::" *> P.notFollowedBy symbolChar *> pure DoubleColon
185+ , P.try $ P.string "->" *> P.notFollowedBy symbolChar *> pure RArrow
186+ , P.try $ P.string "=>" *> P.notFollowedBy symbolChar *> pure RFatArrow
187+ , P.try $ P.string "::" *> P.notFollowedBy symbolChar *> pure DoubleColon
186188 , P.try $ P.char '(' *> pure LParen
187189 , P.try $ P.char ')' *> pure RParen
188190 , P.try $ P.char '{' *> pure LBrace
@@ -197,10 +199,11 @@ parseToken = P.choice
197199 , P.try $ P.char '.' *> P.notFollowedBy symbolChar *> pure Dot
198200 , P.try $ P.char ';' *> P.notFollowedBy symbolChar *> pure Semi
199201 , P.try $ P.char '@' *> P.notFollowedBy symbolChar *> pure At
200− , LName <$> parseLName
202+ , P.try $ P.char '_' *> P.notFollowedBy identLetter *> pure Underscore
203+ , LName <$> parseLName
201204 , do uName <- parseUName
202205 (guard (validModuleName uName) >> Qualifier uName <$ P.char '.') <|> pure (UName uName)
203− , Symbol <$> parseSymbol
206+ , Symbol <$> parseSymbol
204207 , StringLiteral <$> parseStringLiteral
205208 , Number <$> parseNumber
206209 ] <* whitespace
@@ -208,16 +211,16 @@ parseToken = P.choice
208211 where
209212 parseLName :: P.Parsec String u String
210213 parseLName = (:) <$> identStart <*> P.many identLetter
211−
214+
212215 parseUName :: P.Parsec String u String
213216 parseUName = (:) <$> P.upper <*> P.many uidentLetter
214−
217+
215218 parseSymbol :: P.Parsec String u String
216219 parseSymbol = P.many1 symbolChar
217−
220+
218221 identStart :: P.Parsec String u Char
219222 identStart = P.lower <|> P.oneOf "_"
220−
223+
221224 identLetter :: P.Parsec String u Char
222225 identLetter = P.alphaNum <|> P.oneOf "_'"
223226
@@ -226,13 +229,13 @@ parseToken = P.choice
226229
227230 symbolChar :: P.Parsec String u Char
228231 symbolChar = P.oneOf opChars
229−
232+
230233 parseStringLiteral :: P.Parsec String u String
231234 parseStringLiteral = blockString <|> PT.stringLiteral tokenParser
232− where
235+ where
233236 delimeter = P.try (P.string "\"\"\"")
234237 blockString = delimeter >> P.manyTill P.anyChar delimeter
235−
238+
236239 parseNumber :: P.Parsec String u (Either Integer Double)
237240 parseNumber = (Right <$> P.try (PT.float tokenParser) <|>
238241 Left <$> P.try (PT.natural tokenParser)) P.<?> "number"
@@ -262,7 +265,10 @@ tokenParser :: PT.GenTokenParser String u Identity
262265tokenParser = PT.makeTokenParser langDef
263266
264267type TokenParser a = P.Parsec [PositionedToken] ParseState a
265−
268+
269+anyToken :: TokenParser PositionedToken
270+anyToken = P.token (prettyPrintToken . ptToken) ptSourcePos Just
271+
266272token :: (Token -> Maybe a) -> TokenParser a
267273token f = P.token (prettyPrintToken . ptToken) ptSourcePos (f . ptToken)
268274
@@ -345,7 +351,10 @@ semi :: TokenParser ()
345351semi = match Semi
346352
347353at :: TokenParser ()
348−at = match At
354+at = match At
355+
356+underscore :: TokenParser ()
357+underscore = match Underscore
349358
350359-- |
351360-- Parse zero or more values separated by semicolons
@@ -406,13 +415,14 @@ uname' s = token go P.<?> show s
406415 where
407416 go (UName s') | s == s' = Just ()
408417 go _ = Nothing
409−
418+
410419symbol :: TokenParser String
411420symbol = token go P.<?> "symbol"
412421 where
413422 go (Symbol s) = Just s
414423 go Colon = Just ":"
415424 go LFatArrow = Just "<="
425+ go At = Just "@"
416426 go _ = Nothing
417427
418428symbol' :: String -> TokenParser ()
@@ -422,7 +432,7 @@ symbol' s = token go P.<?> show s
422432 go Colon | s == ":" = Just ()
423433 go LFatArrow | s == "<=" = Just ()
424434 go _ = Nothing
425−
435+
426436stringLiteral :: TokenParser String
427437stringLiteral = token go P.<?> "string literal"
428438 where
@@ -446,10 +456,10 @@ identifier = token go P.<?> "identifier"
446456 where
447457 go (LName s) | s `notElem` reservedPsNames = Just s
448458 go _ = Nothing
449−
459+
450460validModuleName :: String -> Bool
451461validModuleName s = not ('_' `elem` s)
452−
462+
453463-- |
454464-- A list of purescript reserved identifiers
455465--
@@ -477,7 +487,7 @@ reservedPsNames = [ "data"
477487 , "in"
478488 , "where"
479489 ]
480−
490+
481491reservedTypeNames :: [String]
482492reservedTypeNames = [ "forall", "where" ]
483493
@@ -486,4 +496,4 @@ reservedTypeNames = [ "forall", "where" ]
486496--
487497opChars :: [Char]
488498opChars = ":!#$%&*+./<=>?@\\^|-~"
489−
499+
src/Language/PureScript/Parser/Types.hs+1−1
@@ -45,7 +45,7 @@ parseObject :: TokenParser Type
4545parseObject = braces $ TypeApp tyObject <$> parseRow
4646
4747parseTypeWildcard :: TokenParser Type
48−parseTypeWildcard = reserved "_" >> return TypeWildcard
48+parseTypeWildcard = underscore >> return TypeWildcard
4949
5050parseTypeVariable :: TokenParser Type
5151parseTypeVariable = do
src/Language/PureScript/Pretty/JS.hs+45−9
@@ -29,6 +29,7 @@ import qualified Control.Arrow as A
2929import Language.PureScript.CodeGen.JS.AST
3030import Language.PureScript.CodeGen.JS.Common
3131import Language.PureScript.Pretty.Common
32+import Language.PureScript.Comments
3233
3334import Numeric
3435
@@ -119,6 +120,32 @@ literals = mkPattern' match
119120 [ return $ lbl ++ ": "
120121 , prettyPrintJS' js
121122 ]
123+ match (JSComment com js) = fmap concat $ sequence $
124+ [ return "\n"
125+ , currentIndent
126+ , return "/**\n"
127+ ] ++
128+ map asLine (concatMap commentLines com) ++
129+ [ currentIndent
130+ , return " */\n"
131+ , currentIndent
132+ , prettyPrintJS' js
133+ ]
134+ where
135+ commentLines :: Comment -> [String]
136+ commentLines (LineComment s) = [s]
137+ commentLines (BlockComment s) = lines s
138+
139+ asLine :: String -> StateT PrinterState Maybe String
140+ asLine s = do
141+ i <- currentIndent
142+ return $ i ++ " * " ++ removeComments s ++ "\n"
143+
144+ removeComments :: String -> String
145+ removeComments ('*' : '/' : s) = removeComments s
146+ removeComments (c : s) = c : removeComments s
147+
148+ removeComments [] = []
122149 match (JSRaw js) = return js
123150 match _ = mzero
124151
@@ -182,15 +209,24 @@ instanceOf = mkPattern match
182209 match (JSInstanceOf val ty) = Just (val, ty)
183210 match _ = Nothing
184211
185−unary :: UnaryOperator -> String -> Operator PrinterState JS String
186−unary op str = Wrap match (++)
212+unary' :: UnaryOperator -> (JS -> String) -> Operator PrinterState JS String
213+unary' op mkStr = Wrap match (++)
187214 where
188215 match :: Pattern PrinterState JS (String, JS)
189216 match = mkPattern match'
190217 where
191− match' (JSUnary op' val) | op' == op = Just (str, val)
218+ match' (JSUnary op' val) | op' == op = Just (mkStr val, val)
192219 match' _ = Nothing
193220
221+unary :: UnaryOperator -> String -> Operator PrinterState JS String
222+unary op str = unary' op (const str)
223+
224+negateOperator :: Operator PrinterState JS String
225+negateOperator = unary' Negate (\v -> if isNegate v then "- " else "-")
226+ where
227+ isNegate (JSUnary Negate _) = True
228+ isNegate _ = False
229+
194230binary :: BinaryOperator -> String -> Operator PrinterState JS String
195231binary op str = AssocL match (\v1 v2 -> v1 ++ " " ++ str ++ " " ++ v2)
196232 where
@@ -244,13 +280,13 @@ prettyPrintJS' = A.runKleisli $ runPattern matchValue
244280 , [ AssocR instanceOf $ \v1 v2 -> v1 ++ " instanceof " ++ v2 ]
245281 , [ unary Not "!" ]
246282 , [ unary BitwiseNot "~" ]
247− , [ unary Negate "-" ]
283+ , [ negateOperator ]
248284 , [ unary Positive "+" ]
249− , [ binary Multiply "*" ]
250− , [ binary Divide "/" ]
251− , [ binary Modulus "%" ]
252− , [ binary Add "+" ]
253− , [ binary Subtract "-" ]
285+ , [ binary Multiply "*"
286+ , binary Divide "/"
287+ , binary Modulus "%" ]
288+ , [ binary Add "+"
289+ , binary Subtract "-" ]
254290 , [ binary ShiftLeft "<<" ]
255291 , [ binary ShiftRight ">>" ]
256292 , [ binary ZeroFillShiftRight ">>>" ]
src/Language/PureScript/Pretty/Types.hs+1−1
@@ -34,7 +34,7 @@ import Language.PureScript.Environment
3434typeLiterals :: Pattern () Type String
3535typeLiterals = mkPattern match
3636 where
37− match TypeWildcard = Just "_"
37+ match TypeWildcard = Just "_"
3838 match (TypeVar var) = Just var
3939 match (PrettyPrintObject row) = Just $ "{ " ++ prettyPrintRow row ++ " }"
4040 match (PrettyPrintArray ty) = Just $ "[" ++ prettyPrintType ty ++ "]"
src/Language/PureScript/Pretty/Values.hs+40−31
@@ -21,12 +21,13 @@ module Language.PureScript.Pretty.Values (
2121import Data.Maybe (fromMaybe)
2222import Data.List (intercalate)
2323
24−import Control.Arrow ((<+>), runKleisli)
24+import Control.Arrow ((<+>), runKleisli, second)
2525import Control.PatternArrows
2626import Control.Monad.State
2727import Control.Applicative
2828
2929import Language.PureScript.AST
30+import Language.PureScript.Names
3031import Language.PureScript.Pretty.Common
3132import Language.PureScript.Pretty.Types (prettyPrintType)
3233
@@ -38,33 +39,28 @@ literals = mkPattern' match
3839 match (StringLiteral s) = return $ show s
3940 match (BooleanLiteral True) = return "true"
4041 match (BooleanLiteral False) = return "false"
41− match (ArrayLiteral xs) = fmap concat $ sequence
42+ match (ArrayLiteral xs) = concat <$> sequence
4243 [ return "[ "
4344 , withIndent $ prettyPrintMany prettyPrintValue' xs
4445 , return " ]"
4546 ]
46− match (ObjectLiteral []) = return "{}"
47− match (ObjectLiteral ps) = fmap concat $ sequence
48− [ return "{\n"
49− , withIndent $ prettyPrintMany prettyPrintObjectProperty ps
50− , return "\n"
51− , currentIndent
52− , return "}"
53− ]
54− match (TypeClassDictionaryConstructorApp className ps) = fmap concat $ sequence
55− [ return ((show className) ++ "(\n")
47+ match (ObjectLiteral ps) = prettyPrintObject' $ second Just `map` ps
48+ match (ObjectConstructor ps) = prettyPrintObject' ps
49+ match (ObjectGetter prop) = return $ "(." ++ prop ++ ")"
50+ match (TypeClassDictionaryConstructorApp className ps) = concat <$> sequence
51+ [ return (show className ++ "(\n")
5652 , match ps
5753 , return ")"
5854 ]
5955 match (Constructor name) = return $ show name
60− match (Case values binders) = fmap concat $ sequence
56+ match (Case values binders) = concat <$> sequence
6157 [ return "case "
6258 , unwords <$> forM values prettyPrintValue'
6359 , return " of\n"
6460 , withIndent $ prettyPrintMany prettyPrintCaseAlternative binders
6561 , currentIndent
6662 ]
67− match (Let ds val) = fmap concat $ sequence
63+ match (Let ds val) = concat <$> sequence
6864 [ return "let\n"
6965 , withIndent $ prettyPrintMany prettyPrintDeclaration ds
7066 , return "\n"
@@ -73,29 +69,31 @@ literals = mkPattern' match
7369 , prettyPrintValue' val
7470 ]
7571 match (Var ident) = return $ show ident
76− match (Do els) = fmap concat $ sequence
72+ match (Do els) = concat <$> sequence
7773 [ return "do "
7874 , withIndent $ prettyPrintMany prettyPrintDoNotationElement els
7975 , currentIndent
8076 ]
77+ match (OperatorSection op (Right val)) = return $ "(" ++ prettyPrintValue op ++ " " ++ prettyPrintValue val ++ ")"
78+ match (OperatorSection op (Left val)) = return $ "(" ++ prettyPrintValue val ++ " " ++ prettyPrintValue op ++ ")"
8179 match (TypeClassDictionary name _ _) = return $ "<<dict " ++ show name ++ ">>"
8280 match (SuperClassDictionary name _) = return $ "<<superclass dict " ++ show name ++ ">>"
8381 match (TypedValue _ val _) = prettyPrintValue' val
84− match (PositionedValue _ val) = prettyPrintValue' val
82+ match (PositionedValue _ _ val) = prettyPrintValue' val
8583 match _ = mzero
8684
8785prettyPrintDeclaration :: Declaration -> StateT PrinterState Maybe String
8886prettyPrintDeclaration (TypeDeclaration ident ty) = return $ show ident ++ " :: " ++ prettyPrintType ty
89−prettyPrintDeclaration (ValueDeclaration ident _ [] (Right val)) = fmap concat $ sequence
87+prettyPrintDeclaration (ValueDeclaration ident _ [] (Right val)) = concat <$> sequence
9088 [ return $ show ident ++ " = "
9189 , prettyPrintValue' val
9290 ]
93−prettyPrintDeclaration (PositionedDeclaration _ d) = prettyPrintDeclaration d
91+prettyPrintDeclaration (PositionedDeclaration _ _ d) = prettyPrintDeclaration d
9492prettyPrintDeclaration _ = error "Invalid argument to prettyPrintDeclaration"
9593
9694prettyPrintCaseAlternative :: CaseAlternative -> StateT PrinterState Maybe String
9795prettyPrintCaseAlternative (CaseAlternative binders result) =
98− fmap concat $ sequence
96+ concat <$> sequence
9997 [ intercalate ", " <$> forM binders prettyPrintBinder'
10098 , prettyPrintResult result
10199 ]
@@ -104,7 +102,7 @@ prettyPrintCaseAlternative (CaseAlternative binders result) =
104102 prettyPrintResult (Right v) = (" -> " ++) <$> prettyPrintValue' v
105103
106104 prettyPrintGuardedValue (grd, val) =
107− fmap concat $ sequence
105+ concat <$> sequence
108106 [ return "| "
109107 , prettyPrintValue' grd
110108 , return " -> "
@@ -116,17 +114,27 @@ prettyPrintDoNotationElement :: DoNotationElement -> StateT PrinterState Maybe S
116114prettyPrintDoNotationElement (DoNotationValue val) =
117115 prettyPrintValue' val
118116prettyPrintDoNotationElement (DoNotationBind binder val) =
119− fmap concat $ sequence
117+ concat <$> sequence
120118 [ prettyPrintBinder' binder
121119 , return " <- "
122120 , prettyPrintValue' val
123121 ]
124122prettyPrintDoNotationElement (DoNotationLet ds) =
125− fmap concat $ sequence
123+ concat <$> sequence
126124 [ return "let "
127125 , withIndent $ prettyPrintMany prettyPrintDeclaration ds
128126 ]
129−prettyPrintDoNotationElement (PositionedDoNotationElement _ el) = prettyPrintDoNotationElement el
127+prettyPrintDoNotationElement (PositionedDoNotationElement _ _ el) = prettyPrintDoNotationElement el
128+
129+prettyPrintObject' :: [(String, Maybe Expr)] -> StateT PrinterState Maybe String
130+prettyPrintObject' [] = return "{}"
131+prettyPrintObject' ps = concat <$> sequence
132+ [ return "{\n"
133+ , withIndent $ prettyPrintMany prettyPrintObjectProperty ps
134+ , return "\n"
135+ , currentIndent
136+ , return "}"
137+ ]
130138
131139ifThenElse :: Pattern PrinterState Expr ((Expr, Expr), Expr)
132140ifThenElse = mkPattern match
@@ -144,6 +152,7 @@ objectUpdate :: Pattern PrinterState Expr ([String], Expr)
144152objectUpdate = mkPattern match
145153 where
146154 match (ObjectUpdate o ps) = Just (flip map ps $ \(key, val) -> key ++ " = " ++ prettyPrintValue val, o)
155+ match (ObjectUpdater o ps) = Just (flip map ps $ \(key, val) -> key ++ " = " ++ maybe "_" prettyPrintValue val, fromMaybe (Var (Qualified Nothing $ Ident "_")) o)
147156 match _ = Nothing
148157
149158app :: Pattern PrinterState Expr (String, Expr)
@@ -188,23 +197,23 @@ prettyPrintBinderAtom = mkPattern' match
188197 match (BooleanBinder True) = return "true"
189198 match (BooleanBinder False) = return "false"
190199 match (VarBinder ident) = return $ show ident
191− match (ConstructorBinder ctor args) = fmap concat $ sequence
200+ match (ConstructorBinder ctor args) = concat <$> sequence
192201 [ return $ show ctor ++ " "
193202 , unwords <$> forM args match
194203 ]
195− match (ObjectBinder bs) = fmap concat $ sequence
204+ match (ObjectBinder bs) = concat <$> sequence
196205 [ return "{\n"
197206 , withIndent $ prettyPrintMany prettyPrintObjectPropertyBinder bs
198207 , currentIndent
199208 , return "}"
200209 ]
201− match (ArrayBinder bs) = fmap concat $ sequence
210+ match (ArrayBinder bs) = concat <$> sequence
202211 [ return "["
203212 , unwords <$> mapM prettyPrintBinder' bs
204213 , return "]"
205214 ]
206215 match (NamedBinder ident binder) = ((show ident ++ "@") ++) <$> prettyPrintBinder' binder
207− match (PositionedBinder _ binder) = prettyPrintBinder' binder
216+ match (PositionedBinder _ _ binder) = prettyPrintBinder' binder
208217 match _ = mzero
209218
210219-- |
@@ -229,13 +238,13 @@ matchConsBinder = mkPattern match'
229238 match' _ = Nothing
230239
231240prettyPrintObjectPropertyBinder :: (String, Binder) -> StateT PrinterState Maybe String
232−prettyPrintObjectPropertyBinder (key, binder) = fmap concat $ sequence
241+prettyPrintObjectPropertyBinder (key, binder) = concat <$> sequence
233242 [ return $ prettyPrintObjectKey key ++ ": "
234243 , prettyPrintBinder' binder
235244 ]
236245
237−prettyPrintObjectProperty :: (String, Expr) -> StateT PrinterState Maybe String
238−prettyPrintObjectProperty (key, value) = fmap concat $ sequence
246+prettyPrintObjectProperty :: (String, Maybe Expr) -> StateT PrinterState Maybe String
247+prettyPrintObjectProperty (key, value) = concat <$> sequence
239248 [ return $ prettyPrintObjectKey key ++ ": "
240− , prettyPrintValue' value
249+ , maybe (pure "_") prettyPrintValue' value
241250 ]
src/Language/PureScript/Renamer.hs+1−1
@@ -150,7 +150,7 @@ renameInValue (Accessor ann prop v) =
150150 Accessor ann prop <$> renameInValue v
151151renameInValue (ObjectUpdate ann obj vs) =
152152 ObjectUpdate ann <$> renameInValue obj <*> mapM (\(name, v) -> (,) name <$> renameInValue v) vs
153−renameInValue e@(Abs (_, _, Just IsTypeClassConstructor) _ _) = return e
153+renameInValue e@(Abs (_, _, _, Just IsTypeClassConstructor) _ _) = return e
154154renameInValue (Abs ann name v) =
155155 newScope $ Abs ann <$> updateScope name <*> renameInValue v
156156renameInValue (App ann v1 v2) =
src/Language/PureScript/Sugar.hs+19−10
@@ -23,20 +23,23 @@ import Language.PureScript.AST
2323import Language.PureScript.Errors
2424import Language.PureScript.Supply
2525
26−import Language.PureScript.Sugar.Operators as S
27−import Language.PureScript.Sugar.DoNotation as S
28−import Language.PureScript.Sugar.CaseDeclarations as S
29−import Language.PureScript.Sugar.TypeDeclarations as S
3026import Language.PureScript.Sugar.BindingGroups as S
31−import Language.PureScript.Sugar.TypeClasses as S
27+import Language.PureScript.Sugar.CaseDeclarations as S
28+import Language.PureScript.Sugar.DoNotation as S
3229import Language.PureScript.Sugar.Names as S
30+import Language.PureScript.Sugar.ObjectWildcards as S
31+import Language.PureScript.Sugar.Operators as S
32+import Language.PureScript.Sugar.TypeClasses as S
33+import Language.PureScript.Sugar.TypeDeclarations as S
3334
3435-- |
3536-- The desugaring pipeline proceeds as follows:
3637--
37−-- * Introduce type synonyms for type class dictionaries
38+-- * Remove signed literals in favour of `negate` applications
3839--
39−-- * Rebracket user-defined binary operators
40+-- * Desugar object literals with wildcards into lambdas
41+--
42+-- * Desugar operator sections
4043--
4144-- * Desugar do-notation using the @Prelude.Monad@ type class
4245--
@@ -44,13 +47,19 @@ import Language.PureScript.Sugar.Names as S
4447--
4548-- * Desugar type declarations into value declarations with explicit type annotations
4649--
47−-- * Group mutually recursive value and data declarations into binding groups.
48−--
4950-- * Qualify any unqualified names and types
5051--
52+-- * Rebracket user-defined binary operators
53+--
54+-- * Introduce type synonyms for type class dictionaries
55+--
56+-- * Group mutually recursive value and data declarations into binding groups.
57+--
5158desugar :: [Module] -> SupplyT (Either ErrorStack) [Module]
5259desugar = map removeSignedLiterals
53− >>> mapM desugarDoModule
60+ >>> mapM desugarObjectConstructors
61+ >=> mapM desugarOperatorSections
62+ >=> mapM desugarDoModule
5463 >=> desugarCasesModule
5564 >=> lift . (desugarTypeDeclarationsModule
5665 >=> desugarImports
src/Language/PureScript/Sugar/BindingGroups.hs+10−11
@@ -24,7 +24,6 @@ module Language.PureScript.Sugar.BindingGroups (
2424import Data.Graph
2525import Data.List (nub, intersect)
2626import Data.Maybe (isJust, mapMaybe)
27−import Data.Monoid ((<>))
2827import Control.Applicative ((<$>), (<*>), pure)
2928import Control.Monad ((<=<))
3029
@@ -52,12 +51,12 @@ createBindingGroups :: ModuleName -> [Declaration] -> Either ErrorStack [Declara
5251createBindingGroups moduleName = mapM f <=< handleDecls
5352
5453 where
55− (f, _, _) = everywhereOnValuesTopDownM return handleExprs return
56−
54+ (f, _, _) = everywhereOnValuesTopDownM return handleExprs return
55+
5756 handleExprs :: Expr -> Either ErrorStack Expr
5857 handleExprs (Let ds val) = flip Let val <$> handleDecls ds
5958 handleExprs other = return other
60−
59+
6160 -- |
6261 -- Replace all sets of mutually-recursive declarations with binding groups
6362 --
@@ -88,7 +87,7 @@ collapseBindingGroups = let (f, _, _) = everywhereOnValues id collapseBindingGro
8887 where
8988 go (DataBindingGroupDeclaration ds) = ds
9089 go (BindingGroupDeclaration ds) = map (\(ident, nameKind, val) -> ValueDeclaration ident nameKind [] (Right val)) ds
91− go (PositionedDeclaration pos d) = map (PositionedDeclaration pos) $ go d
90+ go (PositionedDeclaration pos com d) = map (PositionedDeclaration pos com) $ go d
9291 go other = [other]
9392
9493collapseBindingGroupsForValue :: Expr -> Expr
@@ -139,13 +138,13 @@ usedProperNames moduleName =
139138
140139getIdent :: Declaration -> Ident
141140getIdent (ValueDeclaration ident _ _ _) = ident
142−getIdent (PositionedDeclaration _ d) = getIdent d
141+getIdent (PositionedDeclaration _ _ d) = getIdent d
143142getIdent _ = error "Expected ValueDeclaration"
144143
145144getProperName :: Declaration -> ProperName
146145getProperName (DataDeclaration _ pn _ _) = pn
147146getProperName (TypeSynonymDeclaration pn _ _) = pn
148−getProperName (PositionedDeclaration _ d) = getProperName d
147+getProperName (PositionedDeclaration _ _ d) = getProperName d
149148getProperName _ = error "Expected DataDeclaration"
150149
151150-- |
@@ -178,10 +177,10 @@ toBindingGroup moduleName (CyclicSCC ds') =
178177 toBinding (CyclicSCC ~(d:ds)) = cycleError d ds
179178
180179 cycleError :: Declaration -> [Declaration] -> Either ErrorStack a
181− cycleError (PositionedDeclaration p d) ds = rethrowWithPosition p $ cycleError d ds
180+ cycleError (PositionedDeclaration p _ d) ds = rethrowWithPosition p $ cycleError d ds
182181 cycleError (ValueDeclaration n _ _ (Right e)) [] = Left $
183182 mkErrorStack ("Cycle in definition of " ++ show n) (Just (ExprError e))
184− cycleError d ds@(_:_) = rethrow (<> mkErrorStack ("The following are not yet defined here: " ++ unwords (map (show . getIdent) ds)) Nothing) $ cycleError d []
183+ cycleError d ds@(_:_) = rethrow (mkCompileError ("The following are not yet defined here: " ++ unwords (map (show . getIdent) ds)) Nothing `combineErrors`) $ cycleError d []
185184 cycleError _ _ = error "Expected ValueDeclaration"
186185
187186toDataBindingGroup :: SCC Declaration -> Either ErrorStack Declaration
@@ -195,11 +194,11 @@ toDataBindingGroup (CyclicSCC ds')
195194
196195isTypeSynonym :: Declaration -> Maybe ProperName
197196isTypeSynonym (TypeSynonymDeclaration pn _ _) = Just pn
198−isTypeSynonym (PositionedDeclaration _ d) = isTypeSynonym d
197+isTypeSynonym (PositionedDeclaration _ _ d) = isTypeSynonym d
199198isTypeSynonym _ = Nothing
200199
201200fromValueDecl :: Declaration -> (Ident, NameKind, Expr)
202201fromValueDecl (ValueDeclaration ident nameKind [] (Right val)) = (ident, nameKind, val)
203202fromValueDecl ValueDeclaration{} = error "Binders should have been desugared"
204−fromValueDecl (PositionedDeclaration _ d) = fromValueDecl d
203+fromValueDecl (PositionedDeclaration _ _ d) = fromValueDecl d
205204fromValueDecl _ = error "Expected ValueDeclaration"
src/Language/PureScript/Sugar/CaseDeclarations.hs+9−10
@@ -19,12 +19,11 @@ module Language.PureScript.Sugar.CaseDeclarations (
1919 desugarCasesModule
2020) where
2121
22−import Data.Monoid ((<>))
2322import Data.List (nub, groupBy)
2423
2524import Control.Applicative
2625import Control.Monad ((<=<), forM, join, unless, replicateM)
27−import Control.Monad.Error.Class
26+import Control.Monad.Except (throwError)
2827
2928import Language.PureScript.Names
3029import Language.PureScript.AST
@@ -44,7 +43,7 @@ isLeft (Right _) = False
4443--
4544desugarCasesModule :: [Module] -> SupplyT (Either ErrorStack) [Module]
4645desugarCasesModule ms = forM ms $ \(Module name ds exps) ->
47− rethrow (strMsg ("Error in module " ++ show name) <>) $
46+ rethrow (mkCompileError ("Error in module " ++ show name) Nothing `combineErrors`) $
4847 Module name <$> (desugarCases <=< desugarAbs $ ds) <*> pure exps
4948
5049desugarAbs :: [Declaration] -> SupplyT (Either ErrorStack) [Declaration]
@@ -75,16 +74,16 @@ desugarCases = desugarRest <=< fmap join . flip parU toDecls . groupBy inSameGro
7574 where
7675 go (Let ds val') = Let <$> desugarCases ds <*> pure val'
7776 go other = return other
78− desugarRest (PositionedDeclaration pos d : ds) = do
77+ desugarRest (PositionedDeclaration pos com d : ds) = do
7978 (d' : ds') <- desugarRest (d : ds)
80− return (PositionedDeclaration pos d' : ds')
79+ return (PositionedDeclaration pos com d' : ds')
8180 desugarRest (d : ds) = (:) d <$> desugarRest ds
8281 desugarRest [] = pure []
8382
8483inSameGroup :: Declaration -> Declaration -> Bool
8584inSameGroup (ValueDeclaration ident1 _ _ _) (ValueDeclaration ident2 _ _ _) = ident1 == ident2
86−inSameGroup (PositionedDeclaration _ d1) d2 = inSameGroup d1 d2
87−inSameGroup d1 (PositionedDeclaration _ d2) = inSameGroup d1 d2
85+inSameGroup (PositionedDeclaration _ _ d1) d2 = inSameGroup d1 d2
86+inSameGroup d1 (PositionedDeclaration _ _ d2) = inSameGroup d1 d2
8887inSameGroup _ _ = False
8988
9089toDecls :: [Declaration] -> SupplyT (Either ErrorStack) [Declaration]
@@ -101,9 +100,9 @@ toDecls ds@(ValueDeclaration ident _ bs result : _) = do
101100 throwError $ mkErrorStack ("Duplicate value declaration '" ++ show ident ++ "'") Nothing
102101 caseDecl <- makeCaseDeclaration ident tuples
103102 return [caseDecl]
104−toDecls (PositionedDeclaration pos d : ds) = do
103+toDecls (PositionedDeclaration pos com d : ds) = do
105104 (d' : ds') <- rethrowWithPosition pos $ toDecls (d : ds)
106− return (PositionedDeclaration pos d' : ds')
105+ return (PositionedDeclaration pos com d' : ds')
107106toDecls ds = return ds
108107
109108isVarBinder :: Binder -> Bool
@@ -112,7 +111,7 @@ isVarBinder _ = False
112111
113112toTuple :: Declaration -> ([Binder], Either [(Guard, Expr)] Expr)
114113toTuple (ValueDeclaration _ _ bs result) = (bs, result)
115−toTuple (PositionedDeclaration _ d) = toTuple d
114+toTuple (PositionedDeclaration _ _ d) = toTuple d
116115toTuple _ = error "Not a value declaration"
117116
118117makeCaseDeclaration :: Ident -> [([Binder], Either [(Guard, Expr)] Expr)] -> SupplyT (Either ErrorStack) Declaration
src/Language/PureScript/Sugar/DoNotation.hs+3−3
@@ -36,7 +36,7 @@ desugarDoModule :: Module -> SupplyT (Either ErrorStack) Module
3636desugarDoModule (Module mn ds exts) = Module mn <$> parU ds desugarDo <*> pure exts
3737
3838desugarDo :: Declaration -> SupplyT (Either ErrorStack) Declaration
39−desugarDo (PositionedDeclaration pos d) = (PositionedDeclaration pos) <$> (rethrowWithPosition pos $ desugarDo d)
39+desugarDo (PositionedDeclaration pos com d) = PositionedDeclaration pos com <$> (rethrowWithPosition pos $ desugarDo d)
4040desugarDo d =
4141 let (f, _, _) = everywhereOnValuesM return replace return
4242 in f d
@@ -49,7 +49,7 @@ desugarDo d =
4949
5050 replace :: Expr -> SupplyT (Either ErrorStack) Expr
5151 replace (Do els) = go els
52− replace (PositionedValue pos v) = PositionedValue pos <$> rethrowWithPosition pos (replace v)
52+ replace (PositionedValue pos com v) = PositionedValue pos com <$> rethrowWithPosition pos (replace v)
5353 replace other = return other
5454
5555 go :: [DoNotationElement] -> SupplyT (Either ErrorStack) Expr
@@ -71,4 +71,4 @@ desugarDo d =
7171 go (DoNotationLet ds : rest) = do
7272 rest' <- go rest
7373 return $ Let ds rest'
74− go (PositionedDoNotationElement pos el : rest) = rethrowWithPosition pos $ PositionedValue pos <$> go (el : rest)
74+ go (PositionedDoNotationElement pos com el : rest) = rethrowWithPosition pos $ PositionedValue pos com <$> go (el : rest)
src/Language/PureScript/Sugar/Names.hs+58−32
@@ -18,10 +18,9 @@ module Language.PureScript.Sugar.Names (
1818
1919import Data.List (nub)
2020import Data.Maybe (fromMaybe, isJust, mapMaybe)
21−import Data.Monoid ((<>))
2221
2322import Control.Applicative (Applicative(..), (<$>), (<*>))
24−import Control.Monad.Error
23+import Control.Monad.Except
2524
2625import qualified Data.Map as M
2726
@@ -54,8 +53,8 @@ data Exports = Exports
5453 , exportedTypeClasses :: [ProperName]
5554 -- |
5655 -- The values exported from each module
57− , exportedValues :: [Ident]
5856 --
57+ , exportedValues :: [Ident]
5958 } deriving (Show)
6059
6160-- |
@@ -105,15 +104,26 @@ addEmptyModule env name =
105104--
106105addType :: ExportEnvironment -> ModuleName -> ProperName -> [ProperName] -> Either ErrorStack ExportEnvironment
107106addType env mn name dctors = updateExportedModule env mn $ \m -> do
108− types' <- addExport (exportedTypes m) (name, dctors)
109− return $ m { exportedTypes = types' }
107+ let exTypes = exportedTypes m
108+ let exDctors = snd `concatMap` exTypes
109+ let exClasses = exportedTypeClasses m
110+ when (any ((== name) . fst) exTypes) $ throwMultipleDefError "type" name
111+ when (name `elem` exClasses) $ throwConflictingDefError "Type" "type class" name
112+ forM_ dctors $ \dctor -> do
113+ when (dctor `elem` exDctors) $ throwMultipleDefError "data constructor" dctor
114+ when (dctor `elem` exClasses) $ throwConflictingDefError "Data constructor" "type class" dctor
115+ return $ m { exportedTypes = (name, dctors) : exTypes }
110116
111117-- |
112118-- Adds a class to the export environment.
113119--
114120addTypeClass :: ExportEnvironment -> ModuleName -> ProperName -> Either ErrorStack ExportEnvironment
115121addTypeClass env mn name = updateExportedModule env mn $ \m -> do
116− classes <- addExport (exportedTypeClasses m) name
122+ let exTypes = exportedTypes m
123+ let exDctors = snd `concatMap` exTypes
124+ when (any ((== name) . fst) exTypes) $ throwConflictingDefError "Type class" "type" name
125+ when (name `elem` exDctors) $ throwConflictingDefError "Type class" "data constructor" name
126+ classes <- addExport "type class" (exportedTypeClasses m) name
117127 return $ m { exportedTypeClasses = classes }
118128
119129-- |
@@ -121,17 +131,17 @@ addTypeClass env mn name = updateExportedModule env mn $ \m -> do
121131--
122132addValue :: ExportEnvironment -> ModuleName -> Ident -> Either ErrorStack ExportEnvironment
123133addValue env mn name = updateExportedModule env mn $ \m -> do
124− values <- addExport (exportedValues m) name
134+ values <- addExport "value" (exportedValues m) name
125135 return $ m { exportedValues = values }
126136
127137-- |
128138-- Adds an entry to a list of exports unless it is already present, in which case an error is
129139-- returned.
130140--
131−addExport :: (Eq a, Show a) => [a] -> a -> Either ErrorStack [a]
132−addExport exports name =
141+addExport :: (Eq a, Show a) => String -> [a] -> a -> Either ErrorStack [a]
142+addExport what exports name =
133143 if name `elem` exports
134− then throwError $ mkErrorStack ("Multiple definitions for '" ++ show name ++ "'") Nothing
144+ then throwMultipleDefError what name
135145 else return $ name : exports
136146
137147-- |
@@ -155,7 +165,7 @@ desugarImports modules = do
155165 -- the module has access to an unfiltered list of its own members.
156166 renameInModule' :: ExportEnvironment -> ExportEnvironment -> Module -> Either ErrorStack Module
157167 renameInModule' unfilteredExports exports m@(Module mn _ _) =
158− rethrow (strMsg ("Error in module " ++ show mn) <>) $ do
168+ rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $ do
159169 let env = M.update (\_ -> M.lookup mn unfilteredExports) mn exports
160170 let exps = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn exports
161171 imports <- resolveImports env m
@@ -199,7 +209,7 @@ renameInModule imports exports (Module mn decls exps) =
199209 (go, _, _, _, _) = everywhereWithContextOnValuesM (Nothing, []) updateDecl updateValue updateBinder updateCase defS
200210
201211 updateDecl :: (Maybe SourceSpan, [Ident]) -> Declaration -> Either ErrorStack ((Maybe SourceSpan, [Ident]), Declaration)
202− updateDecl (_, bound) d@(PositionedDeclaration pos _) = return ((Just pos, bound), d)
212+ updateDecl (_, bound) d@(PositionedDeclaration pos _ _) = return ((Just pos, bound), d)
203213 updateDecl (pos, bound) (DataDeclaration dtype name args dctors) =
204214 (,) (pos, bound) <$> (DataDeclaration dtype name args <$> mapM (sndM (mapM (updateTypesEverywhere pos))) dctors)
205215 updateDecl (pos, bound) (TypeSynonymDeclaration name ps ty) =
@@ -217,25 +227,25 @@ renameInModule imports exports (Module mn decls exps) =
217227 updateDecl s d = return (s, d)
218228
219229 updateValue :: (Maybe SourceSpan, [Ident]) -> Expr -> Either ErrorStack ((Maybe SourceSpan, [Ident]), Expr)
220− updateValue (_, bound) v@(PositionedValue pos' _) = return ((Just pos', bound), v)
230+ updateValue (_, bound) v@(PositionedValue pos' _ _) = return ((Just pos', bound), v)
221231 updateValue (pos, bound) (Abs (Left arg) val') = return ((pos, arg : bound), Abs (Left arg) val')
222− updateValue (pos, bound) (Let ds val') =
232+ updateValue (pos, bound) (Let ds val') = do
223233 let args = mapMaybe letBoundVariable ds
224− in return ((pos, args ++ bound), Let ds val')
234+ unless (length (nub args) == length args) $
235+ maybe id rethrowWithPosition pos $
236+ throwError $ mkErrorStack ("Overlapping names in let binding.") Nothing
237+ return ((pos, args ++ bound), Let ds val')
238+ where
225239 updateValue (pos, bound) (Var name'@(Qualified Nothing ident)) | ident `notElem` bound =
226240 (,) (pos, bound) <$> (Var <$> updateValueName name' pos)
227241 updateValue (pos, bound) (Var name'@(Qualified (Just _) _)) =
228242 (,) (pos, bound) <$> (Var <$> updateValueName name' pos)
229− updateValue (pos, bound) (BinaryNoParens name'@(Qualified Nothing ident) v1 v2) | ident `notElem` bound =
230− (,) (pos, bound) <$> (BinaryNoParens <$> updateValueName name' pos <*> pure v1 <*> pure v2)
231− updateValue (pos, bound) (BinaryNoParens name'@(Qualified (Just _) _) v1 v2) =
232− (,) (pos, bound) <$> (BinaryNoParens <$> updateValueName name' pos <*> pure v1 <*> pure v2)
233243 updateValue s@(pos, _) (Constructor name) = (,) s <$> (Constructor <$> updateDataConstructorName name pos)
234244 updateValue s@(pos, _) (TypedValue check val ty) = (,) s <$> (TypedValue check val <$> updateTypesEverywhere pos ty)
235245 updateValue s v = return (s, v)
236246
237247 updateBinder :: (Maybe SourceSpan, [Ident]) -> Binder -> Either ErrorStack ((Maybe SourceSpan, [Ident]), Binder)
238− updateBinder (_, bound) v@(PositionedBinder pos _) = return ((Just pos, bound), v)
248+ updateBinder (_, bound) v@(PositionedBinder pos _ _) = return ((Just pos, bound), v)
239249 updateBinder s@(pos, _) (ConstructorBinder name b) = (,) s <$> (ConstructorBinder <$> updateDataConstructorName name pos <*> pure b)
240250 updateBinder s v = return (s, v)
241251
@@ -244,7 +254,7 @@ renameInModule imports exports (Module mn decls exps) =
244254
245255 letBoundVariable :: Declaration -> Maybe Ident
246256 letBoundVariable (ValueDeclaration ident _ _ _) = Just ident
247− letBoundVariable (PositionedDeclaration _ d) = letBoundVariable d
257+ letBoundVariable (PositionedDeclaration _ _ d) = letBoundVariable d
248258 letBoundVariable _ = Nothing
249259
250260 updateTypesEverywhere :: Maybe SourceSpan -> Type -> Either ErrorStack Type
@@ -308,7 +318,7 @@ findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) pri
308318 addModule :: ExportEnvironment -> Module -> Either ErrorStack ExportEnvironment
309319 addModule env (Module mn ds _) = do
310320 env' <- addEmptyModule env mn
311− rethrow (strMsg ("Error in module " ++ show mn) <>) $ foldM (addDecl mn) env' ds
321+ rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $ foldM (addDecl mn) env' ds
312322
313323 -- Add a declaration from a module to the global export environment
314324 addDecl :: ModuleName -> ExportEnvironment -> Declaration -> Either ErrorStack ExportEnvironment
@@ -317,14 +327,14 @@ findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) pri
317327 foldM go env' ds
318328 where
319329 go env'' (TypeDeclaration name _) = addValue env'' mn name
320− go env'' (PositionedDeclaration pos d) = rethrowWithPosition pos $ go env'' d
330+ go env'' (PositionedDeclaration pos _ d) = rethrowWithPosition pos $ go env'' d
321331 go _ _ = error "Invalid declaration in TypeClassDeclaration"
322332 addDecl mn env (DataDeclaration _ tn _ dcs) = addType env mn tn (map fst dcs)
323333 addDecl mn env (TypeSynonymDeclaration tn _ _) = addType env mn tn []
324334 addDecl mn env (ExternDataDeclaration tn _) = addType env mn tn []
325335 addDecl mn env (ValueDeclaration name _ _ _) = addValue env mn name
326336 addDecl mn env (ExternDeclaration _ name _ _) = addValue env mn name
327− addDecl mn env (PositionedDeclaration _ d) = addDecl mn env d
337+ addDecl mn env (PositionedDeclaration pos _ d) = rethrowWithPosition pos $ addDecl mn env d
328338 addDecl _ env _ = return env
329339
330340-- |
@@ -334,7 +344,7 @@ findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) pri
334344filterExports :: ModuleName -> [DeclarationRef] -> ExportEnvironment -> Either ErrorStack ExportEnvironment
335345filterExports mn exps env = do
336346 let moduleExports = fromMaybe (error "Module is missing") (mn `M.lookup` env)
337− moduleExports' <- rethrow (strMsg ("Error in module " ++ show mn) <>) $ filterModule moduleExports
347+ moduleExports' <- rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $ filterModule moduleExports
338348 return $ M.insert mn moduleExports' env
339349 where
340350
@@ -349,7 +359,7 @@ filterExports mn exps env = do
349359 -- Ensure the exported types and data constructors exist in the module and add them to the set of
350360 -- exports
351361 filterTypes :: [(ProperName, [ProperName])] -> [(ProperName, [ProperName])] -> DeclarationRef -> Either ErrorStack [(ProperName, [ProperName])]
352− filterTypes expTys result (PositionedDeclarationRef pos r) = rethrowWithPosition pos $ filterTypes expTys result r
362+ filterTypes expTys result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterTypes expTys result r
353363 filterTypes expTys result (TypeRef name expDcons) = do
354364 dcons <- maybe (throwError $ mkErrorStack ("Cannot export undefined type '" ++ show name ++ "'") Nothing) return $ name `lookup` expTys
355365 dcons' <- maybe (return dcons) (foldM (filterDcons name dcons) []) expDcons
@@ -365,7 +375,7 @@ filterExports mn exps env = do
365375
366376 -- Ensure the exported classes exist in the module and add them to the set of exports
367377 filterClasses :: [ProperName] -> [ProperName] -> DeclarationRef -> Either ErrorStack [ProperName]
368− filterClasses exps' result (PositionedDeclarationRef pos r) = rethrowWithPosition pos $ filterClasses exps' result r
378+ filterClasses exps' result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterClasses exps' result r
369379 filterClasses exps' result (TypeClassRef name) =
370380 if name `elem` exps'
371381 then return $ name : result
@@ -374,7 +384,7 @@ filterExports mn exps env = do
374384
375385 -- Ensure the exported values exist in the module and add them to the set of exports
376386 filterValues :: [Ident] -> [Ident] -> DeclarationRef -> Either ErrorStack [Ident]
377− filterValues exps' result (PositionedDeclarationRef pos r) = rethrowWithPosition pos $ filterValues exps' result r
387+ filterValues exps' result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterValues exps' result r
378388 filterValues exps' result (ValueRef name) =
379389 if name `elem` exps'
380390 then return $ name : result
@@ -389,7 +399,7 @@ findImports :: [Declaration] -> M.Map ModuleName (Maybe SourceSpan, ImportDeclar
389399findImports = foldl (findImports' Nothing) M.empty
390400 where
391401 findImports' pos result (ImportDeclaration mn typ qual) = M.insert mn (pos, typ, qual) result
392− findImports' _ result (PositionedDeclaration pos d) = findImports' (Just pos) result d
402+ findImports' _ result (PositionedDeclaration pos _ d) = findImports' (Just pos) result d
393403 findImports' _ result _ = result
394404
395405-- |
@@ -443,7 +453,7 @@ resolveImport currentModule importModule exps imps impQual =
443453 checkTypeRef (TypeRef _ Nothing) acc (TypeRef _ (Just _)) = acc
444454 checkTypeRef (TypeRef name (Just dctor)) _ (TypeRef name' (Just dctor')) = name == name' && dctor == dctor'
445455 checkTypeRef (TypeRef name _) _ (TypeRef name' Nothing) = name == name'
446− checkTypeRef (PositionedDeclarationRef _ r) acc hiddenRef = checkTypeRef r acc hiddenRef
456+ checkTypeRef (PositionedDeclarationRef _ _ r) acc hiddenRef = checkTypeRef r acc hiddenRef
447457 checkTypeRef _ acc _ = acc
448458 in foldl (checkTypeRef ref) False hidden
449459 isHidden hidden ref = ref `elem` hidden
@@ -457,7 +467,7 @@ resolveImport currentModule importModule exps imps impQual =
457467
458468 -- Import something explicitly
459469 importExplicit :: ImportEnvironment -> DeclarationRef -> Either ErrorStack ImportEnvironment
460− importExplicit imp (PositionedDeclarationRef pos r) = rethrowWithPosition pos $ importExplicit imp r
470+ importExplicit imp (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ importExplicit imp r
461471 importExplicit imp (ValueRef name) = do
462472 values' <- updateImports (importedValues imp) name
463473 return $ imp { importedValues = values' }
@@ -476,7 +486,7 @@ resolveImport currentModule importModule exps imps impQual =
476486 checkedRefs :: [DeclarationRef] -> Either ErrorStack [DeclarationRef]
477487 checkedRefs = mapM check
478488 where
479− check (PositionedDeclarationRef pos r) =
489+ check (PositionedDeclarationRef pos _ r) =
480490 rethrowWithPosition pos $ check r
481491 check ref@(ValueRef name) =
482492 checkImportExists "value" values name >> return ref
@@ -520,3 +530,19 @@ resolveImport currentModule importModule exps imps impQual =
520530 if item `elem` exports
521531 then return item
522532 else throwError $ mkErrorStack ("Cannot import unknown " ++ t ++ " '" ++ show item ++ "' from '" ++ show importModule ++ "'") Nothing
533+
534+-- |
535+-- Raises an error for when there is more than one definition for something.
536+--
537+throwMultipleDefError :: (Show a) => String -> a -> Either ErrorStack b
538+throwMultipleDefError what name = throwError $
539+ mkErrorStack ("Multiple definitions for " ++ what ++ " '" ++ show name ++ "'") Nothing
540+
541+-- |
542+-- Raises an error for when there is a conflicting definition for something, for example, a type
543+-- class and data constructor of the same name.
544+--
545+throwConflictingDefError :: (Show a) => String -> String -> a -> Either ErrorStack b
546+throwConflictingDefError what1 what2 name = throwError $
547+ mkErrorStack (what1 ++ " '" ++ show name ++ "' cannot be defined in the same module as a " ++ what2 ++ " of the same name") Nothing
548+
src/Language/PureScript/Sugar/ObjectWildcards.hsnew file+61
@@ -0,0 +1,61 @@
1+-----------------------------------------------------------------------------
2+--
3+-- Module : Language.PureScript.Sugar.ObjectWildcards
4+-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5+-- License : MIT
6+--
7+-- Maintainer : Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com>
8+-- Stability : experimental
9+-- Portability :
10+--
11+-- |
12+--
13+-----------------------------------------------------------------------------
14+
15+module Language.PureScript.Sugar.ObjectWildcards (
16+ desugarObjectConstructors
17+) where
18+
19+import Control.Applicative
20+import Control.Arrow (second)
21+
22+import Data.List (partition)
23+import Data.Maybe (isJust, fromJust, catMaybes)
24+
25+import Language.PureScript.AST
26+import Language.PureScript.Errors
27+import Language.PureScript.Names
28+import Language.PureScript.Supply
29+
30+desugarObjectConstructors :: Module -> SupplyT (Either ErrorStack) Module
31+desugarObjectConstructors (Module mn ds exts) = Module mn <$> mapM desugarDecl ds <*> pure exts
32+ where
33+
34+ desugarDecl :: Declaration -> SupplyT (Either ErrorStack) Declaration
35+ (desugarDecl, _, _) = everywhereOnValuesM return desugarExpr return
36+
37+ desugarExpr :: Expr -> SupplyT (Either ErrorStack) Expr
38+ desugarExpr (ObjectConstructor ps) = wrapLambda ObjectLiteral ps
39+ desugarExpr (ObjectUpdater (Just obj) ps) = wrapLambda (ObjectUpdate obj) ps
40+ desugarExpr (ObjectUpdater Nothing ps) = do
41+ obj <- Ident <$> freshName
42+ Abs (Left obj) <$> wrapLambda (ObjectUpdate (Var (Qualified Nothing obj))) ps
43+ desugarExpr (ObjectGetter prop) = do
44+ arg <- Ident <$> freshName
45+ return $ Abs (Left arg) (Accessor prop (Var (Qualified Nothing arg)))
46+ desugarExpr e = return e
47+
48+ wrapLambda :: ([(String, Expr)] -> Expr) -> [(String, Maybe Expr)] -> SupplyT (Either ErrorStack) Expr
49+ wrapLambda mkVal ps =
50+ let (props, args) = partition (isJust . snd) ps
51+ in if null args
52+ then return . mkVal $ second fromJust `map` props
53+ else do
54+ (args', ps') <- unzip <$> mapM mkProp ps
55+ return $ foldr (Abs . Left) (mkVal ps') (catMaybes args')
56+
57+ mkProp :: (String, Maybe Expr) -> SupplyT (Either ErrorStack) (Maybe Ident, (String, Expr))
58+ mkProp (name, Just e) = return (Nothing, (name, e))
59+ mkProp (name, Nothing) = do
60+ arg <- Ident <$> freshName
61+ return (Just arg, (name, Var (Qualified Nothing arg)))
src/Language/PureScript/Sugar/Operators.hs+28−16
@@ -21,18 +21,19 @@
2121
2222module Language.PureScript.Sugar.Operators (
2323 rebracket,
24− removeSignedLiterals
24+ removeSignedLiterals,
25+ desugarOperatorSections
2526) where
2627
27−import Language.PureScript.Names
2828import Language.PureScript.AST
2929import Language.PureScript.Errors
30+import Language.PureScript.Names
31+import Language.PureScript.Supply
3032
3133import Control.Applicative
3234import Control.Monad.State
33−import Control.Monad.Error.Class
35+import Control.Monad.Except
3436
35−import Data.Monoid ((<>))
3637import Data.Function (on)
3738import Data.Functor.Identity
3839import Data.List (groupBy, sortBy)
@@ -58,8 +59,6 @@ removeSignedLiterals (Module mn ds exts) = Module mn (map f' ds) exts
5859 where
5960 (f', _, _) = everywhereOnValues id go id
6061
61− go (UnaryMinus (NumericLiteral (Left n))) = NumericLiteral (Left $ negate n)
62− go (UnaryMinus (NumericLiteral (Right n))) = NumericLiteral (Right $ negate n)
6362 go (UnaryMinus val) = App (Var (Qualified (Just (ModuleName [ProperName C.prelude])) (Ident C.negate))) val
6463 go other = other
6564
@@ -80,7 +79,7 @@ collectFixities :: Module -> [(Qualified Ident, SourceSpan, Fixity)]
8079collectFixities (Module moduleName ds _) = concatMap collect ds
8180 where
8281 collect :: Declaration -> [(Qualified Ident, SourceSpan, Fixity)]
83− collect (PositionedDeclaration pos (FixityDeclaration fixity name)) = [(Qualified (Just moduleName) (Op name), pos, fixity)]
82+ collect (PositionedDeclaration pos _ (FixityDeclaration fixity name)) = [(Qualified (Just moduleName) (Op name), pos, fixity)]
8483 collect FixityDeclaration{} = error "Fixity without srcpos info"
8584 collect _ = []
8685
@@ -90,7 +89,7 @@ ensureNoDuplicates m = go $ sortBy (compare `on` fst) m
9089 go [] = return ()
9190 go [_] = return ()
9291 go ((x@(Qualified (Just mn) name), _) : (y, pos) : _) | x == y =
93− rethrow (strMsg ("Error in module " ++ show mn) <>) $
92+ rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $
9493 rethrowWithPosition pos $
9594 throwError $ mkErrorStack ("Redefined fixity for " ++ show name) Nothing
9695 go (_ : rest) = go rest
@@ -105,7 +104,7 @@ customOperatorTable fixities =
105104 in
106105 map (map (\(name, f, _, a) -> (name, f, a))) groups
107106
108−type Chain = [Either Expr (Qualified Ident)]
107+type Chain = [Either Expr Expr]
109108
110109matchOperators :: [[(Qualified Ident, Expr -> Expr -> Expr, Associativity)]] -> Expr -> Either ErrorStack Expr
111110matchOperators ops = parseChains
@@ -114,11 +113,11 @@ matchOperators ops = parseChains
114113 parseChains b@BinaryNoParens{} = bracketChain (extendChain b)
115114 parseChains other = return other
116115 extendChain :: Expr -> Chain
117− extendChain (BinaryNoParens name l r) = Left l : Right name : extendChain r
116+ extendChain (BinaryNoParens op l r) = Left l : Right op : extendChain r
118117 extendChain other = [Left other]
119118 bracketChain :: Chain -> Either ErrorStack Expr
120119 bracketChain = either (Left . (`mkErrorStack` Nothing) . show) Right . P.parse (P.buildExpressionParser opTable parseValue <* P.eof) "operator expression"
121− opTable = [P.Infix (P.try (parseTicks >>= \ident -> return (\t1 t2 -> App (App (Var ident) t1) t2))) P.AssocLeft]
120+ opTable = [P.Infix (P.try (parseTicks >>= \op -> return (\t1 t2 -> App (App op t1) t2))) P.AssocLeft]
122121 : map (map (\(name, f, a) -> P.Infix (P.try (matchOp name) >> return f) (toAssoc a))) ops
123122 ++ [[ P.Infix (P.try (parseOp >>= \ident -> return (\t1 t2 -> App (App (Var ident) t1) t2))) P.AssocLeft ]]
124123
@@ -136,17 +135,30 @@ parseValue = token (either Just (const Nothing)) P.<?> "expression"
136135parseOp :: P.Parsec Chain () (Qualified Ident)
137136parseOp = token (either (const Nothing) fromOp) P.<?> "operator"
138137 where
139− fromOp q@(Qualified _ (Op _)) = Just q
138+ fromOp (Var q@(Qualified _ (Op _))) = Just q
140139 fromOp _ = Nothing
141140
142−parseTicks :: P.Parsec Chain () (Qualified Ident)
143−parseTicks = token (either (const Nothing) fromOp) P.<?> "infix function"
141+parseTicks :: P.Parsec Chain () Expr
142+parseTicks = token (either (const Nothing) fromOther) P.<?> "infix function"
144143 where
145− fromOp q@(Qualified _ (Ident _)) = Just q
146− fromOp _ = Nothing
144+ fromOther (Var (Qualified _ (Op _))) = Nothing
145+ fromOther v = Just v
147146
148147matchOp :: Qualified Ident -> P.Parsec Chain () ()
149148matchOp op = do
150149 ident <- parseOp
151150 guard $ ident == op
152151
152+desugarOperatorSections :: Module -> SupplyT (Either ErrorStack) Module
153+desugarOperatorSections (Module mn ds exts) = Module mn <$> mapM goDecl ds <*> pure exts
154+ where
155+
156+ goDecl :: Declaration -> SupplyT (Either ErrorStack) Declaration
157+ (goDecl, _, _) = everywhereOnValuesM return goExpr return
158+
159+ goExpr :: Expr -> SupplyT (Either ErrorStack) Expr
160+ goExpr (OperatorSection op (Left val)) = return $ App op val
161+ goExpr (OperatorSection op (Right val)) = do
162+ arg <- Ident <$> freshName
163+ return $ Abs (Left arg) $ App (App op (Var (Qualified Nothing arg))) val
164+ goExpr other = return other
src/Language/PureScript/Sugar/TypeClasses.hs+23−23
@@ -21,23 +21,22 @@ module Language.PureScript.Sugar.TypeClasses
2121 ) where
2222
2323import Language.PureScript.AST hiding (isExported)
24−import Language.PureScript.Names
25−import Language.PureScript.Types
26−import Language.PureScript.Kinds
27−import Language.PureScript.Sugar.CaseDeclarations
2824import Language.PureScript.Environment
2925import Language.PureScript.Errors
30−import Language.PureScript.Supply
26+import Language.PureScript.Kinds
27+import Language.PureScript.Names
3128import Language.PureScript.Pretty.Types (prettyPrintTypeAtom)
29+import Language.PureScript.Sugar.CaseDeclarations
30+import Language.PureScript.Supply
31+import Language.PureScript.Types
3232
3333import qualified Language.PureScript.Constants as C
3434
3535import Control.Applicative
36−import Control.Monad.Error
37−import Control.Monad.State
3836import Control.Arrow (first, second)
37+import Control.Monad.Except
38+import Control.Monad.State
3939import Data.List ((\\), find)
40−import Data.Monoid ((<>))
4140import Data.Maybe (catMaybes, mapMaybe, isJust)
4241
4342import qualified Data.Map as M
@@ -158,15 +157,15 @@ desugarDecl mn exps = go
158157 where
159158 go d@(TypeClassDeclaration name args implies members) = do
160159 modify (M.insert (mn, name) d)
161− return $ (Nothing, d : typeClassDictionaryDeclaration name args implies members : map (typeClassMemberToDictionaryAccessor mn name args) members)
160+ return (Nothing, d : typeClassDictionaryDeclaration name args implies members : map (typeClassMemberToDictionaryAccessor mn name args) members)
162161 go d@(ExternInstanceDeclaration name _ className tys) = return (expRef name className tys, [d])
163162 go d@(TypeInstanceDeclaration name deps className tys members) = do
164163 desugared <- lift $ desugarCases members
165164 dictDecl <- typeInstanceDictionaryDeclaration name mn deps className tys desugared
166− return $ (expRef name className tys, [d, dictDecl])
167− go (PositionedDeclaration pos d) = do
165+ return (expRef name className tys, [d, dictDecl])
166+ go (PositionedDeclaration pos com d) = do
168167 (dr, ds) <- rethrowWithPosition pos $ desugarDecl mn exps d
169− return (dr, map (PositionedDeclaration pos) ds)
168+ return (dr, map (PositionedDeclaration pos com) ds)
170169 go other = return (Nothing, [other])
171170
172171 expRef :: Ident -> Qualified ProperName -> [Type] -> Maybe DeclarationRef
@@ -197,7 +196,7 @@ desugarDecl mn exps = go
197196
198197memberToNameAndType :: Declaration -> (Ident, Type)
199198memberToNameAndType (TypeDeclaration ident ty) = (ident, ty)
200−memberToNameAndType (PositionedDeclaration _ d) = memberToNameAndType d
199+memberToNameAndType (PositionedDeclaration _ _ d) = memberToNameAndType d
201200memberToNameAndType _ = error "Invalid declaration in type class definition"
202201
203202typeClassDictionaryDeclaration :: ProperName -> [(String, Maybe Kind)] -> [Constraint] -> [Declaration] -> Declaration
@@ -212,11 +211,12 @@ typeClassDictionaryDeclaration name args implies members =
212211
213212typeClassMemberToDictionaryAccessor :: ModuleName -> ProperName -> [(String, Maybe Kind)] -> Declaration -> Declaration
214213typeClassMemberToDictionaryAccessor mn name args (TypeDeclaration ident ty) =
215− ValueDeclaration ident TypeClassAccessorImport [] $ Right $
216− TypedValue False (Abs (Left $ Ident "dict") (Accessor (runIdent ident) (Var $ Qualified Nothing (Ident "dict")))) $
217− moveQuantifiersToFront (quantify (ConstrainedType [(Qualified (Just mn) name, map (TypeVar . fst) args)] ty))
218−typeClassMemberToDictionaryAccessor mn name args (PositionedDeclaration pos d) =
219− PositionedDeclaration pos $ typeClassMemberToDictionaryAccessor mn name args d
214+ let className = Qualified (Just mn) name
215+ in ValueDeclaration ident TypeClassAccessorImport [] $ Right $
216+ TypedValue False (TypeClassDictionaryAccessor className ident) $
217+ moveQuantifiersToFront (quantify (ConstrainedType [(className, map (TypeVar . fst) args)] ty))
218+typeClassMemberToDictionaryAccessor mn name args (PositionedDeclaration pos com d) =
219+ PositionedDeclaration pos com $ typeClassMemberToDictionaryAccessor mn name args d
220220typeClassMemberToDictionaryAccessor _ _ _ _ = error "Invalid declaration in type class definition"
221221
222222unit :: Type
@@ -224,7 +224,7 @@ unit = TypeApp tyObject REmpty
224224
225225typeInstanceDictionaryDeclaration :: Ident -> ModuleName -> [Constraint] -> Qualified ProperName -> [Type] -> [Declaration] -> Desugar Declaration
226226typeInstanceDictionaryDeclaration name mn deps className tys decls =
227− rethrow (strMsg ("Error in type class instance " ++ show className ++ " " ++ unwords (map prettyPrintTypeAtom tys) ++ ":") <>) $ do
227+ rethrow (mkCompileError ("Error in type class instance " ++ show className ++ " " ++ unwords (map prettyPrintTypeAtom tys) ++ ":") Nothing `combineErrors`) $ do
228228 m <- get
229229
230230 -- Lookup the type arguments and member types for the type class
@@ -263,7 +263,7 @@ typeInstanceDictionaryDeclaration name mn deps className tys decls =
263263 where
264264
265265 declName :: Declaration -> Maybe Ident
266− declName (PositionedDeclaration _ d) = declName d
266+ declName (PositionedDeclaration _ _ d) = declName d
267267 declName (ValueDeclaration ident _ _ _) = Just ident
268268 declName (TypeDeclaration ident _) = Just ident
269269 declName _ = Nothing
@@ -272,15 +272,15 @@ typeInstanceDictionaryDeclaration name mn deps className tys decls =
272272 memberToValue tys' (ValueDeclaration ident _ [] (Right val)) = do
273273 _ <- lift . lift . maybe (Left $ mkErrorStack ("Type class does not define member '" ++ show ident ++ "'") Nothing) Right $ lookup ident tys'
274274 return val
275− memberToValue tys' (PositionedDeclaration pos d) = rethrowWithPosition pos $ do
275+ memberToValue tys' (PositionedDeclaration pos com d) = rethrowWithPosition pos $ do
276276 val <- memberToValue tys' d
277− return (PositionedValue pos val)
277+ return (PositionedValue pos com val)
278278 memberToValue _ _ = error "Invalid declaration in type instance definition"
279279
280280typeClassMemberName :: Declaration -> String
281281typeClassMemberName (TypeDeclaration ident _) = runIdent ident
282282typeClassMemberName (ValueDeclaration ident _ _ _) = runIdent ident
283−typeClassMemberName (PositionedDeclaration _ d) = typeClassMemberName d
283+typeClassMemberName (PositionedDeclaration _ _ d) = typeClassMemberName d
284284typeClassMemberName d = error $ "Invalid declaration in type class definition: " ++ show d
285285
286286superClassDictionaryNames :: [Constraint] -> [String]
src/Language/PureScript/Sugar/TypeDeclarations.hs+6−8
@@ -19,11 +19,9 @@ module Language.PureScript.Sugar.TypeDeclarations (
1919 desugarTypeDeclarationsModule
2020) where
2121
22−import Data.Monoid ((<>))
23−
2422import Control.Applicative
25−import Control.Monad.Error.Class
2623import Control.Monad (forM)
24+import Control.Monad.Except (throwError)
2725
2826import Language.PureScript.AST
2927import Language.PureScript.Names
@@ -36,25 +34,25 @@ import Language.PureScript.Traversals
3634--
3735desugarTypeDeclarationsModule :: [Module] -> Either ErrorStack [Module]
3836desugarTypeDeclarationsModule ms = forM ms $ \(Module name ds exps) ->
39− rethrow (strMsg ("Error in module " ++ show name) <>) $
37+ rethrow (mkCompileError ("Error in module " ++ show name) Nothing `combineErrors`) $
4038 Module name <$> desugarTypeDeclarations ds <*> pure exps
4139
4240-- |
4341-- Replace all top level type declarations with type annotations
4442--
4543desugarTypeDeclarations :: [Declaration] -> Either ErrorStack [Declaration]
46−desugarTypeDeclarations (PositionedDeclaration pos d : ds) = do
44+desugarTypeDeclarations (PositionedDeclaration pos com d : ds) = do
4745 (d' : ds') <- rethrowWithPosition pos $ desugarTypeDeclarations (d : ds)
48− return (PositionedDeclaration pos d' : ds')
46+ return (PositionedDeclaration pos com d' : ds')
4947desugarTypeDeclarations (TypeDeclaration name ty : d : rest) = do
5048 (_, nameKind, val) <- fromValueDeclaration d
5149 desugarTypeDeclarations (ValueDeclaration name nameKind [] (Right (TypedValue True val ty)) : rest)
5250 where
5351 fromValueDeclaration :: Declaration -> Either ErrorStack (Ident, NameKind, Expr)
5452 fromValueDeclaration (ValueDeclaration name' nameKind [] (Right val)) | name == name' = return (name', nameKind, val)
55− fromValueDeclaration (PositionedDeclaration pos d') = do
53+ fromValueDeclaration (PositionedDeclaration pos com d') = do
5654 (ident, nameKind, val) <- rethrowWithPosition pos $ fromValueDeclaration d'
57− return (ident, nameKind, PositionedValue pos val)
55+ return (ident, nameKind, PositionedValue pos com val)
5856 fromValueDeclaration _ = throwError $ mkErrorStack ("Orphan type declaration for " ++ show name) Nothing
5957desugarTypeDeclarations (TypeDeclaration name _ : []) = throwError $ mkErrorStack ("Orphan type declaration for " ++ show name) Nothing
6058desugarTypeDeclarations (ValueDeclaration name nameKind bs val : rest) = do
src/Language/PureScript/Supply.hs+1−1
@@ -24,7 +24,7 @@ import Data.Functor.Identity
2424
2525import Control.Applicative
2626import Control.Monad.State
27−import Control.Monad.Error.Class
27+import Control.Monad.Except
2828
2929newtype SupplyT m a = SupplyT { unSupplyT :: StateT Integer m a } deriving (Functor, Applicative, Monad, MonadTrans)
3030
src/Language/PureScript/TypeChecker.hs+19−19
@@ -27,12 +27,11 @@ import Language.PureScript.TypeChecker.Synonyms as T
2727
2828import Data.Maybe
2929import Data.List (nub, (\\), find, intercalate)
30−import Data.Monoid ((<>))
3130import Data.Foldable (for_)
3231import qualified Data.Map as M
3332
3433import Control.Monad.State
35−import Control.Monad.Error
34+import Control.Monad.Except
3635
3736import Language.PureScript.Types
3837import Language.PureScript.Names
@@ -47,7 +46,7 @@ addDataType moduleName dtype name args dctors ctorKind = do
4746 env <- getEnv
4847 putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (ctorKind, DataType args dctors) (types env) }
4948 forM_ dctors $ \(dctor, tys) ->
50− rethrow (strMsg ("Error in data constructor " ++ show dctor) <>) $
49+ rethrow (mkCompileError ("Error in data constructor " ++ show dctor) Nothing `combineErrors`) $
5150 addDataConstructor moduleName dtype name (map fst args) dctor tys
5251
5352addDataConstructor :: ModuleName -> DataDeclType -> ProperName -> [String] -> ProperName -> [Type] -> Check ()
@@ -57,7 +56,8 @@ addDataConstructor moduleName dtype name args dctor tys = do
5756 let retTy = foldl TypeApp (TypeConstructor (Qualified (Just moduleName) name)) (map TypeVar args)
5857 let dctorTy = foldr function retTy tys
5958 let polyType = mkForAll args dctorTy
60− putEnv $ env { dataConstructors = M.insert (Qualified (Just moduleName) dctor) (dtype, name, polyType) (dataConstructors env) }
59+ let fields = [Ident ("value" ++ show n) | n <- [0..(length tys - 1)]]
60+ putEnv $ env { dataConstructors = M.insert (Qualified (Just moduleName) dctor) (dtype, name, polyType, fields) (dataConstructors env) }
6161
6262addTypeSynonym :: ModuleName -> ProperName -> [(String, Maybe Kind)] -> Type -> Kind -> Check ()
6363addTypeSynonym moduleName name args ty kind = do
@@ -84,12 +84,12 @@ addTypeClass moduleName pn args implies ds =
8484 modify $ \st -> st { checkEnv = (checkEnv st) { typeClasses = M.insert (Qualified (Just moduleName) pn) (args, members, implies) (typeClasses . checkEnv $ st) } }
8585 where
8686 toPair (TypeDeclaration ident ty) = (ident, ty)
87− toPair (PositionedDeclaration _ d) = toPair d
87+ toPair (PositionedDeclaration _ _ d) = toPair d
8888 toPair _ = error "Invalid declaration in TypeClassDeclaration"
8989
9090addTypeClassDictionaries :: [TypeClassDictionaryInScope] -> Check ()
9191addTypeClassDictionaries entries =
92− let mentries = M.fromList [ ((canonicalizeDictionary entry, mn), entry) | entry@TypeClassDictionaryInScope{ tcdName = Qualified mn _ } <- entries ]
92+ let mentries = M.fromList [ ((canonicalizeDictionary entry, mn), entry) | entry@TypeClassDictionaryInScope{ tcdName = Qualified mn _ } <- entries ]
9393 in modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = (typeClassDictionaries . checkEnv $ st) `M.union` mentries } }
9494
9595checkDuplicateTypeArguments :: [String] -> Check ()
@@ -133,7 +133,7 @@ typeCheckAll mainModuleName moduleName exps = go
133133 go :: [Declaration] -> Check [Declaration]
134134 go [] = return []
135135 go (DataDeclaration dtype name args dctors : rest) = do
136− rethrow (strMsg ("Error in type constructor " ++ show name) <>) $ do
136+ rethrow (mkCompileError ("Error in type constructor " ++ show name) Nothing `combineErrors`) $ do
137137 when (dtype == Newtype) $ checkNewtype dctors
138138 checkDuplicateTypeArguments $ map fst args
139139 ctorKind <- kindsOf True moduleName name args (concatMap snd dctors)
@@ -147,7 +147,7 @@ typeCheckAll mainModuleName moduleName exps = go
147147 checkNewtype [(_, _)] = throwError . strMsg $ "newtypes constructors must have a single argument"
148148 checkNewtype _ = throwError . strMsg $ "newtypes must have a single constructor"
149149 go (d@(DataBindingGroupDeclaration tys) : rest) = do
150− rethrow (strMsg "Error in data binding group" <>) $ do
150+ rethrow (mkCompileError "Error in data binding group" Nothing `combineErrors`) $ do
151151 let syns = mapMaybe toTypeSynonym tys
152152 let dataDecls = mapMaybe toDataDecl tys
153153 (syn_ks, data_ks) <- kindsOfAll moduleName syns (map (\(_, name, args, dctors) -> (name, args, concatMap snd dctors)) dataDecls)
@@ -163,13 +163,13 @@ typeCheckAll mainModuleName moduleName exps = go
163163 return $ d : ds
164164 where
165165 toTypeSynonym (TypeSynonymDeclaration nm args ty) = Just (nm, args, ty)
166− toTypeSynonym (PositionedDeclaration _ d') = toTypeSynonym d'
166+ toTypeSynonym (PositionedDeclaration _ _ d') = toTypeSynonym d'
167167 toTypeSynonym _ = Nothing
168168 toDataDecl (DataDeclaration dtype nm args dctors) = Just (dtype, nm, args, dctors)
169− toDataDecl (PositionedDeclaration _ d') = toDataDecl d'
169+ toDataDecl (PositionedDeclaration _ _ d') = toDataDecl d'
170170 toDataDecl _ = Nothing
171171 go (TypeSynonymDeclaration name args ty : rest) = do
172− rethrow (strMsg ("Error in type synonym " ++ show name) <>) $ do
172+ rethrow (mkCompileError ("Error in type synonym " ++ show name) Nothing `combineErrors`) $ do
173173 checkDuplicateTypeArguments $ map fst args
174174 kind <- kindsOf False moduleName name args [ty]
175175 let args' = args `withKinds` kind
@@ -178,7 +178,7 @@ typeCheckAll mainModuleName moduleName exps = go
178178 return $ TypeSynonymDeclaration name args ty : ds
179179 go (TypeDeclaration _ _ : _) = error "Type declarations should have been removed"
180180 go (ValueDeclaration name nameKind [] (Right val) : rest) = do
181− d <- rethrow (strMsg ("Error in declaration " ++ show name) <>) $ do
181+ d <- rethrow (mkCompileError ("Error in declaration " ++ show name) Nothing `combineErrors`) $ do
182182 valueIsNotDefined moduleName name
183183 [(_, (val', ty))] <- typesOf mainModuleName moduleName [(name, val)]
184184 addValue moduleName name ty nameKind
@@ -187,7 +187,7 @@ typeCheckAll mainModuleName moduleName exps = go
187187 return $ d : ds
188188 go (ValueDeclaration{} : _) = error "Binders were not desugared"
189189 go (BindingGroupDeclaration vals : rest) = do
190− d <- rethrow (strMsg ("Error in binding group " ++ show (map (\(ident, _, _) -> ident) vals)) <>) $ do
190+ d <- rethrow (mkCompileError ("Error in binding group " ++ show (map (\(ident, _, _) -> ident) vals)) Nothing `combineErrors`) $ do
191191 forM_ (map (\(ident, _, _) -> ident) vals) $ \name ->
192192 valueIsNotDefined moduleName name
193193 tys <- typesOf mainModuleName moduleName $ map (\(ident, _, ty) -> (ident, ty)) vals
@@ -207,7 +207,7 @@ typeCheckAll mainModuleName moduleName exps = go
207207 ds <- go rest
208208 return $ d : ds
209209 go (d@(ExternDeclaration importTy name _ ty) : rest) = do
210− rethrow (strMsg ("Error in foreign import declaration " ++ show name) <>) $ do
210+ rethrow (mkCompileError ("Error in foreign import declaration " ++ show name) Nothing `combineErrors`) $ do
211211 env <- getEnv
212212 kind <- kindOf moduleName ty
213213 guardWith (strMsg "Expected kind *") $ kind == Star
@@ -239,10 +239,10 @@ typeCheckAll mainModuleName moduleName exps = go
239239 goInstance d dictName deps className tys rest
240240 go (d@(ExternInstanceDeclaration dictName deps className tys) : rest) = do
241241 goInstance d dictName deps className tys rest
242− go (PositionedDeclaration pos d : rest) =
242+ go (PositionedDeclaration pos com d : rest) =
243243 rethrowWithPosition pos $ do
244244 (d' : rest') <- go (d : rest)
245− return (PositionedDeclaration pos d' : rest')
245+ return (PositionedDeclaration pos com d' : rest')
246246 goInstance :: Declaration -> Ident -> [Constraint] -> Qualified ProperName -> [Type] -> [Declaration] -> Check [Declaration]
247247 goInstance d dictName deps className tys rest = do
248248 mapM_ (checkTypeClassInstance moduleName) tys
@@ -258,7 +258,7 @@ typeCheckAll mainModuleName moduleName exps = go
258258
259259 exportsInstance :: DeclarationRef -> Bool
260260 exportsInstance (TypeInstanceRef name) | name == dictName = True
261− exportsInstance (PositionedDeclarationRef _ r) = exportsInstance r
261+ exportsInstance (PositionedDeclarationRef _ _ r) = exportsInstance r
262262 exportsInstance _ = False
263263
264264 -- |
@@ -346,10 +346,10 @@ typeCheckModule mainModuleName (Module mn decls (Just exps)) = do
346346 runValueRef _ = error "non-ValueRef passed to runValueRef"
347347 findClassMembers :: Declaration -> Maybe [Ident]
348348 findClassMembers (TypeClassDeclaration name' _ _ ds) | name == name' = Just $ map extractMemberName ds
349− findClassMembers (PositionedDeclaration _ d) = findClassMembers d
349+ findClassMembers (PositionedDeclaration _ _ d) = findClassMembers d
350350 findClassMembers _ = Nothing
351351 extractMemberName :: Declaration -> Ident
352− extractMemberName (PositionedDeclaration _ d) = extractMemberName d
352+ extractMemberName (PositionedDeclaration _ _ d) = extractMemberName d
353353 extractMemberName (TypeDeclaration memberName _) = memberName
354354 extractMemberName _ = error "Unexpected declaration in typeclass member list"
355355 checkClassMembersAreExported _ = return ()
src/Language/PureScript/TypeChecker/Entailment.hs+25−4
@@ -20,13 +20,15 @@ module Language.PureScript.TypeChecker.Entailment (
2020import Data.Function (on)
2121import Data.List
2222import Data.Maybe (maybeToList)
23+import Data.Foldable (foldMap)
2324import qualified Data.Map as M
2425
2526import Control.Applicative
2627import Control.Arrow (Arrow(..))
27−import Control.Monad.Error
28+import Control.Monad.Except
2829
2930import Language.PureScript.AST
31+import Language.PureScript.Errors
3032import Language.PureScript.Environment
3133import Language.PureScript.Names
3234import Language.PureScript.Pretty
@@ -199,13 +201,32 @@ entails env moduleName context = solve (sortedNubBy canonicalizeDictionary (filt
199201-- and return a substitution from type variables to types which makes the type heads unify.
200202--
201203typeHeadsAreEqual :: ModuleName -> Environment -> Type -> Type -> Maybe [(String, Type)]
202−typeHeadsAreEqual _ _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []
203−typeHeadsAreEqual _ _ t (TypeVar v) = Just [(v, t)]
204+typeHeadsAreEqual _ _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []
205+typeHeadsAreEqual _ _ t (TypeVar v) = Just [(v, t)]
204206typeHeadsAreEqual _ _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []
205−typeHeadsAreEqual m e (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m e h1 h2 <*> typeHeadsAreEqual m e t1 t2
207+typeHeadsAreEqual m e (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m e h1 h2
208+ <*> typeHeadsAreEqual m e t1 t2
206209typeHeadsAreEqual m e (SaturatedTypeSynonym name args) t2 = case expandTypeSynonym' e name args of
207210 Left _ -> Nothing
208211 Right t1 -> typeHeadsAreEqual m e t1 t2
212+typeHeadsAreEqual _ _ REmpty REmpty = Just []
213+typeHeadsAreEqual m e r1@(RCons _ _ _) r2@(RCons _ _ _) =
214+ let (s1, r1') = rowToList r1
215+ (s2, r2') = rowToList r2
216+
217+ int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
218+ sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
219+ sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]
220+ in (++) <$> foldMap (\(t1, t2) -> typeHeadsAreEqual m e t1 t2) int
221+ <*> go sd1 r1' sd2 r2'
222+ where
223+ go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Maybe [(String, Type)]
224+ go [] REmpty [] REmpty = Just []
225+ go [] (TUnknown _) _ _ = Just []
226+ go [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = Just []
227+ go [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = Just []
228+ go sd r [] (TypeVar v) = Just [(v, rowFromList (sd, r))]
229+ go _ _ _ _ = Nothing
209230typeHeadsAreEqual _ _ _ _ = Nothing
210231
211232-- |
src/Language/PureScript/TypeChecker/Kinds.hs+72−46
@@ -14,21 +14,23 @@
1414-----------------------------------------------------------------------------
1515
1616{-# OPTIONS_GHC -fno-warn-orphans #-}
17−{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
17+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TupleSections #-}
1818
1919module Language.PureScript.TypeChecker.Kinds (
2020 kindOf,
21+ kindOfWithScopedVars,
2122 kindsOf,
2223 kindsOfAll
2324) where
2425
2526import Data.Maybe (fromMaybe)
26−import Data.Monoid ((<>))
27+
2728import qualified Data.HashMap.Strict as H
2829import qualified Data.Map as M
2930
31+import Control.Arrow (second)
3032import Control.Applicative
31−import Control.Monad.Error
33+import Control.Monad.Except
3234import Control.Monad.State
3335import Control.Monad.Unify
3436
@@ -69,11 +71,19 @@ instance Unifiable Check Kind where
6971-- Infer the kind of a single type
7072--
7173kindOf :: ModuleName -> Type -> Check Kind
72−kindOf _ ty =
73− rethrow (mkErrorStack "Error checking kind" (Just (TypeError ty)) <>) $
74− fmap (starIfUnknown . tidyUp) . liftUnify $ infer ty
74+kindOf _ ty = fst <$> kindOfWithScopedVars ty
75+
76+-- |
77+-- Infer the kind of a single type, returning the kinds of any scoped type variables
78+--
79+kindOfWithScopedVars :: Type -> Check (Kind, [(String, Kind)])
80+kindOfWithScopedVars ty =
81+ rethrow (mkCompileError "Error checking kind" (Just (TypeError ty)) `combineErrors`) $
82+ fmap tidyUp . liftUnify $ infer ty
7583 where
76− tidyUp (k, sub) = sub $? k
84+ tidyUp ((k, args), sub) = ( starIfUnknown (sub $? k)
85+ , map (second (starIfUnknown . (sub $?))) args
86+ )
7787
7888-- |
7989-- Infer the kind of a type constructor with a collection of arguments and a collection of associated data constructors
@@ -125,7 +135,7 @@ kindsOfAll moduleName syns tys = fmap tidyUp . liftUnify $ do
125135--
126136solveTypes :: Bool -> [Type] -> [Kind] -> Kind -> UnifyT Kind Check Kind
127137solveTypes isData ts kargs tyCon = do
128− ks <- mapM infer ts
138+ ks <- mapM (fmap fst . infer) ts
129139 when isData $ do
130140 tyCon =?= foldr FunKind Star kargs
131141 forM_ ks $ \k -> k =?= Star
@@ -145,48 +155,64 @@ starIfUnknown k = k
145155-- |
146156-- Infer a kind for a type
147157--
148−infer :: Type -> UnifyT Kind Check Kind
149−infer ty = rethrow (mkErrorStack "Error inferring type of value" (Just (TypeError ty)) <>) $ infer' ty
158+infer :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
159+infer ty = rethrow (mkCompileError "Error inferring type of value" (Just (TypeError ty)) `combineErrors`) $ infer' ty
150160
151−infer' :: Type -> UnifyT Kind Check Kind
152−infer' TypeWildcard = fresh
153−infer' (TypeVar v) = do
154− Just moduleName <- checkCurrentModule <$> get
155− UnifyT . lift $ lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
156−infer' c@(TypeConstructor v) = do
157− env <- liftCheck getEnv
158− case M.lookup v (types env) of
159− Nothing -> UnifyT . lift . throwError $ mkErrorStack "Unknown type constructor" (Just (TypeError c))
160− Just (kind, _) -> return kind
161−infer' (TypeApp t1 t2) = do
162− k0 <- fresh
163− k1 <- infer t1
164− k2 <- infer t2
165− k1 =?= FunKind k2 k0
166− return k0
161+infer' :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
167162infer' (ForAll ident ty _) = do
168163 k1 <- fresh
169164 Just moduleName <- checkCurrentModule <$> get
170− k2 <- bindLocalTypeVariables moduleName [(ProperName ident, k1)] $ infer ty
165+ (k2, args) <- bindLocalTypeVariables moduleName [(ProperName ident, k1)] $ infer ty
171166 k2 =?= Star
172− return Star
173−infer' REmpty = do
174− k <- fresh
175− return $ Row k
176−infer' (RCons _ ty row) = do
177− k1 <- infer ty
178− k2 <- infer row
179− k2 =?= Row k1
180− return $ Row k1
181−infer' (ConstrainedType deps ty) = do
182− forM_ deps $ \(className, tys) -> do
183− _ <- infer $ foldl TypeApp (TypeConstructor className) tys
184− return ()
185− k <- infer ty
186− k =?= Star
187− return Star
167+ return (Star, (ident, k1) : args)
188168infer' (KindedType ty k) = do
189− k' <- infer ty
169+ (k', args) <- infer ty
190170 k =?= k'
191− return k'
192−infer' _ = error "Invalid argument to infer"
171+ return (k', args)
172+infer' other = (, []) <$> go other
173+ where
174+ go :: Type -> UnifyT Kind Check Kind
175+ go (ForAll ident ty _) = do
176+ k1 <- fresh
177+ Just moduleName <- checkCurrentModule <$> get
178+ k2 <- bindLocalTypeVariables moduleName [(ProperName ident, k1)] $ go ty
179+ k2 =?= Star
180+ return Star
181+ go (KindedType ty k) = do
182+ k' <- go ty
183+ k =?= k'
184+ return k'
185+ go TypeWildcard = fresh
186+ go (TypeVar v) = do
187+ Just moduleName <- checkCurrentModule <$> get
188+ UnifyT . lift $ lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
189+ go (Skolem v _ _) = do
190+ Just moduleName <- checkCurrentModule <$> get
191+ UnifyT . lift $ lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
192+ go c@(TypeConstructor v) = do
193+ env <- liftCheck getEnv
194+ case M.lookup v (types env) of
195+ Nothing -> UnifyT . lift . throwError $ mkErrorStack "Unknown type constructor" (Just (TypeError c))
196+ Just (kind, _) -> return kind
197+ go (TypeApp t1 t2) = do
198+ k0 <- fresh
199+ k1 <- go t1
200+ k2 <- go t2
201+ k1 =?= FunKind k2 k0
202+ return k0
203+ go REmpty = do
204+ k <- fresh
205+ return $ Row k
206+ go (RCons _ ty row) = do
207+ k1 <- go ty
208+ k2 <- go row
209+ k2 =?= Row k1
210+ return $ Row k1
211+ go (ConstrainedType deps ty) = do
212+ forM_ deps $ \(className, tys) -> do
213+ _ <- go $ foldl TypeApp (TypeConstructor className) tys
214+ return ()
215+ k <- go ty
216+ k =?= Star
217+ return Star
218+ go _ = error "Invalid argument to infer"
src/Language/PureScript/TypeChecker/Monad.hs+20−11
@@ -14,7 +14,7 @@
1414-----------------------------------------------------------------------------
1515
1616{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleInstances, RankNTypes,
17− MultiParamTypeClasses, FlexibleContexts #-}
17+ MultiParamTypeClasses, FlexibleContexts, GADTs #-}
1818
1919module Language.PureScript.TypeChecker.Monad where
2020
@@ -22,7 +22,8 @@ import Data.Maybe
2222import qualified Data.Map as M
2323
2424import Control.Applicative
25−import Control.Monad.Error
25+import Control.Monad.Except
26+import Control.Monad.Reader.Class
2627import Control.Monad.State
2728import Control.Monad.Unify
2829
@@ -56,6 +57,12 @@ bindTypes newNames action = do
5657 modify $ \st -> st { checkEnv = (checkEnv st) { types = types . checkEnv $ orig } }
5758 return a
5859
60+-- |
61+-- Temporarily bind a collection of names to types
62+--
63+withScopedTypeVars :: (Functor m, MonadState CheckState m) => ModuleName -> [(String, Kind)] -> m a -> m a
64+withScopedTypeVars mn ks = bindTypes (M.fromList (map (\(name, k) -> (Qualified (Just mn) (ProperName name), (k, ScopedTypeVar))) ks))
65+
5966-- |
6067-- Temporarily make a collection of type class dictionaries available
6168--
@@ -102,7 +109,7 @@ makeBindingGroupVisible action = do
102109-- |
103110-- Lookup the type of a value by name in the @Environment@
104111--
105−lookupVariable :: (Error e, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified Ident -> m Type
112+lookupVariable :: (e ~ ErrorStack, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified Ident -> m Type
106113lookupVariable currentModule (Qualified moduleName var) = do
107114 env <- getEnv
108115 case M.lookup (fromMaybe currentModule moduleName, var) (names env) of
@@ -112,7 +119,7 @@ lookupVariable currentModule (Qualified moduleName var) = do
112119-- |
113120-- Lookup the visibility of a value by name in the @Environment@
114121--
115−getVisibility :: (Error e, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified Ident -> m NameVisibility
122+getVisibility :: (e ~ ErrorStack, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified Ident -> m NameVisibility
116123getVisibility currentModule (Qualified moduleName var) = do
117124 env <- getEnv
118125 case M.lookup (fromMaybe currentModule moduleName, var) (names env) of
@@ -122,7 +129,7 @@ getVisibility currentModule (Qualified moduleName var) = do
122129-- |
123130-- Assert that a name is visible
124131--
125−checkVisibility :: (Error e, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified Ident -> m ()
132+checkVisibility :: (e ~ ErrorStack, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified Ident -> m ()
126133checkVisibility currentModule name@(Qualified _ var) = do
127134 vis <- getVisibility currentModule name
128135 case vis of
@@ -132,7 +139,7 @@ checkVisibility currentModule name@(Qualified _ var) = do
132139-- |
133140-- Lookup the kind of a type by name in the @Environment@
134141--
135−lookupTypeVariable :: (Error e, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified ProperName -> m Kind
142+lookupTypeVariable :: (e ~ ErrorStack, Functor m, MonadState CheckState m, MonadError e m) => ModuleName -> Qualified ProperName -> m Kind
136143lookupTypeVariable currentModule (Qualified moduleName name) = do
137144 env <- getEnv
138145 case M.lookup (Qualified (Just $ fromMaybe currentModule moduleName) name) (types env) of
@@ -165,7 +172,7 @@ data CheckState = CheckState {
165172-- The type checking monad, which provides the state of the type checker, and error reporting capabilities
166173--
167174newtype Check a = Check { unCheck :: StateT CheckState (Either ErrorStack) a }
168− deriving (Functor, Monad, Applicative, Alternative, MonadPlus, MonadState CheckState, MonadError ErrorStack)
175+ deriving (Functor, Monad, Applicative, MonadState CheckState, MonadError ErrorStack)
169176
170177-- |
171178-- Get the current @Environment@
@@ -188,14 +195,16 @@ modifyEnv f = modify (\s -> s { checkEnv = f (checkEnv s) })
188195-- |
189196-- Run a computation in the Check monad, starting with an empty @Environment@
190197--
191−runCheck :: Options mode -> Check a -> Either String (a, Environment)
192−runCheck opts = runCheck' opts initEnvironment
198+runCheck :: (MonadReader (Options mode) m, MonadError String m) => Check a -> m (a, Environment)
199+runCheck = runCheck' initEnvironment
193200
194201-- |
195202-- Run a computation in the Check monad, failing with an error, or succeeding with a return value and the final @Environment@.
196203--
197−runCheck' :: Options mode -> Environment -> Check a -> Either String (a, Environment)
198−runCheck' opts env c = stringifyErrorStack (optionsVerboseErrors opts) $ do
204+runCheck' :: (MonadReader (Options mode) m, MonadError String m) => Environment -> Check a -> m (a, Environment)
205+runCheck' env c = do
206+ verbose <- asks optionsVerboseErrors
207+ stringifyErrorStack verbose $ do
199208 (a, s) <- flip runStateT (CheckState env 0 0 Nothing) $ unCheck c
200209 return (a, checkEnv s)
201210
src/Language/PureScript/TypeChecker/Rows.hs+1−1
@@ -19,7 +19,7 @@ module Language.PureScript.TypeChecker.Rows (
1919
2020import Data.List
2121
22−import Control.Monad.Error
22+import Control.Monad.Except
2323
2424import Language.PureScript.AST
2525import Language.PureScript.Errors
src/Language/PureScript/TypeChecker/Skolems.hs+2−1
@@ -26,7 +26,7 @@ import Data.List (nub, (\\))
2626import Data.Monoid
2727
2828import Control.Applicative
29−import Control.Monad.Error
29+import Control.Monad.Except
3030import Control.Monad.Unify
3131
3232import Language.PureScript.AST
@@ -71,6 +71,7 @@ skolemizeTypesInValue :: String -> Int -> SkolemScope -> Expr -> Expr
7171skolemizeTypesInValue ident sko scope = let (_, f, _) = everywhereOnValues id go id in f
7272 where
7373 go (SuperClassDictionary c ts) = SuperClassDictionary c (map (skolemize ident sko scope) ts)
74+ go (TypedValue check val ty) = TypedValue check val (skolemize ident sko scope ty)
7475 go other = other
7576
7677-- |
src/Language/PureScript/TypeChecker/Subsumption.hs+2−3
@@ -18,11 +18,10 @@ module Language.PureScript.TypeChecker.Subsumption (
1818) where
1919
2020import Data.List (sortBy)
21−import Data.Monoid
2221import Data.Ord (comparing)
2322
2423import Control.Applicative
25−import Control.Monad.Error
24+import Control.Monad.Except
2625import Control.Monad.Unify
2726
2827import Language.PureScript.AST
@@ -39,7 +38,7 @@ import Language.PureScript.Types
3938-- Check whether one type subsumes another, rethrowing errors to provide a better error message
4039--
4140subsumes :: Maybe Expr -> Type -> Type -> UnifyT Type Check (Maybe Expr)
42−subsumes val ty1 ty2 = rethrow (mkErrorStack errorMessage (ExprError <$> val) <>) $ subsumes' val ty1 ty2
41+subsumes val ty1 ty2 = rethrow (mkCompileError errorMessage (ExprError <$> val) `combineErrors`) $ subsumes' val ty1 ty2
4342 where
4443 errorMessage = "Error checking that type "
4544 ++ prettyPrintType ty1
src/Language/PureScript/TypeChecker/Synonyms.hs+6−5
@@ -13,7 +13,7 @@
1313--
1414-----------------------------------------------------------------------------
1515
16−{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses #-}
16+{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, GADTs #-}
1717
1818module Language.PureScript.TypeChecker.Synonyms (
1919 saturateAllTypeSynonyms,
@@ -28,10 +28,11 @@ import Data.Maybe (fromMaybe)
2828import qualified Data.Map as M
2929
3030import Control.Applicative
31−import Control.Monad.Error
31+import Control.Monad.Except
3232import Control.Monad.State
3333
3434import Language.PureScript.Environment
35+import Language.PureScript.Errors
3536import Language.PureScript.Names
3637import Language.PureScript.TypeChecker.Monad
3738import Language.PureScript.Types
@@ -82,7 +83,7 @@ replaceAllTypeSynonyms' env d =
8283 in
8384 saturateAllTypeSynonyms syns d
8485
85−replaceAllTypeSynonyms :: (Error e, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
86+replaceAllTypeSynonyms :: (e ~ ErrorStack, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
8687replaceAllTypeSynonyms d = do
8788 env <- getEnv
8889 either (throwError . strMsg) return $ replaceAllTypeSynonyms' env d
@@ -98,12 +99,12 @@ expandTypeSynonym' env name args =
9899 replaceAllTypeSynonyms' env repl
99100 Nothing -> error "Type synonym was not defined"
100101
101−expandTypeSynonym :: (Error e, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Qualified ProperName -> [Type] -> m Type
102+expandTypeSynonym :: (e ~ ErrorStack, Functor m, Monad m, MonadState CheckState m, MonadError e m) => Qualified ProperName -> [Type] -> m Type
102103expandTypeSynonym name args = do
103104 env <- getEnv
104105 either (throwError . strMsg) return $ expandTypeSynonym' env name args
105106
106−expandAllTypeSynonyms :: (Error e, Functor m, Applicative m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
107+expandAllTypeSynonyms :: (e ~ ErrorStack, Functor m, Applicative m, Monad m, MonadState CheckState m, MonadError e m) => Type -> m Type
107108expandAllTypeSynonyms = everywhereOnTypesTopDownM go
108109 where
109110 go (SaturatedTypeSynonym name args) = expandTypeSynonym name args
src/Language/PureScript/TypeChecker/Types.hs+41−42
@@ -13,7 +13,7 @@
1313--
1414-----------------------------------------------------------------------------
1515
16−{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses #-}
16+{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, OverloadedStrings #-}
1717
1818module Language.PureScript.TypeChecker.Types (
1919 typesOf
@@ -38,11 +38,11 @@ module Language.PureScript.TypeChecker.Types (
3838import Data.Either (lefts, rights)
3939import Data.List
4040import Data.Maybe (fromMaybe)
41−import Data.Monoid
4241import qualified Data.Map as M
42+import Data.String (IsString)
4343
4444import Control.Applicative
45−import Control.Monad.Error
45+import Control.Monad.Except
4646import Control.Monad.State
4747import Control.Monad.Unify
4848
@@ -52,6 +52,7 @@ import Language.PureScript.Errors
5252import Language.PureScript.Kinds
5353import Language.PureScript.Names
5454import Language.PureScript.Pretty
55+import Language.PureScript.Traversals
5556import Language.PureScript.TypeChecker.Entailment
5657import Language.PureScript.TypeChecker.Kinds
5758import Language.PureScript.TypeChecker.Monad
@@ -128,16 +129,16 @@ typeDictionaryForBindingGroup moduleName vals = do
128129 return (untyped, typed, dict, untypedDict)
129130
130131checkTypedBindingGroupElement :: ModuleName -> (Ident, (Expr, Type, Bool)) -> TypeData -> UnifyT Type Check (Ident, (Expr, Type))
131−checkTypedBindingGroupElement moduleName (ident, (val', ty, checkType)) dict = do
132+checkTypedBindingGroupElement mn (ident, (val', ty, checkType)) dict = do
132133 -- Replace type wildcards
133134 ty' <- replaceTypeWildcards ty
134135 -- Kind check
135− kind <- liftCheck $ kindOf moduleName ty
136− guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
136+ (kind, args) <- liftCheck $ kindOfWithScopedVars ty
137+ checkTypeKind kind
137138 -- Check the type with the new names in scope
138139 ty'' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty'
139140 val'' <- if checkType
140− then bindNames dict $ TypedValue True <$> check val' ty'' <*> pure ty''
141+ then withScopedTypeVars mn args $ bindNames dict $ TypedValue True <$> check val' ty'' <*> pure ty''
141142 else return (TypedValue False val' ty'')
142143 return (ident, (val'', ty''))
143144
@@ -182,10 +183,8 @@ replaceTypeClassDictionaries mn =
182183-- |
183184-- Check the kind of a type, failing if it is not of kind *.
184185--
185−checkTypeKind :: ModuleName -> Type -> UnifyT t Check ()
186−checkTypeKind moduleName ty = do
187− kind <- liftCheck $ kindOf moduleName ty
188− guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
186+checkTypeKind :: Kind -> UnifyT t Check ()
187+checkTypeKind kind = guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
189188
190189-- |
191190-- Remove any ForAlls and ConstrainedType constructors in a type by introducing new unknowns
@@ -208,7 +207,7 @@ instantiatePolyTypeWithUnknowns val ty = return (val, ty)
208207-- Infer a type for a value, rethrowing any error to provide a more useful error message
209208--
210209infer :: Expr -> UnifyT Type Check Expr
211−infer val = rethrow (mkErrorStack "Error inferring type of value" (Just (ExprError val)) <>) $ infer' val
210+infer val = rethrow (mkCompileError "Error inferring type of value" (Just (ExprError val)) `combineErrors`) $ infer' val
212211
213212-- |
214213-- Infer a type for a value
@@ -271,8 +270,8 @@ infer' v@(Constructor c) = do
271270 env <- getEnv
272271 case M.lookup c (dataConstructors env) of
273272 Nothing -> throwError . strMsg $ "Constructor " ++ show c ++ " is undefined"
274− Just (_, _, ty) -> do ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty
275− return $ TypedValue True v ty'
273+ Just (_, _, ty, _) -> do (v', ty') <- sndM (introduceSkolemScope <=< replaceAllTypeSynonyms) <=< instantiatePolyTypeWithUnknowns v $ ty
274+ return $ TypedValue True v' ty'
276275infer' (Case vals binders) = do
277276 ts <- mapM infer vals
278277 ret <- fresh
@@ -292,21 +291,23 @@ infer' (SuperClassDictionary className tys) = do
292291 return $ TypeClassDictionary False (className, tys) dicts
293292infer' (TypedValue checkType val ty) = do
294293 Just moduleName <- checkCurrentModule <$> get
295− checkTypeKind moduleName ty
294+ (kind, args) <- liftCheck $ kindOfWithScopedVars ty
295+ checkTypeKind kind
296296 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
297− val' <- if checkType then check val ty' else return val
297+ val' <- if checkType then withScopedTypeVars moduleName args (check val ty') else return val
298298 return $ TypedValue True val' ty'
299−infer' (PositionedValue pos val) = rethrowWithPosition pos $ infer' val
299+infer' (PositionedValue pos _ val) = rethrowWithPosition pos $ infer' val
300300infer' _ = error "Invalid argument to infer"
301301
302302inferLetBinding :: [Declaration] -> [Declaration] -> Expr -> (Expr -> UnifyT Type Check Expr) -> UnifyT Type Check ([Declaration], Expr)
303303inferLetBinding seen [] ret j = (,) seen <$> makeBindingGroupVisible (j ret)
304304inferLetBinding seen (ValueDeclaration ident nameKind [] (Right (tv@(TypedValue checkType val ty))) : rest) ret j = do
305305 Just moduleName <- checkCurrentModule <$> get
306− checkTypeKind moduleName ty
306+ (kind, args) <- liftCheck $ kindOfWithScopedVars ty
307+ checkTypeKind kind
307308 let dict = M.singleton (moduleName, ident) (ty, nameKind, Undefined)
308309 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
309− TypedValue _ val' ty'' <- if checkType then bindNames dict (check val ty') else return tv
310+ TypedValue _ val' ty'' <- if checkType then withScopedTypeVars moduleName args (bindNames dict (check val ty')) else return tv
310311 bindNames (M.singleton (moduleName, ident) (ty'', nameKind, Defined)) $ inferLetBinding (seen ++ [ValueDeclaration ident nameKind [] (Right (TypedValue checkType val' ty''))]) rest ret j
311312inferLetBinding seen (ValueDeclaration ident nameKind [] (Right val) : rest) ret j = do
312313 valTy <- fresh
@@ -322,9 +323,9 @@ inferLetBinding seen (BindingGroupDeclaration ds : rest) ret j = do
322323 ds2' <- forM untyped $ \e -> typeForBindingGroupElement e dict untypedDict
323324 let ds' = [(ident, LocalVariable, val') | (ident, (val', _)) <- ds1' ++ ds2']
324325 makeBindingGroupVisible $ bindNames dict $ inferLetBinding (seen ++ [BindingGroupDeclaration ds']) rest ret j
325−inferLetBinding seen (PositionedDeclaration pos d : ds) ret j = rethrowWithPosition pos $ do
326+inferLetBinding seen (PositionedDeclaration pos com d : ds) ret j = rethrowWithPosition pos $ do
326327 (d' : ds', val') <- inferLetBinding seen (d : ds) ret j
327− return (PositionedDeclaration pos d' : ds', val')
328+ return (PositionedDeclaration pos com d' : ds', val')
328329inferLetBinding _ _ _ _ = error "Invalid argument to inferLetBinding"
329330
330331-- |
@@ -354,7 +355,7 @@ inferBinder val (VarBinder name) = return $ M.singleton name val
354355inferBinder val (ConstructorBinder ctor binders) = do
355356 env <- getEnv
356357 case M.lookup ctor (dataConstructors env) of
357− Just (_, _, ty) -> do
358+ Just (_, _, ty, _) -> do
358359 (_, fn) <- instantiatePolyTypeWithUnknowns (error "Data constructor types cannot contain constraints") ty
359360 fn' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ fn
360361 go binders fn'
@@ -394,7 +395,7 @@ inferBinder val (ConsBinder headBinder tailBinder) = do
394395inferBinder val (NamedBinder name binder) = do
395396 m <- inferBinder val binder
396397 return $ M.insert name val m
397−inferBinder val (PositionedBinder pos binder) =
398+inferBinder val (PositionedBinder pos _ binder) =
398399 rethrowWithPosition pos $ inferBinder val binder
399400
400401-- |
@@ -426,7 +427,7 @@ checkBinders nvals ret (CaseAlternative binders result : bs) = do
426427-- Check the type of a value, rethrowing errors to provide a better error message
427428--
428429check :: Expr -> Type -> UnifyT Type Check Expr
429−check val ty = rethrow (mkErrorStack errorMessage (Just (ExprError val)) <>) $ check' val ty
430+check val ty = rethrow (mkCompileError errorMessage (Just (ExprError val)) `combineErrors`) $ check' val ty
430431 where
431432 errorMessage =
432433 "Error checking type of term " ++
@@ -472,7 +473,8 @@ check' (ArrayLiteral vals) t@(TypeApp a ty) = do
472473 a =?= tyArray
473474 array <- ArrayLiteral <$> forM vals (`check` ty)
474475 return $ TypedValue True array t
475−check' (Abs (Left arg) ret) ty@(TypeApp (TypeApp t argTy) retTy) | t == tyFunction = do
476+check' (Abs (Left arg) ret) ty@(TypeApp (TypeApp t argTy) retTy) = do
477+ t =?= tyFunction
476478 Just moduleName <- checkCurrentModule <$> get
477479 ret' <- makeBindingGroupVisible $ bindLocalVariables moduleName [(arg, argTy, Defined)] $ check ret retTy
478480 return $ TypedValue True (Abs (Left arg) ret') ty
@@ -505,14 +507,15 @@ check' (SuperClassDictionary className tys) _ = do
505507 return $ TypeClassDictionary False (className, tys) dicts
506508check' (TypedValue checkType val ty1) ty2 = do
507509 Just moduleName <- checkCurrentModule <$> get
508− checkTypeKind moduleName ty1
510+ (kind, args) <- liftCheck $ kindOfWithScopedVars ty1
511+ checkTypeKind kind
509512 ty1' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty1
510513 ty2' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty2
511514 val' <- subsumes (Just val) ty1' ty2'
512515 case val' of
513516 Nothing -> throwError . strMsg $ "Unable to check type subsumption"
514517 Just val'' -> do
515− val''' <- if checkType then check val'' ty2' else return val''
518+ val''' <- if checkType then withScopedTypeVars moduleName args (check val'' ty2') else return val''
516519 return $ TypedValue checkType (TypedValue True val''' ty1') ty2'
517520check' (Case vals binders) ret = do
518521 vals' <- mapM infer vals
@@ -549,7 +552,7 @@ check' (Constructor c) ty = do
549552 env <- getEnv
550553 case M.lookup c (dataConstructors env) of
551554 Nothing -> throwError . strMsg $ "Constructor " ++ show c ++ " is undefined"
552− Just (_, _, ty1) -> do
555+ Just (_, _, ty1, _) -> do
553556 repl <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty1
554557 _ <- subsumes Nothing repl ty
555558 return $ TypedValue True (Constructor c) ty
@@ -560,11 +563,11 @@ check' val ty | containsTypeSynonyms ty = do
560563 ty' <- introduceSkolemScope <=< expandAllTypeSynonyms <=< replaceTypeWildcards $ ty
561564 check val ty'
562565check' val kt@(KindedType ty kind) = do
563− guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
566+ checkTypeKind kind
564567 val' <- check' val ty
565568 return $ TypedValue True val' kt
566−check' (PositionedValue pos val) ty =
567− rethrowWithPosition pos $ check val ty
569+check' (PositionedValue pos _ val) ty =
570+ rethrowWithPosition pos $ check' val ty
568571check' val ty = throwError $ mkErrorStack ("Expr does not have type " ++ prettyPrintType ty) (Just (ExprError val))
569572
570573containsTypeSynonyms :: Type -> Bool
@@ -580,18 +583,14 @@ containsTypeSynonyms = everythingOnTypes (||) go where
580583checkProperties :: [(String, Expr)] -> Type -> Bool -> UnifyT Type Check [(String, Expr)]
581584checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
582585 go [] [] REmpty = return []
583− go [] [] u@(TUnknown _) = do u =?= REmpty
584− return []
586+ go [] [] u@(TUnknown _)
587+ | lax = return []
588+ | otherwise = do u =?= REmpty
589+ return []
585590 go [] [] Skolem{} | lax = return []
586591 go [] ((p, _): _) _ | lax = return []
587592 | otherwise = throwError $ mkErrorStack ("Object does not have property " ++ p) (Just (ExprError (ObjectLiteral ps)))
588593 go ((p,_):_) [] REmpty = throwError $ mkErrorStack ("Property " ++ p ++ " is not present in closed object type " ++ prettyPrintRow row) (Just (ExprError (ObjectLiteral ps)))
589− go ((p,v):ps') [] u@(TUnknown _) = do
590− v'@(TypedValue _ _ ty) <- infer v
591− rest <- fresh
592− u =?= RCons p ty rest
593− ps'' <- go ps' [] rest
594− return $ (p, v') : ps''
595594 go ((p,v):ps') ts r =
596595 case lookup p ts of
597596 Nothing -> do
@@ -610,7 +609,7 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
610609-- Check the type of a function application, rethrowing errors to provide a better error message
611610--
612611checkFunctionApplication :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
613−checkFunctionApplication fn fnTy arg ret = rethrow (mkErrorStack errorMessage (Just (ExprError fn)) <>) $ do
612+checkFunctionApplication fn fnTy arg ret = rethrow (mkCompileError errorMessage (Just (ExprError fn)) `combineErrors`) $ do
614613 subst <- unifyCurrentSubstitution <$> UnifyT get
615614 checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
616615 where
@@ -674,5 +673,5 @@ meet e1 e2 t1 t2 = do
674673-- |
675674-- Ensure a set of property names and value does not contain duplicate labels
676675--
677−ensureNoDuplicateProperties :: (Error e, MonadError e m) => [(String, Expr)] -> m ()
678−ensureNoDuplicateProperties ps = guardWith (strMsg "Duplicate property names") $ length (nub . map fst $ ps) == length ps
676+ensureNoDuplicateProperties :: (IsString e, MonadError e m) => [(String, Expr)] -> m ()
677+ensureNoDuplicateProperties ps = guardWith "Duplicate property names" $ length (nub . map fst $ ps) == length ps
src/Language/PureScript/TypeChecker/Unify.hs+24−4
@@ -27,10 +27,9 @@ module Language.PureScript.TypeChecker.Unify (
2727
2828import Data.List (nub, sort)
2929import Data.Maybe (fromMaybe)
30−import Data.Monoid
3130import qualified Data.HashMap.Strict as H
3231
33−import Control.Monad.Error
32+import Control.Monad.Except
3433import Control.Monad.Unify
3534
3635import Language.PureScript.Environment
@@ -61,7 +60,7 @@ instance Unifiable Check Type where
6160-- Unify two types, updating the current substitution
6261--
6362unifyTypes :: Type -> Type -> UnifyT Type Check ()
64−unifyTypes t1 t2 = rethrow (mkErrorStack ("Error unifying type " ++ prettyPrintType t1 ++ " with type " ++ prettyPrintType t2) Nothing <>) $
63+unifyTypes t1 t2 = rethrow (mkCompileError ("Error unifying type " ++ prettyPrintType t1 ++ " with type " ++ prettyPrintType t2) Nothing `combineErrors`) $
6564 unifyTypes' t1 t2
6665 where
6766 unifyTypes' (TUnknown u1) (TUnknown u2) | u1 == u2 = return ()
@@ -130,6 +129,10 @@ unifyRows r1 r2 =
130129 rest <- fresh
131130 u1 =:= rowFromList (sd2, rest)
132131 u2 =:= rowFromList (sd1, rest)
132+ unifyRows' sd1 (SaturatedTypeSynonym name args) sd2 r2' = do
133+ r1' <- expandTypeSynonym name $ args
134+ unifyRows (rowFromList (sd1, r1')) (rowFromList (sd2, r2'))
135+ unifyRows' sd1 r1' sd2 r2'@(SaturatedTypeSynonym _ _) = unifyRows' sd2 r2' sd1 r1'
133136 unifyRows' [] REmpty [] REmpty = return ()
134137 unifyRows' [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = return ()
135138 unifyRows' [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = return ()
@@ -149,6 +152,23 @@ unifiesWith e (SaturatedTypeSynonym name args) t2 =
149152 Left _ -> False
150153 Right t1 -> unifiesWith e t1 t2
151154unifiesWith e t1 t2@(SaturatedTypeSynonym _ _) = unifiesWith e t2 t1
155+unifiesWith _ REmpty REmpty = True
156+unifiesWith e r1@(RCons _ _ _) r2@(RCons _ _ _) =
157+ let (s1, r1') = rowToList r1
158+ (s2, r2') = rowToList r2
159+
160+ int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
161+ sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
162+ sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]
163+ in all (\(t1, t2) -> unifiesWith e t1 t2) int && go sd1 r1' sd2 r2'
164+ where
165+ go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Bool
166+ go [] REmpty [] REmpty = True
167+ go [] (TypeVar v1) [] (TypeVar v2) = v1 == v2
168+ go [] (Skolem _ s1 _) [] (Skolem _ s2 _) = s1 == s2
169+ go _ (TUnknown _) _ _ = True
170+ go _ _ _ (TUnknown _) = True
171+ go _ _ _ _ = False
152172unifiesWith _ _ _ = False
153173
154174-- |
@@ -158,7 +178,7 @@ replaceVarWithUnknown :: String -> Type -> UnifyT Type Check Type
158178replaceVarWithUnknown ident ty = do
159179 tu <- fresh
160180 return $ replaceTypeVars ident tu ty
161−
181+
162182-- |
163183-- Replace type wildcards with unknowns
164184--
tests/Main.hs+6−6
@@ -22,24 +22,24 @@ import Data.List (isSuffixOf)
2222import Data.Traversable (traverse)
2323import Control.Monad
2424import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
25+import Control.Monad.Reader (runReaderT)
2526import Control.Applicative
2627import System.Exit
2728import System.Process
2829import System.FilePath (pathSeparator)
2930import System.Directory (getCurrentDirectory, getTemporaryDirectory, getDirectoryContents, findExecutable)
3031import Text.Parsec (ParseError)
31−import qualified System.IO.UTF8 as U
3232
3333readInput :: [FilePath] -> IO [(FilePath, String)]
3434readInput inputFiles = forM inputFiles $ \inputFile -> do
35− text <- U.readFile inputFile
35+ text <- readFile inputFile
3636 return (inputFile, text)
3737
3838loadPrelude :: Either String (String, String, P.Environment)
39−loadPrelude =
39+loadPrelude =
4040 case P.parseModulesFromFiles id [("", P.prelude)] of
4141 Left parseError -> Left (show parseError)
42− Right ms -> P.compile (P.defaultCompileOptions { P.optionsAdditional = P.CompileOptions "Tests" [] [] }) (map snd ms) []
42+ Right ms -> runReaderT (P.compile (map snd ms) []) $ P.defaultCompileOptions { P.optionsAdditional = P.CompileOptions "Tests" [] [] }
4343
4444compile :: P.Options P.Compile -> [FilePath] -> IO (Either String (String, String, P.Environment))
4545compile opts inputFiles = do
@@ -47,7 +47,7 @@ compile opts inputFiles = do
4747 case modules of
4848 Left parseError ->
4949 return (Left $ show parseError)
50− Right ms -> return $ P.compile opts (map snd ms) []
50+ Right ms -> return $ runReaderT (P.compile (map snd ms) []) opts
5151
5252assert :: FilePath -> P.Options P.Compile -> FilePath -> (Either String (String, String, P.Environment) -> IO (Maybe String)) -> IO ()
5353assert preludeExterns opts inputFile f = do
@@ -86,7 +86,7 @@ findNodeProcess = runMaybeT . msum $ map (MaybeT . findExecutable) names
8686
8787main :: IO ()
8888main = do
89− putStrLn "Compiling Prelude"
89+ putStrLn "Compiling Prelude"
9090 case loadPrelude of
9191 Left err -> putStrLn err >> exitFailure
9292 Right (preludeJs, exts, _) -> do