git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge remote-tracking branch 'origin/master' into corefn-class-repr

Conflicts: src/Language/PureScript/CodeGen/JS.hs src/Language/PureScript/TypeChecker/Types.hs

commit945660d0afe553147f22c40220e766023b0b15bd authorGary Burgess <gary.burgess@gmail.com> dateTue 17 Feb 2015, 21:53 (12 years ago) parent100acfad844d14
145 files changed+1879−760
LICENSE+35−35 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/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/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+15−9 examples/passing/OperatorSections.purs+21 examples/passing/Operators.purs+11−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 prelude/README.md+343−33 prelude/images/Prelude.png prelude/prelude.purs+62−17 prelude/updateDocs.sh+1−1 psc-docs/Main.hs+72−37 psc-make/Main.hs+27−20 psc/Main.hs+22−14 psci/Commands.hs+1−1 psci/Main.hs+40−30 psci/Parser.hs+5−5 purescript.cabal+4−3 src/Language/PureScript.hs+40−35 src/Language/PureScript/AST/Declarations.hs+21−1 src/Language/PureScript/AST/SourcePos.hs+2−2 src/Language/PureScript/AST/Traversals.hs+32−8 src/Language/PureScript/CodeGen/Externs.hs+10−3 src/Language/PureScript/CodeGen/JS.hs+48−30 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+2−2 src/Language/PureScript/Constants.hs+15 src/Language/PureScript/CoreFn/Ann.hs+1−1 src/Language/PureScript/CoreFn/Binders.hs+2−1 src/Language/PureScript/CoreFn/Expr.hs+12−2 src/Language/PureScript/CoreFn/Literals.hs+2−1 src/Language/PureScript/Environment.hs+6−1 src/Language/PureScript/Errors.hs+2−2 src/Language/PureScript/ModuleDependencies.hs+7−4 src/Language/PureScript/Options.hs+5−2 src/Language/PureScript/Parser.hs+1−1 src/Language/PureScript/Parser/Common.hs−6 src/Language/PureScript/Parser/Declarations.hs+37−9 src/Language/PureScript/Parser/Lexer.hs+38−30 src/Language/PureScript/Parser/Types.hs+1−1 src/Language/PureScript/Pretty/JS.hs+4−4 src/Language/PureScript/Pretty/Types.hs+1−1 src/Language/PureScript/Pretty/Values.hs+36−27 src/Language/PureScript/Sugar.hs+19−10 src/Language/PureScript/Sugar/BindingGroups.hs+3−3 src/Language/PureScript/Sugar/Names.hs+41−15 src/Language/PureScript/Sugar/ObjectWildcards.hs+61 src/Language/PureScript/Sugar/Operators.hs+25−10 src/Language/PureScript/TypeChecker.hs+1−1 src/Language/PureScript/TypeChecker/Entailment.hs+23−3 src/Language/PureScript/TypeChecker/Kinds.hs+69−42 src/Language/PureScript/TypeChecker/Monad.hs+13−4 src/Language/PureScript/TypeChecker/Skolems.hs+1 src/Language/PureScript/TypeChecker/Types.hs+24−26 src/Language/PureScript/TypeChecker/Unify.hs+22−1 tests/Main.hs+5−4
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,
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/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/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+15−9
@@ -6,20 +6,26 @@ import Debug.Trace
66foreign import data Assert :: !
77
88foreign import assert
9− "function assert(x) { return function (desc) {\
10− \ return function () {\
11− \ if (!x) throw new Error('assertion (' + desc + ') failed');\
12− \ return {};\
13− \ };\
14− \};};" :: forall e. Boolean -> String -> Eff (assert :: Assert | e) Unit
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
1519
1620bug :: Number -> Number -> Number
1721bug a b = 0 - (a - b)
1822
1923foreign import explode
20− "function explode() {\
21− \ throw new Error('Assertion failed!');\
22− \}":: forall eff a. Eff eff a
24+ """
25+ function explode() {
26+ throw new Error('Assertion failed!');
27+ }
28+ """ :: forall eff a. Eff eff a
2329
2430main = do
2531 assert (bug 0 2 == 2) "bug 0 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+11−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,7 +61,7 @@ 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
6767 test17 :: Number
@@ -73,6 +73,11 @@ module Main where
7373 test19 :: Number
7474 test19 = negate $ negate (-1)
7575
76+ test20 :: Number
77+ test20 = 1 @ 2
78+ where
79+ (@) x y = x + y * y
80+
7681 main = do
7782 let t1 = test1 1 2 (\x y -> x + y)
7883 let t2 = test2
@@ -93,4 +98,5 @@ module Main where
9398 let t17 = test17
9499 let t18 = test18
95100 let t19 = test19
101+ let t20 = test20
96102 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"
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+62−17
@@ -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
@@ -188,13 +210,32 @@ module Prelude
188210 infixl 6 -
189211 infixl 6 +
190212
191− class Num a where
192− (+) :: a -> a -> a
193− (-) :: a -> a -> a
194− (*) :: 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
195223 (/) :: a -> a -> a
196− (%) :: a -> a -> a
197− negate :: a -> a
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
198239
199240 foreign import numAdd
200241 """
@@ -241,20 +282,24 @@ module Prelude
241282 }
242283 """ :: Number -> Number -> Number
243284
244− foreign import numNegate
245− """
246− function numNegate(n) {
247− return -n;
248− }
249− """ :: Number -> Number
285+ (%) = numMod
250286
251− instance numNumber :: Num Number where
287+ instance semiringNumber :: Semiring Number where
252288 (+) = numAdd
253− (-) = numSub
289+ zero = 0
254290 (*) = numMul
291+ one = 1
292+
293+ instance ringNumber :: Ring Number where
294+ (-) = numSub
295+
296+ instance moduloSemiringNumber :: ModuloSemiring Number where
255297 (/) = numDiv
256− (%) = numMod
257− negate = numNegate
298+ mod _ _ = 0
299+
300+ instance divisionRingNumber :: DivisionRing Number
301+
302+ instance numNumber :: Num Number
258303
259304 newtype Unit = Unit {}
260305
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+72−37
@@ -22,27 +22,26 @@ import Data.Function (on)
2222import Data.List
2323import Data.Maybe (fromMaybe)
2424import Data.Version (showVersion)
25+import Data.Foldable (traverse_)
2526
2627import Options.Applicative
2728
2829import qualified Language.PureScript as P
2930import qualified Paths_purescript as Paths
3031import System.Exit (exitSuccess, exitFailure)
31−import System.IO (hPutStr, stderr)
32−
32+import System.IO (hPutStrLn, stderr)
3333
3434data PSCDocsOptions = PSCDocsOptions
3535 { pscdIncludeHeir :: Bool
3636 , pscdInputFiles :: [FilePath]
3737 }
3838
39−
4039docgen :: PSCDocsOptions -> IO ()
4140docgen (PSCDocsOptions showHierarchy input) = do
4241 e <- P.parseModulesFromFiles (fromMaybe "") <$> mapM (fmap (first Just) . parseFile) (nub input)
4342 case e of
4443 Left err -> do
45− hPutStr stderr $ show err
44+ hPutStrLn stderr $ show err
4645 exitFailure
4746 Right ms -> do
4847 putStrLn . runDocs $ (renderModules showHierarchy) (map snd ms)
@@ -62,10 +61,16 @@ spacer = tell [""]
6261headerLevel :: Int -> String -> Docs
6362headerLevel level hdr = tell [replicate level '#' ++ ' ' : hdr]
6463
64+withIndent :: Int -> Docs -> Docs
65+withIndent indent = censor (map (replicate indent ' ' ++ ))
66+
6567atIndent :: Int -> String -> Docs
6668atIndent indent text =
6769 let ls = lines text in
68− forM_ ls $ \l -> tell [replicate indent ' ' ++ l]
70+ withIndent indent (tell ls)
71+
72+ticks :: String -> String
73+ticks = ("`" ++) . (++ "`")
6974
7075renderModules :: Bool -> [P.Module] -> Docs
7176renderModules showHierarchy ms = do
@@ -109,7 +114,9 @@ renderModule showHierarchy mdl@(P.Module moduleName _ exps) =
109114
110115renderTopLevel :: Maybe [P.DeclarationRef] -> [P.Declaration] -> Docs
111116renderTopLevel exps decls = forM_ (sortBy (compare `on` getName) decls) $ \decl -> do
112− renderDeclaration 4 exps decl
117+ traverse_ (headerLevel 4) (ticks `fmap` getDeclarationTitle decl)
118+ spacer
119+ renderDeclaration exps decl
113120 spacer
114121
115122renderTypeclassImage :: P.ModuleName -> Docs
@@ -117,53 +124,81 @@ renderTypeclassImage name =
117124 let name' = P.runModuleName name
118125 in tell ["![" ++ name' ++ "](images/" ++ name' ++ ".png)"]
119126
120−renderDeclaration :: Int -> Maybe [P.DeclarationRef] -> P.Declaration -> Docs
121−renderDeclaration n _ (P.TypeDeclaration ident ty) =
122− atIndent n $ show ident ++ " :: " ++ prettyPrintType' ty
123−renderDeclaration n _ (P.ExternDeclaration _ ident _ ty) =
124− atIndent n $ show ident ++ " :: " ++ prettyPrintType' ty
125−renderDeclaration n exps (P.DataDeclaration dtype name args ctors) = do
127+getDeclarationTitle :: P.Declaration -> Maybe String
128+getDeclarationTitle (P.TypeDeclaration name _) = Just (show name)
129+getDeclarationTitle (P.ExternDeclaration _ name _ _) = Just (show name)
130+getDeclarationTitle (P.DataDeclaration _ name _ _) = Just (show name)
131+getDeclarationTitle (P.ExternDataDeclaration name _) = Just (show name)
132+getDeclarationTitle (P.TypeSynonymDeclaration name _ _) = Just (show name)
133+getDeclarationTitle (P.TypeClassDeclaration name _ _ _) = Just (show name)
134+getDeclarationTitle (P.TypeInstanceDeclaration name _ _ _ _) = Just (show name)
135+getDeclarationTitle (P.PositionedDeclaration _ _ d) = getDeclarationTitle d
136+getDeclarationTitle _ = Nothing
137+
138+renderDeclaration :: Maybe [P.DeclarationRef] -> P.Declaration -> Docs
139+renderDeclaration _ (P.TypeDeclaration ident ty) =
140+ atIndent 4 $ show ident ++ " :: " ++ prettyPrintType' ty
141+renderDeclaration _ (P.ExternDeclaration _ ident _ ty) =
142+ atIndent 4 $ show ident ++ " :: " ++ prettyPrintType' ty
143+renderDeclaration exps (P.DataDeclaration dtype name args ctors) = do
126144 let
127145 typeApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
128146 typeName = prettyPrintType' typeApp
129147 exported = filter (P.isDctorExported name exps . fst) ctors
130− atIndent n $ show dtype ++ " " ++ typeName ++ (if null exported then "" else " where")
131− forM_ exported $ \(ctor, tys) ->
132− let ctorTy = foldr P.function typeApp tys
133− in atIndent (n + 2) $ P.runProperName ctor ++ " :: " ++ prettyPrintType' ctorTy
134−renderDeclaration n _ (P.ExternDataDeclaration name kind) =
135− atIndent n $ "data " ++ P.runProperName name ++ " :: " ++ P.prettyPrintKind kind
136−renderDeclaration n _ (P.TypeSynonymDeclaration name args ty) = do
148+ atIndent 4 $ show dtype ++ " " ++ typeName
149+ zipWithM_ (\isFirst (ctor, tys) ->
150+ atIndent 6 $ (if isFirst then "= " else "| ") ++ P.runProperName ctor ++ " " ++ unwords (map P.prettyPrintTypeAtom tys))
151+ (True : repeat False) exported
152+renderDeclaration _ (P.ExternDataDeclaration name kind) =
153+ atIndent 4 $ "data " ++ P.runProperName name ++ " :: " ++ P.prettyPrintKind kind
154+renderDeclaration _ (P.TypeSynonymDeclaration name args ty) = do
137155 let
138156 typeApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
139− typeName = prettyPrintType' typeApp
140− atIndent n $ "type " ++ typeName ++ " = " ++ prettyPrintType' ty
141−renderDeclaration n exps (P.TypeClassDeclaration name args implies ds) = do
157+ typeName = prettyPrintType' typeApp
158+ atIndent 4 $ "type " ++ typeName ++ " = " ++ prettyPrintType' ty
159+renderDeclaration _ (P.TypeClassDeclaration name args implies ds) = do
142160 let impliesText = case implies of
143161 [] -> ""
144162 is -> "(" ++ intercalate ", " (map (\(pn, tys') -> show pn ++ " " ++ unwords (map P.prettyPrintTypeAtom tys')) is) ++ ") <= "
145163 classApp = foldl P.TypeApp (P.TypeConstructor (P.Qualified Nothing name)) (map toTypeVar args)
146164 className = prettyPrintType' classApp
147− atIndent n $ "class " ++ impliesText ++ className ++ " where"
148− mapM_ (renderDeclaration (n + 2) exps) ds
149−renderDeclaration n _ (P.TypeInstanceDeclaration name constraints className tys _) = do
165+ atIndent 4 $ "class " ++ impliesText ++ className ++ " where"
166+ mapM_ renderClassMember ds
167+ where
168+ renderClassMember (P.PositionedDeclaration _ _ d) = renderClassMember d
169+ renderClassMember (P.TypeDeclaration ident ty) = atIndent 6 $ show ident ++ " :: " ++ prettyPrintType' ty
170+ renderClassMember _ = error "Invalid argument to renderClassMember."
171+renderDeclaration _ (P.TypeInstanceDeclaration name constraints className tys _) = do
150172 let constraintsText = case constraints of
151173 [] -> ""
152174 cs -> "(" ++ intercalate ", " (map (\(pn, tys') -> show pn ++ " " ++ unwords (map P.prettyPrintTypeAtom tys')) cs) ++ ") => "
153− atIndent n $ "instance " ++ show name ++ " :: " ++ constraintsText ++ show className ++ " " ++ unwords (map P.prettyPrintTypeAtom tys)
154−renderDeclaration n exps (P.PositionedDeclaration _ com d) = do
155− renderComments n com
156− spacer
157− renderDeclaration n exps d
158−renderDeclaration _ _ _ = return ()
175+ atIndent 4 $ "instance " ++ show name ++ " :: " ++ constraintsText ++ show className ++ " " ++ unwords (map P.prettyPrintTypeAtom tys)
176+renderDeclaration exps (P.PositionedDeclaration _ com d) = do
177+ renderComments com
178+ renderDeclaration exps d
179+renderDeclaration _ _ = return ()
159180
160−renderComments :: Int -> [P.Comment] -> Docs
161−renderComments n cs = mapM_ (atIndent n) ls
162− where
163− ls = concatMap toLines cs
181+renderComments :: [P.Comment] -> Docs
182+renderComments cs = do
183+ let raw = concatMap toLines cs
184+
185+ if all hasPipe raw
186+ then atIndent 0 . unlines . map stripPipes $ raw
187+ else atIndent 4 $ unlines raw
164188
189+ unless (null raw) spacer
190+ where
191+
165192 toLines (P.LineComment s) = [s]
166193 toLines (P.BlockComment s) = lines s
194+
195+ hasPipe s = case dropWhile (== ' ') s of { ('|':_) -> True; _ -> False }
196+
197+ stripPipes = dropPipe . dropWhile (== ' ')
198+
199+ dropPipe ('|':' ':s) = s
200+ dropPipe ('|':s) = s
201+ dropPipe s = s
167202
168203toTypeVar :: (String, Maybe P.Kind) -> P.Type
169204toTypeVar (s, Nothing) = P.TypeVar s
@@ -217,7 +252,7 @@ inputFile = strArgument $
217252 <> help "The input .purs file(s)"
218253
219254includeHeirarcy :: Parser Bool
220−includeHeirarcy = switch $
255+includeHeirarcy = switch $
221256 long "hierarchy-images"
222257 <> help "Include markdown for type class hierarchy images in the output."
223258
@@ -232,6 +267,6 @@ main = execParser opts >>= docgen
232267 infoModList = fullDesc <> headerInfo <> footerInfo
233268 headerInfo = header "psc-docs - Generate Markdown documentation from PureScript extern files"
234269 footerInfo = footer $ "psc-docs " ++ showVersion Paths.version
235−
270+
236271 version :: Parser (a -> a)
237272 version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
psc-make/Main.hs+27−20
@@ -18,8 +18,10 @@ module Main where
1818
1919import Control.Applicative
2020import Control.Monad.Error
21+import Control.Monad.Reader
2122
2223import Data.Version (showVersion)
24+import Data.Traversable (traverse)
2325
2426import Options.Applicative as Opts
2527
@@ -50,20 +52,19 @@ readInput InputOptions{..} = do
5052 content <- forM ioInputFiles $ \inFile -> (Right inFile, ) <$> readFile inFile
5153 return (if ioNoPrelude then content else (Left P.RebuildNever, P.prelude) : content)
5254
53−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) (ErrorT String IO) a }
56+ deriving (Functor, Applicative, Monad, MonadIO, MonadError String, MonadReader (P.Options P.Make))
5457
55−runMake :: Make a -> IO (Either String a)
56−runMake = runErrorT . unMake
58+runMake :: P.Options P.Make -> Make a -> IO (Either String a)
59+runMake opts = runErrorT . flip runReaderT opts . unMake
5760
5861makeIO :: IO a -> Make a
59−makeIO = Make . ErrorT . fmap (either (Left . show) Right) . tryIOError
62+makeIO = Make . lift . ErrorT . fmap (either (Left . show) Right) . tryIOError
6063
6164instance P.MonadMake Make where
6265 getTimestamp path = makeIO $ do
6366 exists <- doesFileExist path
64− case exists of
65− True -> Just <$> getModificationTime path
66− False -> return Nothing
67+ traverse (const $ getModificationTime path) $ guard exists
6768 readTextFile path = makeIO $ do
6869 putStrLn $ "Reading " ++ path
6970 readFile path
@@ -71,7 +72,6 @@ instance P.MonadMake Make where
7172 mkdirp path
7273 putStrLn $ "Writing " ++ path
7374 writeFile path text
74− liftError = either throwError return
7575 progress = makeIO . putStrLn
7676
7777compile :: PSCMakeOptions -> IO ()
@@ -82,7 +82,7 @@ compile (PSCMakeOptions input outputDir opts usePrefix) = do
8282 print err
8383 exitFailure
8484 Right ms -> do
85− e <- runMake $ P.make outputDir opts ms prefix
85+ e <- runMake opts $ P.make outputDir ms prefix
8686 case e of
8787 Left err -> do
8888 putStrLn err
@@ -111,12 +111,12 @@ outputDirectory = strOption $
111111 <> help "The output directory"
112112
113113noTco :: Parser Bool
114−noTco = switch $
114+noTco = switch $
115115 long "no-tco"
116116 <> help "Disable tail call optimizations"
117117
118118noPrelude :: Parser Bool
119−noPrelude = switch $
119+noPrelude = switch $
120120 long "no-prelude"
121121 <> help "Omit the Prelude"
122122
@@ -127,35 +127,42 @@ noMagicDo = switch $
127127
128128noOpts :: Parser Bool
129129noOpts = switch $
130− long "verbose-errors"
130+ long "no-opts"
131131 <> help "Skip the optimization phase."
132132
133+comments :: Parser Bool
134+comments = switch $
135+ short 'c'
136+ <> long "comments"
137+ <> help "Include comments in the generated code."
138+
133139verboseErrors :: Parser Bool
134140verboseErrors = switch $
135141 short 'v'
136− <> long "no-opts"
142+ <> long "verbose-errors"
137143 <> help "Display verbose error messages"
138144
139145noPrefix :: Parser Bool
140−noPrefix = switch $
146+noPrefix = switch $
141147 short 'p'
142148 <> long "no-prefix"
143149 <> help "Do not include comment header"
144150
145151
146152options :: Parser (P.Options P.Make)
147−options = P.Options <$> noPrelude
148− <*> noTco
153+options = P.Options <$> noPrelude
154+ <*> noTco
149155 <*> noMagicDo
150156 <*> pure Nothing
151157 <*> noOpts
158+ <*> comments
152159 <*> verboseErrors
153160 <*> pure P.MakeOptions
154161
155162pscMakeOptions :: Parser PSCMakeOptions
156−pscMakeOptions = PSCMakeOptions <$> many inputFile
157− <*> outputDirectory
158− <*> options
163+pscMakeOptions = PSCMakeOptions <$> many inputFile
164+ <*> outputDirectory
165+ <*> options
159166 <*> (not <$> noPrefix)
160167
161168main :: IO ()
@@ -165,6 +172,6 @@ main = execParser opts >>= compile
165172 infoModList = fullDesc <> headerInfo <> footerInfo
166173 headerInfo = header "psc-make - Compiles PureScript to Javascript"
167174 footerInfo = footer $ "psc-make " ++ showVersion Paths.version
168−
175+
169176 version :: Parser (a -> a)
170177 version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
psc/Main.hs+22−14
@@ -18,6 +18,7 @@ module Main where
1818
1919import Control.Applicative
2020import Control.Monad.Error
21+import Control.Monad.Reader
2122
2223import Data.Maybe (fromMaybe)
2324import Data.Version (showVersion)
@@ -26,7 +27,7 @@ import Options.Applicative as Opts
2627import System.Directory (createDirectoryIfMissing)
2728import System.FilePath (takeDirectory)
2829import System.Exit (exitSuccess, exitFailure)
29−import System.IO (hPutStr, hPutStrLn, stderr)
30+import System.IO (hPutStrLn, stderr)
3031
3132import qualified Language.PureScript as P
3233import qualified Paths_purescript as Paths
@@ -58,10 +59,10 @@ compile (PSCOptions input opts stdin output externs usePrefix) = do
5859 modules <- P.parseModulesFromFiles (fromMaybe "") <$> readInput (InputOptions (P.optionsNoPrelude opts) stdin input)
5960 case modules of
6061 Left err -> do
61− hPutStr stderr $ show err
62+ hPutStrLn stderr $ show err
6263 exitFailure
6364 Right ms -> do
64− case P.compile opts (map snd ms) prefix of
65+ case P.compile (map snd ms) prefix `runReaderT` opts of
6566 Left err -> do
6667 hPutStrLn stderr err
6768 exitFailure
@@ -115,28 +116,34 @@ runMain = optional $ noArgs <|> withArgs
115116 where
116117 defaultVal = "Main"
117118 noArgs = flag' defaultVal (long "main")
118− withArgs = strOption $
119+ withArgs = strOption $
119120 long "main"
120121 <> help (concat [
121122 "Generate code to run the main method in the specified module. ",
122123 "(no argument: \"", defaultVal, "\")"
123124 ])
124−
125+
125126noMagicDo :: Parser Bool
126127noMagicDo = switch $
127128 long "no-magic-do"
128129 <> help "Disable the optimization that overloads the do keyword to generate efficient code specifically for the Eff monad."
129−
130+
130131noTco :: Parser Bool
131−noTco = switch $
132+noTco = switch $
132133 long "no-tco"
133134 <> help "Disable tail call optimizations"
134135
135136noPrelude :: Parser Bool
136−noPrelude = switch $
137+noPrelude = switch $
137138 long "no-prelude"
138139 <> help "Omit the Prelude"
139140
141+comments :: Parser Bool
142+comments = switch $
143+ short 'c'
144+ <> long "comments"
145+ <> help "Include comments in the generated code."
146+
140147useStdIn :: Parser Bool
141148useStdIn = switch $
142149 short 's'
@@ -161,22 +168,23 @@ externsFile = optional . strOption $
161168 <> help "The output .e.purs file"
162169
163170noPrefix :: Parser Bool
164−noPrefix = switch $
171+noPrefix = switch $
165172 short 'p'
166173 <> long "no-prefix"
167174 <> help "Do not include comment header"
168175
169176options :: Parser (P.Options P.Compile)
170−options = P.Options <$> noPrelude
171− <*> noTco
177+options = P.Options <$> noPrelude
178+ <*> noTco
172179 <*> noMagicDo
173180 <*> runMain
174181 <*> noOpts
175182 <*> verboseErrors
183+ <*> comments
176184 <*> additionalOptions
177185 where
178− additionalOptions =
179− P.CompileOptions <$> browserNamespace
186+ additionalOptions =
187+ P.CompileOptions <$> browserNamespace
180188 <*> many dceModule
181189 <*> many codeGenModule
182190
@@ -195,7 +203,7 @@ main = execParser opts >>= compile
195203 infoModList = fullDesc <> headerInfo <> footerInfo
196204 headerInfo = header "psc - Compiles PureScript to Javascript"
197205 footerInfo = footer $ "psc " ++ showVersion Paths.version
198−
206+
199207 version :: Parser (a -> a)
200208 version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
201209
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+40−30
@@ -28,7 +28,7 @@ import qualified Data.Map as M
2828import Control.Applicative
2929import Control.Monad
3030import Control.Monad.Error (ErrorT(..), MonadError)
31−import Control.Monad.Error.Class (MonadError(..))
31+import Control.Monad.Reader (MonadReader, ReaderT, runReaderT)
3232import Control.Monad.Trans.Class
3333import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
3434import Control.Monad.Trans.State.Strict
@@ -69,7 +69,7 @@ data PSCiState = PSCiState
6969 { psciImportedFilenames :: [FilePath]
7070 , psciImportedModuleNames :: [P.ModuleName]
7171 , psciLoadedModules :: [(Either P.RebuildPolicy FilePath, P.Module)]
72− , psciLetBindings :: [P.Expr -> P.Expr]
72+ , psciLetBindings :: [P.Declaration]
7373 }
7474
7575-- State helpers
@@ -95,8 +95,8 @@ updateModules modules st = st { psciLoadedModules = psciLoadedModules st ++ modu
9595-- |
9696-- Updates the state to have more let bindings.
9797--
98−updateLets :: (P.Expr -> P.Expr) -> PSCiState -> PSCiState
99−updateLets name st = st { psciLetBindings = name : psciLetBindings st }
98+updateLets :: [P.Declaration] -> PSCiState -> PSCiState
99+updateLets ds st = st { psciLetBindings = ds ++ psciLetBindings st }
100100
101101-- File helpers
102102-- |
@@ -141,6 +141,16 @@ loadAllModules files = do
141141 return (Right filename, content)
142142 return $ P.parseModulesFromFiles (either (const "") id) $ (Left P.RebuildNever, P.prelude) : filesAndContent
143143
144+-- |
145+-- Load all modules, updating the application state
146+--
147+loadAllImportedModules :: PSCI ()
148+loadAllImportedModules = do
149+ files <- PSCI . lift $ fmap psciImportedFilenames get
150+ modulesOrFirstError <- psciIO $ loadAllModules files
151+ case modulesOrFirstError of
152+ Left err -> psciIO $ print err
153+ Right modules -> PSCI . lift . modify $ \st -> st { psciLoadedModules = modules }
144154
145155-- |
146156-- Expands tilde in path.
@@ -304,7 +314,7 @@ completion = completeWordWithPrev Nothing " \t\n\r" findCompletions
304314-- | Compilation options.
305315--
306316options :: P.Options P.Make
307−options = P.Options False False False Nothing False False P.MakeOptions
317+options = P.Options False False False Nothing False False False P.MakeOptions
308318
309319-- |
310320-- PSCI monad
@@ -312,27 +322,25 @@ options = P.Options False False False Nothing False False P.MakeOptions
312322newtype PSCI a = PSCI { runPSCI :: InputT (StateT PSCiState IO) a } deriving (Functor, Applicative, Monad)
313323
314324psciIO :: IO a -> PSCI a
315−psciIO io = PSCI (lift (lift io))
325+psciIO io = PSCI . lift $ lift io
316326
317−newtype Make a = Make { unMake :: ErrorT String IO a } deriving (Functor, Applicative, Monad, MonadError String)
327+newtype Make a = Make { unMake :: ReaderT (P.Options P.Make) (ErrorT String IO) a }
328+ deriving (Functor, Applicative, Monad, MonadError String, MonadReader (P.Options P.Make))
318329
319330runMake :: Make a -> IO (Either String a)
320−runMake = runErrorT . unMake
331+runMake = runErrorT . flip runReaderT options . unMake
321332
322333makeIO :: IO a -> Make a
323−makeIO = Make . ErrorT . fmap (either (Left . show) Right) . tryIOError
334+makeIO = Make . lift . ErrorT . fmap (either (Left . show) Right) . tryIOError
324335
325336instance P.MonadMake Make where
326337 getTimestamp path = makeIO $ do
327338 exists <- doesFileExist path
328− if exists
329− then Just <$> getModificationTime path
330− else return Nothing
339+ traverse (const $ getModificationTime path) $ guard exists
331340 readTextFile path = makeIO $ readFile path
332341 writeTextFile path text = makeIO $ do
333342 mkdirp path
334343 writeFile path text
335− liftError = either throwError return
336344 progress s = unless (s == "Compiling $PSCI") $ makeIO . putStrLn $ s
337345
338346mkdirp :: FilePath -> IO ()
@@ -348,13 +356,13 @@ createTemporaryModule exec PSCiState{psciImportedModuleNames = imports, psciLetB
348356 importDecl m = P.ImportDeclaration m P.Unqualified Nothing
349357 traceModule = P.ModuleName [P.ProperName "Debug", P.ProperName "Trace"]
350358 trace = P.Var (P.Qualified (Just traceModule) (P.Ident "print"))
351− itValue = foldl (\x f -> f x) val lets
352359 mainValue = P.App trace (P.Var (P.Qualified Nothing (P.Ident "it")))
353− itDecl = P.ValueDeclaration (P.Ident "it") P.Value [] $ Right itValue
360+ itDecl = P.ValueDeclaration (P.Ident "it") P.Value [] $ Right val
354361 mainDecl = P.ValueDeclaration (P.Ident "main") P.Value [] $ Right mainValue
355362 decls = if exec then [itDecl, mainDecl] else [itDecl]
356363 in
357− P.Module moduleName ((importDecl `map` imports) ++ decls) Nothing
364+ P.Module moduleName ((importDecl `map` imports) ++ lets ++ decls) Nothing
365+
358366
359367-- |
360368-- Makes a volatile module to hold a non-qualified type synonym for a fully-qualified data type declaration.
@@ -392,7 +400,7 @@ handleDeclaration :: P.Expr -> PSCI ()
392400handleDeclaration val = do
393401 st <- PSCI $ lift get
394402 let m = createTemporaryModule True st val
395− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
403+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
396404 case e of
397405 Left err -> PSCI $ outputStrLn err
398406 Right _ -> do
@@ -408,12 +416,12 @@ handleDeclaration val = do
408416-- Takes a let declaration and updates the environment, then run a make. If the declaration fails,
409417-- restore the pre-let environment.
410418--
411−handleLet :: (P.Expr -> P.Expr) -> PSCI ()
412−handleLet l = do
419+handleLet :: [P.Declaration] -> PSCI ()
420+handleLet ds = do
413421 st <- PSCI $ lift get
414− let st' = updateLets l st
422+ let st' = updateLets ds st
415423 let m = createTemporaryModule False st' (P.ObjectLiteral [])
416− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st' ++ [(Left P.RebuildAlways, m)]) []
424+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st' ++ [(Left P.RebuildAlways, m)]) []
417425 case e of
418426 Left err -> PSCI $ outputStrLn err
419427 Right _ -> PSCI $ lift (put st')
@@ -446,7 +454,7 @@ handleImport :: P.ModuleName -> PSCI ()
446454handleImport moduleName = do
447455 st <- updateImports moduleName <$> PSCI (lift get)
448456 let m = createTemporaryModuleForImports st
449− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
457+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
450458 case e of
451459 Left err -> PSCI $ outputStrLn err
452460 Right _ -> do
@@ -460,7 +468,7 @@ handleTypeOf :: P.Expr -> PSCI ()
460468handleTypeOf val = do
461469 st <- PSCI $ lift get
462470 let m = createTemporaryModule False st val
463− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
471+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
464472 case e of
465473 Left err -> PSCI $ outputStrLn err
466474 Right env' ->
@@ -494,7 +502,7 @@ handleBrowse :: P.ModuleName -> PSCI ()
494502handleBrowse moduleName = do
495503 st <- PSCI $ lift get
496504 let loadedModules = psciLoadedModules st
497− env <- psciIO . runMake $ P.make modulesDir options loadedModules []
505+ env <- psciIO . runMake $ P.make modulesDir loadedModules []
498506 case env of
499507 Left err -> PSCI $ outputStrLn err
500508 Right env' ->
@@ -510,7 +518,7 @@ handleKindOf typ = do
510518 st <- PSCI $ lift get
511519 let m = createTemporaryModuleForKind st typ
512520 mName = P.ModuleName [P.ProperName "$PSCI"]
513− e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
521+ e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
514522 case e of
515523 Left err -> PSCI $ outputStrLn err
516524 Right env' ->
@@ -561,10 +569,12 @@ handleCommand (LoadFile filePath) = do
561569 PSCI . outputStrLn $ "Couldn't locate: " ++ filePath
562570handleCommand Reset = do
563571 files <- psciImportedFilenames <$> PSCI (lift get)
564− modulesOrFirstError <- psciIO $ loadAllModules files
565− case modulesOrFirstError of
566− Left err -> psciIO $ print err >> exitFailure
567− Right modules -> PSCI . lift $ put (PSCiState files defaultImports modules [])
572+ PSCI . lift . modify $ \st -> st
573+ { psciImportedFilenames = files
574+ , psciImportedModuleNames = defaultImports
575+ , psciLetBindings = []
576+ }
577+ loadAllImportedModules
568578handleCommand (TypeOf val) = handleTypeOf val
569579handleCommand (KindOf typ) = handleKindOf typ
570580handleCommand (Browse moduleName) = handleBrowse moduleName
@@ -609,7 +619,7 @@ loop (PSCiOptions singleLineMode files) = do
609619 Left err -> outputStrLn err >> go
610620 Right Nothing -> go
611621 Right (Just Quit) -> outputStrLn quitMessage
612− Right (Just c') -> runPSCI (handleCommand c') >> go
622+ Right (Just c') -> runPSCI (loadAllImportedModules >> handleCommand c') >> go
613623
614624singleLineFlag :: Parser Bool
615625singleLineFlag = switch $
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+4−3
@@ -1,5 +1,5 @@
11name: purescript
2−version: 0.6.4
2+version: 0.6.7.1
33cabal-version: >=1.8
44build-type: Simple
55license: MIT
@@ -93,6 +93,7 @@ library
9393 Language.PureScript.Sugar.CaseDeclarations
9494 Language.PureScript.Sugar.DoNotation
9595 Language.PureScript.Sugar.Names
96+ Language.PureScript.Sugar.ObjectWildcards
9697 Language.PureScript.Sugar.Operators
9798 Language.PureScript.Sugar.TypeClasses
9899 Language.PureScript.Sugar.TypeDeclarations
@@ -150,7 +151,7 @@ executable psci
150151 ghc-options: -Wall -fno-warn-warnings-deprecations -O2
151152
152153executable psc-docs
153− build-depends: base >=4 && <5, purescript -any,
154+ build-depends: base >=4 && <5, purescript -any,
154155 optparse-applicative >= 0.10.0, process -any, mtl -any
155156 main-is: Main.hs
156157 buildable: True
@@ -158,7 +159,7 @@ executable psc-docs
158159 other-modules:
159160 ghc-options: -Wall -fno-warn-warnings-deprecations -O2
160161
161−executable hierarchy
162+executable psc-hierarchy
162163 build-depends: base >=4 && <5, purescript -any, optparse-applicative >= 0.10.0,
163164 process -any, mtl -any, parsec -any, filepath -any, directory -any
164165 main-is: Main.hs
src/Language/PureScript.hs+40−35
@@ -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,6 +22,7 @@ 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
@@ -29,6 +30,7 @@ import qualified Data.Set as S
2930import Control.Applicative
3031import Control.Arrow ((&&&))
3132import Control.Monad.Error
33+import Control.Monad.Reader
3234
3335import System.FilePath ((</>))
3436
@@ -71,42 +73,47 @@ import qualified Language.PureScript.Constants as C
7173--
7274-- * Pretty-print the generated Javascript
7375--
74−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)
7578compile = compile' initEnvironment
7679
77−compile' :: Environment -> Options Compile -> [Module] -> [String] -> Either String (String, String, Environment)
78−compile' env opts ms prefix = do
79− (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
8087 (desugared, nextVar) <- stringifyErrorStack True $ runSupplyT 0 $ desugar sorted
81− (elaborated, env') <- runCheck' opts env $ forM desugared $ typeCheckModule mainModuleIdent
88+ (elaborated, env') <- runCheck' env $ forM desugared $ typeCheckModule mainModuleIdent
8289 regrouped <- stringifyErrorStack True $ createBindingGroupsModule . collapseBindingGroupsModule $ elaborated
8390 let corefn = map (CoreFn.moduleToCoreFn env') regrouped
84− let entryPoints = moduleNameFromString `map` entryPointModules (optionsAdditional opts)
91+ let entryPoints = moduleNameFromString `map` entryPointModules additional
8592 let elim = if null entryPoints then corefn else eliminateDeadCode entryPoints corefn
8693 let renamed = renameInModules elim
87− let codeGenModuleNames = moduleNameFromString `map` codeGenModules (optionsAdditional opts)
94+ let codeGenModuleNames = moduleNameFromString `map` codeGenModules additional
8895 let modulesToCodeGen = if null codeGenModuleNames then renamed else filter (\(CoreFn.Module mn _ _ _ _) -> mn `elem` codeGenModuleNames) renamed
89− let js = evalSupply nextVar $ concat <$> mapM (moduleToJs opts) modulesToCodeGen
96+ js <- concat <$> (evalSupplyT nextVar $ T.traverse moduleToJs modulesToCodeGen)
9097 let exts = intercalate "\n" . map (`moduleToPs` env') $ regrouped
91− js' <- generateMain env' opts js
98+ js' <- generateMain env' js
9299 let pjs = unlines $ map ("// " ++) prefix ++ [prettyPrintJS js']
93100 return (pjs, exts, env')
94− where
95− mainModuleIdent = moduleNameFromString <$> optionsMain opts
96101
97−generateMain :: Environment -> Options Compile -> [JS] -> Either String [JS]
98−generateMain env opts js =
99− 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
100107 Just mmi -> do
101108 when ((mmi, Ident C.main) `M.notMember` names env) $
102− Left $ show mmi ++ "." ++ C.main ++ " is undefined"
103− 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)))) []]
104111 _ -> return js
105112
106113-- |
107114-- A type class which collects the IO actions we need to be able to run in "make" mode
108115--
109−class MonadMake m where
116+class (MonadReader (P.Options P.Make) m, MonadError String m) => MonadMake m where
110117 -- |
111118 -- Get a file timestamp
112119 --
@@ -122,11 +129,6 @@ class MonadMake m where
122129 --
123130 writeTextFile :: FilePath -> String -> m ()
124131
125− -- |
126− -- Report an error
127− --
128− liftError :: Either String a -> m a
129−
130132 -- |
131133 -- Respond to a progress update
132134 --
@@ -152,11 +154,13 @@ traverseEither f (Right y) = Right <$> f y
152154-- If timestamps have not changed, the externs file can be used to provide the module's types without
153155-- having to typecheck the module again.
154156--
155−make :: (Functor m, Applicative m, Monad m, MonadMake m) => FilePath -> Options Make -> [(Either RebuildPolicy FilePath, Module)] -> [String] -> m Environment
156−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
157161 let filePathMap = M.fromList (map (\(fp, Module mn _ _) -> (mn, fp)) ms)
158162
159− (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
160164
161165 toRebuild <- foldM (\s (Module moduleName' _ _) -> do
162166 let filePath = runModuleName moduleName'
@@ -176,15 +180,16 @@ make outputDir opts ms prefix = do
176180
177181 marked <- rebuildIfNecessary (reverseDependencies graph) toRebuild sorted
178182
179− (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)
180184
181− evalSupplyT nextVar (go initEnvironment desugared)
185+ evalSupplyT nextVar $ go initEnvironment desugared
182186
183187 where
184− 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
185190 go env [] = return env
186191 go env ((False, m) : ms') = do
187− (_, env') <- lift . liftError . runCheck' opts env $ typeCheckModule Nothing m
192+ (_, env') <- lift . runCheck' env $ typeCheckModule Nothing m
188193
189194 go env' ms'
190195 go env ((True, m@(Module moduleName' _ exps)) : ms') = do
@@ -194,15 +199,15 @@ make outputDir opts ms prefix = do
194199
195200 lift . progress $ "Compiling " ++ runModuleName moduleName'
196201
197− (Module _ elaborated _, env') <- lift . liftError . runCheck' opts env $ typeCheckModule Nothing m
202+ (Module _ elaborated _, env') <- lift . runCheck' env $ typeCheckModule Nothing m
198203
199− regrouped <- lift . liftError . stringifyErrorStack True . createBindingGroups moduleName' . collapseBindingGroups $ elaborated
204+ regrouped <- stringifyErrorStack True . createBindingGroups moduleName' . collapseBindingGroups $ elaborated
200205
201206 let mod' = Module moduleName' regrouped exps
202207 let corefn = CoreFn.moduleToCoreFn env' mod'
203208 let [renamed] = renameInModules [corefn]
204209
205− pjs <- prettyPrintJS <$> moduleToJs opts renamed
210+ pjs <- prettyPrintJS <$> moduleToJs renamed
206211 let js = unlines $ map ("// " ++) prefix ++ [pjs]
207212 let exts = unlines $ map ("-- " ++) prefix ++ [moduleToPs mod' env']
208213
@@ -220,10 +225,10 @@ make outputDir opts ms prefix = do
220225 rebuildIfNecessary graph toRebuild (Module moduleName' _ _ : ms') = do
221226 let externsFile = outputDir </> runModuleName moduleName' </> "externs.purs"
222227 externs <- readTextFile externsFile
223− 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)]
224229 case externsModules of
225230 [m'@(Module moduleName'' _ _)] | moduleName'' == moduleName' -> (:) (False, m') <$> rebuildIfNecessary graph toRebuild ms'
226− _ -> liftError . Left $ "Externs file " ++ externsFile ++ " was invalid"
231+ _ -> throwError $ "Externs file " ++ externsFile ++ " was invalid"
227232
228233reverseDependencies :: ModuleGraph -> M.Map ModuleName [ModuleName]
229234reverseDependencies g = combine [ (dep, mn) | (mn, deps) <- g, dep <- deps ]
src/Language/PureScript/AST/Declarations.hs+21−1
@@ -305,13 +305,18 @@ data Expr
305305 -- Binary operator application. During the rebracketing phase of desugaring, this data constructor
306306 -- will be removed.
307307 --
308− | BinaryNoParens (Qualified Ident) Expr Expr
308+ | BinaryNoParens Expr Expr Expr
309309 -- |
310310 -- Explicit parentheses. During the rebracketing phase of desugaring, this data constructor
311311 -- will be removed.
312312 --
313313 | Parens Expr
314314 -- |
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+ -- |
315320 -- An array literal
316321 --
317322 | ArrayLiteral [Expr]
@@ -320,6 +325,16 @@ data Expr
320325 --
321326 | ObjectLiteral [(String, Expr)]
322327 -- |
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+ -- |
323338 -- An record property accessor expression
324339 --
325340 | Accessor String Expr
@@ -328,6 +343,11 @@ data Expr
328343 --
329344 | ObjectUpdate Expr [(String, Expr)]
330345 -- |
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+ -- |
331351 -- Function introduction
332352 --
333353 | Abs (Either Ident Binder) Expr
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+32−8
@@ -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
@@ -42,13 +43,17 @@ everywhereOnValues f g h = (f', g', h')
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))
@@ -80,7 +85,6 @@ everywhereOnValues f g h = (f', g', h')
8085 handleDoNotationElement (DoNotationLet ds) = DoNotationLet (map f' ds)
8186 handleDoNotationElement (PositionedDoNotationElement pos com e) = PositionedDoNotationElement pos com (handleDoNotationElement e)
8287
83−
8488everywhereOnValuesTopDownM :: (Functor m, Applicative m, Monad m) =>
8589 (Declaration -> m Declaration) ->
8690 (Expr -> m Expr) ->
@@ -97,13 +101,17 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
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')
@@ -146,13 +154,17 @@ everywhereOnValuesM f g h = (f', g', h')
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
@@ -198,13 +210,17 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
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
@@ -261,13 +277,17 @@ everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'
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
@@ -327,13 +347,17 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
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
src/Language/PureScript/CodeGen/Externs.hs+10−3
@@ -45,11 +45,18 @@ moduleToPs (Module moduleName ds (Just exts)) env = intercalate "\n" . execWrite
4545
4646 declToPs :: Declaration -> Writer [String] ()
4747 declToPs (ImportDeclaration mn _ _) = tell ["import " ++ show mn ++ " ()"]
48− declToPs (FixityDeclaration (Fixity assoc prec) ident) =
49− tell [ unwords [ show assoc, show prec, ident ] ]
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
5057 declToPs (PositionedDeclaration _ com d) = mapM commentToPs com >> declToPs d
5158 declToPs _ = return ()
52−
59+
5360 commentToPs :: Comment -> Writer [String] ()
5461 commentToPs (LineComment s) = tell ["-- " ++ s]
5562 commentToPs (BlockComment s) = tell ["{- " ++ s ++ " -}"]
src/Language/PureScript/CodeGen/JS.hs+48−30
@@ -13,21 +13,22 @@
1313--
1414-----------------------------------------------------------------------------
1515
16−{-# LANGUAGE GADTs, ViewPatterns #-}
16+{-# LANGUAGE GADTs, ViewPatterns, FlexibleContexts #-}
1717
1818module Language.PureScript.CodeGen.JS (
1919 module AST,
2020 module Common,
21− bindToJs,
2221 moduleToJs
2322) where
2423
2524import Data.List ((\\), delete)
2625import Data.Maybe (mapMaybe)
26+import qualified Data.Traversable as T (traverse)
2727
2828import Control.Applicative
2929import Control.Arrow ((&&&))
3030import Control.Monad (foldM, replicateM, forM)
31+import Control.Monad.Reader (MonadReader, asks, lift)
3132
3233import Language.PureScript.CodeGen.JS.AST as AST
3334import Language.PureScript.CodeGen.JS.Common as Common
@@ -43,16 +44,18 @@ import qualified Language.PureScript.Constants as C
4344-- Generate code in the simplified Javascript intermediate representation for all declarations in a
4445-- module.
4546--
46−moduleToJs :: (Functor m, Applicative m, Monad m) => Options mode -> Module Ann -> SupplyT m [JS]
47−moduleToJs opts (Module name imps exps foreigns decls) = do
48− 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
4952 let foreigns' = mapMaybe (\(_, js, _) -> js) foreigns
5053 jsDecls <- mapM (bindToJs name) decls
51− let optimized = concatMap (map $ optimize opts) jsDecls
54+ optimized <- lift $ T.traverse (T.traverse optimize) jsDecls
5255 let isModuleEmpty = null exps
53− let moduleBody = JSStringLiteral "use strict" : jsImports ++ foreigns' ++ optimized
56+ let moduleBody = JSStringLiteral "use strict" : jsImports ++ foreigns' ++ concat optimized
5457 let exps' = JSObjectLiteral $ map (runIdent &&& JSVar . identToJs) exps
55− return $ case optionsAdditional opts of
58+ return $ case additional of
5659 MakeOptions -> moduleBody ++ [JSAssignment (JSAccessor "exports" (JSVar "module")) exps']
5760 CompileOptions ns _ _ | not isModuleEmpty ->
5861 [ JSVariableIntroduction ns
@@ -65,18 +68,19 @@ moduleToJs opts (Module name imps exps foreigns decls) = do
6568-- |
6669-- Generates Javascript code for a module import.
6770--
68−importToJs :: Options mode -> ModuleName -> JS
69−importToJs opts mn =
70− JSVariableIntroduction (moduleNameToJs mn) (Just moduleBody)
71− where
72− moduleBody = case optionsAdditional opts of
73− MakeOptions -> JSApp (JSVar "require") [JSStringLiteral (runModuleName mn)]
74− 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)
7578
7679-- |
7780-- Generate code in the simplified Javascript intermediate representation for a declaration
7881--
79−bindToJs :: (Functor m, Applicative m, Monad m) => ModuleName -> Bind Ann -> SupplyT m [JS]
82+bindToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
83+ => ModuleName -> Bind Ann -> SupplyT m [JS]
8084bindToJs mp (NonRec ident val) = return <$> nonRecToJS mp ident val
8185bindToJs mp (Rec vals) = forM vals (uncurry (nonRecToJS mp))
8286
@@ -86,9 +90,13 @@ bindToJs mp (Rec vals) = forM vals (uncurry (nonRecToJS mp))
8690--
8791-- The main purpose of this function is to handle code generation for comments.
8892--
89−nonRecToJS :: (Functor m, Applicative m, Monad m) => ModuleName -> Ident -> Expr Ann -> SupplyT m JS
90−nonRecToJS m i e@(extractAnn -> (_, com, _, _)) | not (null com) =
91− JSComment com <$> nonRecToJS m i (modifyAnn removeComments e)
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)
92100nonRecToJS mp ident val = do
93101 js <- valueToJs mp val
94102 return $ JSVariableIntroduction (identToJs ident) (Just js)
@@ -117,7 +125,8 @@ accessorString prop | identNeedsEscaping prop = JSIndexer (JSStringLiteral prop)
117125-- |
118126-- Generate code in the simplified Javascript intermediate representation for a value or expression.
119127--
120−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
121130valueToJs m (Literal _ l) =
122131 literalToValueJS m l
123132valueToJs m (Var (_, _, _, Just (IsConstructor _ [])) name) =
@@ -128,7 +137,7 @@ valueToJs m (Accessor _ prop val) =
128137 accessorString prop <$> valueToJs m val
129138valueToJs m (ObjectUpdate _ o ps) = do
130139 obj <- valueToJs m o
131− sts <- mapM (sndM (valueToJs m)) ps
140+ sts <- mapM (sndM $ valueToJs m) ps
132141 extendObj obj sts
133142valueToJs _ e@(Abs (_, _, _, Just IsTypeClassConstructor) _ _) =
134143 let args = unAbs e
@@ -191,7 +200,8 @@ valueToJs _ (Constructor _ _ (ProperName ctor) fields) =
191200iife :: String -> [JS] -> JS
192201iife v exprs = JSApp (JSFunction Nothing [] (JSBlock $ exprs ++ [JSReturn $ JSVar v])) []
193202
194−literalToValueJS :: (Functor m, Applicative m, Monad m) => ModuleName -> Literal (Expr Ann) -> SupplyT m JS
203+literalToValueJS :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
204+ => ModuleName -> Literal (Expr Ann) -> SupplyT m JS
195205literalToValueJS _ (NumericLiteral n) = return $ JSNumericLiteral n
196206literalToValueJS _ (StringLiteral s) = return $ JSStringLiteral s
197207literalToValueJS _ (BooleanLiteral b) = return $ JSBooleanLiteral b
@@ -238,7 +248,8 @@ qualifiedToJS _ f (Qualified _ a) = JSVar $ identToJs (f a)
238248-- Generate code in the simplified Javascript intermediate representation for pattern match binders
239249-- and guards.
240250--
241−bindersToJs :: (Functor m, Applicative m, Monad m) => ModuleName -> [CaseAlternative Ann] -> [JS] -> SupplyT m JS
251+bindersToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
252+ => ModuleName -> [CaseAlternative Ann] -> [JS] -> SupplyT m JS
242253bindersToJs m binders vals = do
243254 valNames <- replicateM (length vals) freshName
244255 let assignments = zipWith JSVariableIntroduction valNames (map Just vals)
@@ -248,14 +259,16 @@ bindersToJs m binders vals = do
248259 return $ JSApp (JSFunction Nothing [] (JSBlock (assignments ++ concat jss ++ [JSThrow $ JSUnary JSNew $ JSApp (JSVar "Error") [JSStringLiteral "Failed pattern match"]])))
249260 []
250261 where
251− go :: (Functor m, Applicative m, Monad m) => [String] -> [JS] -> [Binder Ann] -> SupplyT m [JS]
262+ go :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
263+ => [String] -> [JS] -> [Binder Ann] -> SupplyT m [JS]
252264 go _ done [] = return done
253265 go (v:vs) done' (b:bs) = do
254266 done'' <- go vs done' bs
255267 binderToJs m v done'' b
256268 go _ _ _ = error "Invalid arguments to bindersToJs"
257269
258− guardsToJs :: (Functor m, Applicative m, Monad m) => Either [(Guard Ann, Expr Ann)] (Expr Ann) -> SupplyT m [JS]
270+ guardsToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
271+ => Either [(Guard Ann, Expr Ann)] (Expr Ann) -> SupplyT m [JS]
259272 guardsToJs (Left gs) = forM gs $ \(cond, val) -> do
260273 cond' <- valueToJs m cond
261274 done <- valueToJs m val
@@ -266,7 +279,8 @@ bindersToJs m binders vals = do
266279-- Generate code in the simplified Javascript intermediate representation for a pattern match
267280-- binder.
268281--
269−binderToJs :: (Functor m, Applicative m, Monad m) => ModuleName -> String -> [JS] -> Binder Ann -> SupplyT m [JS]
282+binderToJs :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
283+ => ModuleName -> String -> [JS] -> Binder Ann -> SupplyT m [JS]
270284binderToJs _ _ done (NullBinder{}) = return done
271285binderToJs m varName done (LiteralBinder _ l) =
272286 literalToBinderJS m varName done l
@@ -283,7 +297,8 @@ binderToJs m varName done (ConstructorBinder (_, _, _, Just (IsConstructor ctorT
283297 (JSBlock js)
284298 Nothing]
285299 where
286− go :: (Functor m, Applicative m, Monad m) => [(Ident, Binder Ann)] -> [JS] -> SupplyT m [JS]
300+ go :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
301+ => [(Ident, Binder Ann)] -> [JS] -> SupplyT m [JS]
287302 go [] done' = return done'
288303 go ((field, binder) : remain) done' = do
289304 argVar <- freshName
@@ -313,7 +328,8 @@ binderToJs m varName done (NamedBinder _ ident binder) = do
313328 js <- binderToJs m varName done binder
314329 return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : js)
315330
316−literalToBinderJS :: (Functor m, Applicative m, Monad m) => ModuleName -> String -> [JS] -> Literal (Binder Ann) -> SupplyT m [JS]
331+literalToBinderJS :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
332+ => ModuleName -> String -> [JS] -> Literal (Binder Ann) -> SupplyT m [JS]
317333literalToBinderJS _ varName done (NumericLiteral num) =
318334 return [JSIfElse (JSBinary EqualTo (JSVar varName) (JSNumericLiteral num)) (JSBlock done) Nothing]
319335literalToBinderJS _ varName done (StringLiteral str) =
@@ -324,7 +340,8 @@ literalToBinderJS _ varName done (BooleanLiteral False) =
324340 return [JSIfElse (JSUnary Not (JSVar varName)) (JSBlock done) Nothing]
325341literalToBinderJS m varName done (ObjectLiteral bs) = go done bs
326342 where
327− go :: (Functor m, Applicative m, Monad m) => [JS] -> [(String, Binder Ann)] -> SupplyT m [JS]
343+ go :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
344+ => [JS] -> [(String, Binder Ann)] -> SupplyT m [JS]
328345 go done' [] = return done'
329346 go done' ((prop, binder):bs') = do
330347 propVar <- freshName
@@ -335,7 +352,8 @@ literalToBinderJS m varName done (ArrayLiteral bs) = do
335352 js <- go done 0 bs
336353 return [JSIfElse (JSBinary EqualTo (JSAccessor "length" (JSVar varName)) (JSNumericLiteral (Left (fromIntegral $ length bs)))) (JSBlock js) Nothing]
337354 where
338− go :: (Functor m, Applicative m, Monad m) => [JS] -> Integer -> [Binder Ann] -> SupplyT m [JS]
355+ go :: (Functor m, Applicative m, Monad m, MonadReader (Options mode) m)
356+ => [JS] -> Integer -> [Binder Ann] -> SupplyT m [JS]
339357 go done' _ [] = return done'
340358 go done' index (binder:bs') = do
341359 elVar <- freshName
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.hs+2−2
@@ -18,8 +18,8 @@
1818module Language.PureScript.Comments where
1919
2020import qualified Data.Data as D
21−
21+
2222data Comment
2323 = LineComment String
2424 | BlockComment String
25− deriving (Show, Eq, Ord, D.Data, D.Typeable)
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+1−1
@@ -34,4 +34,4 @@ nullAnn = (Nothing, [], Nothing, Nothing)
3434-- Remove the comments from an annotation
3535--
3636removeComments :: Ann -> Ann
37−removeComments (ss, _, ty, meta) = (ss, [], ty, meta)
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/Expr.hs+12−2
@@ -13,9 +13,12 @@
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
@@ -61,7 +64,7 @@ data Expr a
6164 -- |
6265 -- A let binding
6366 --
64− | 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)
6568
6669-- |
6770-- A let or module binding.
@@ -74,7 +77,7 @@ data Bind a
7477 -- |
7578 -- Mutually recursive binding group for several values
7679 --
77− | Rec [(Ident, Expr a)] deriving (Show, D.Data, D.Typeable)
80+ | Rec [(Ident, Expr a)] deriving (Show, D.Data, D.Typeable, Functor)
7881
7982-- |
8083-- A guard is just a boolean-valued expression that appears alongside a set of binders
@@ -95,6 +98,12 @@ data CaseAlternative a = CaseAlternative
9598 , caseAlternativeResult :: Either [(Guard a, Expr a)] (Expr a)
9699 } deriving (Show, D.Data, D.Typeable)
97100
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+
98107-- |
99108-- Extract the annotation from a term
100109--
@@ -109,6 +118,7 @@ extractAnn (Var a _) = a
109118extractAnn (Case a _ _) = a
110119extractAnn (Let a _ _) = a
111120
121+
112122-- |
113123-- Modify the annotation on a term
114124--
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/Environment.hs+6−1
@@ -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
src/Language/PureScript/Errors.hs+2−2
@@ -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
src/Language/PureScript/ModuleDependencies.hs+7−4
@@ -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.Error.Class
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 _ = []
@@ -67,7 +70,7 @@ usedModules = let (f, _, _, _, _) = everythingOnValues (++) forDecls forValues (
6770-- |
6871-- Convert a strongly connected component of the module graph to a module
6972--
70−toModule :: SCC Module -> Either String Module
73+toModule :: (MonadError String m) => SCC Module -> m Module
7174toModule (AcyclicSCC m) = return m
7275toModule (CyclicSCC [m]) = return m
73−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−6
@@ -88,12 +88,6 @@ buildPostfixParser fs first = do
8888 Nothing -> return a
8989 Just a' -> go a'
9090
91−-- |
92−-- Parse an identifier in backticks or an operator
93−--
94−parseIdentInfix :: TokenParser (Qualified Ident)
95−parseIdentInfix = P.between tick tick (parseQualified (Ident <$> identifier)) <|> (parseQualified (Op <$> symbol))
96−
9791-- |
9892-- Mark the current indentation level
9993--
src/Language/PureScript/Parser/Declarations.hs+37−9
@@ -41,6 +41,7 @@ import Language.PureScript.Parser.Common
4141import Language.PureScript.Parser.Types
4242import Language.PureScript.Parser.Kinds
4343import Language.PureScript.Parser.Lexer
44+import Language.PureScript.Names
4445import Language.PureScript.CodeGen.JS.AST
4546import Language.PureScript.Environment
4647
@@ -285,11 +286,13 @@ parseArrayLiteral :: TokenParser Expr
285286parseArrayLiteral = ArrayLiteral <$> squares (commaSep parseValue)
286287
287288parseObjectLiteral :: TokenParser Expr
288−parseObjectLiteral = ObjectLiteral <$> braces (commaSep parseIdentifierAndValue)
289+parseObjectLiteral = ObjectConstructor <$> braces (commaSep parseIdentifierAndValue)
289290
290−parseIdentifierAndValue :: TokenParser (String, Expr)
291+parseIdentifierAndValue :: TokenParser (String, Maybe Expr)
291292parseIdentifierAndValue = (,) <$> (C.indented *> (lname <|> stringLiteral) <* C.indented <* colon)
292− <*> (C.indented *> parseValue)
293+ <*> (C.indented *> val)
294+ where
295+ val = (Just <$> parseValue) <|> (underscore *> pure Nothing)
293296
294297parseAbs :: TokenParser Expr
295298parseAbs = do
@@ -343,6 +346,7 @@ parseValueAtom = P.choice
343346 , P.try parseBooleanLiteral
344347 , parseArrayLiteral
345348 , P.try parseObjectLiteral
349+ , P.try parseObjectGetter
346350 , parseAbs
347351 , P.try parseConstructor
348352 , P.try parseVar
@@ -350,13 +354,28 @@ parseValueAtom = P.choice
350354 , parseIfThenElse
351355 , parseDo
352356 , parseLet
353− , Parens <$> parens parseValue ]
357+ , P.try $ Parens <$> parens parseValue
358+ , parseOperatorSection
359+ , P.try parseObjectUpdaterWildcard ]
354360
355−parsePropertyUpdate :: TokenParser (String, Expr)
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)
367+
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)
356375parsePropertyUpdate = do
357376 name <- lname <|> stringLiteral
358377 _ <- C.indented *> equals
359− value <- C.indented *> parseValue
378+ value <- C.indented *> (underscore *> pure Nothing) <|> (Just <$> parseValue)
360379 return (name, value)
361380
362381parseAccessor :: Expr -> TokenParser Expr
@@ -381,6 +400,9 @@ parseDoNotationElement = P.choice
381400 , parseDoNotationLet
382401 , P.try (DoNotationValue <$> parseValue) ]
383402
403+parseObjectGetter :: TokenParser Expr
404+parseObjectGetter = ObjectGetter <$> (underscore *> C.indented *> dot *> C.indented *> (lname <|> stringLiteral))
405+
384406-- |
385407-- Parse a value
386408--
@@ -392,17 +414,23 @@ parseValue = withSourceSpan PositionedValue
392414 where
393415 indexersAndAccessors = C.buildPostfixParser postfixTable1 parseValueAtom
394416 postfixTable1 = [ parseAccessor
395− , \v -> P.try $ flip ObjectUpdate <$> (C.indented *> braces (commaSep1 (C.indented *> parsePropertyUpdate))) <*> pure v ]
417+ , P.try . parseUpdaterBody . Just ]
396418 postfixTable2 = [ \v -> P.try (flip App <$> (C.indented *> indexersAndAccessors)) <*> pure v
397419 , \v -> flip (TypedValue True) <$> (P.try (C.indented *> doubleColon) *> parsePolyType) <*> pure v
398420 ]
399421 operators = [ [ P.Prefix (P.try (C.indented *> symbol' "-") >> return UnaryMinus)
400422 ]
401− , [ P.Infix (P.try (C.indented *> C.parseIdentInfix P.<?> "operator") >>= \ident ->
423+ , [ P.Infix (P.try (C.indented *> parseInfixExpr P.<?> "infix expression") >>= \ident ->
402424 return (BinaryNoParens ident)) P.AssocRight
403425 ]
404426 ]
405427
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+
406434parseStringBinder :: TokenParser Binder
407435parseStringBinder = StringBinder <$> stringLiteral
408436
@@ -437,7 +465,7 @@ parseNamedBinder = NamedBinder <$> (C.parseIdent <* C.indented <* at)
437465 <*> (C.indented *> parseBinder)
438466
439467parseNullBinder :: TokenParser Binder
440−parseNullBinder = reserved "_" *> return NullBinder
468+parseNullBinder = underscore *> return NullBinder
441469
442470parseIdentifierAndBinder :: TokenParser (String, Binder)
443471parseIdentifierAndBinder = do
src/Language/PureScript/Parser/Lexer.hs+38−30
@@ -15,7 +15,7 @@
1515
1616{-# LANGUAGE TupleSections #-}
1717
18−module Language.PureScript.Parser.Lexer
18+module Language.PureScript.Parser.Lexer
1919 ( PositionedToken(..)
2020 , Token()
2121 , TokenParser()
@@ -34,8 +34,8 @@ module Language.PureScript.Parser.Lexer
3434 , squares
3535 , indent
3636 , indentAt
37− , larrow
38− , rarrow
37+ , larrow
38+ , rarrow
3939 , lfatArrow
4040 , rfatArrow
4141 , colon
@@ -47,6 +47,7 @@ module Language.PureScript.Parser.Lexer
4747 , comma
4848 , semi
4949 , at
50+ , underscore
5051 , semiSep
5152 , semiSep1
5253 , commaSep
@@ -83,7 +84,7 @@ import Language.PureScript.Comments
8384
8485import qualified Text.Parsec as P
8586import qualified Text.Parsec.Token as PT
86−
87+
8788data Token
8889 = LParen
8990 | RParen
@@ -105,6 +106,7 @@ data Token
105106 | Comma
106107 | Semi
107108 | At
109+ | Underscore
108110 | LName String
109111 | UName String
110112 | Qualifier String
@@ -112,7 +114,7 @@ data Token
112114 | StringLiteral String
113115 | Number (Either Integer Double)
114116 deriving (Show, Eq, Ord)
115−
117+
116118prettyPrintToken :: Token -> String
117119prettyPrintToken LParen = "("
118120prettyPrintToken RParen = ")"
@@ -133,6 +135,7 @@ prettyPrintToken Dot = "."
133135prettyPrintToken Comma = ","
134136prettyPrintToken Semi = ";"
135137prettyPrintToken At = "@"
138+prettyPrintToken Underscore = "_"
136139prettyPrintToken (Indent n) = "indentation at level " ++ show n
137140prettyPrintToken (LName s) = show s
138141prettyPrintToken (UName s) = show s
@@ -146,19 +149,19 @@ data PositionedToken = PositionedToken
146149 , ptToken :: Token
147150 , ptComments :: [Comment]
148151 } deriving (Eq)
149−
152+
150153instance Show PositionedToken where
151154 show = show . ptToken
152155
153156lex :: FilePath -> String -> Either P.ParseError [PositionedToken]
154157lex filePath input = P.parse parseTokens filePath input
155−
158+
156159parseTokens :: P.Parsec String u [PositionedToken]
157160parseTokens = whitespace *> P.many parsePositionedToken <* P.skipMany parseComment <* P.eof
158161
159162whitespace :: P.Parsec String u ()
160163whitespace = P.skipMany (P.satisfy isSpace)
161−
164+
162165parseComment :: P.Parsec String u Comment
163166parseComment = (BlockComment <$> blockComment <|> LineComment <$> lineComment) <* whitespace
164167 where
@@ -177,11 +180,11 @@ parsePositionedToken = P.try $ do
177180
178181parseToken :: P.Parsec String u Token
179182parseToken = P.choice
180− [ P.try $ P.string "<-" *> P.notFollowedBy symbolChar *> pure LArrow
183+ [ P.try $ P.string "<-" *> P.notFollowedBy symbolChar *> pure LArrow
181184 , P.try $ P.string "<=" *> P.notFollowedBy symbolChar *> pure LFatArrow
182− , P.try $ P.string "->" *> P.notFollowedBy symbolChar *> pure RArrow
183− , P.try $ P.string "=>" *> P.notFollowedBy symbolChar *> pure RFatArrow
184− , 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
185188 , P.try $ P.char '(' *> pure LParen
186189 , P.try $ P.char ')' *> pure RParen
187190 , P.try $ P.char '{' *> pure LBrace
@@ -196,10 +199,11 @@ parseToken = P.choice
196199 , P.try $ P.char '.' *> P.notFollowedBy symbolChar *> pure Dot
197200 , P.try $ P.char ';' *> P.notFollowedBy symbolChar *> pure Semi
198201 , P.try $ P.char '@' *> P.notFollowedBy symbolChar *> pure At
199− , LName <$> parseLName
202+ , P.try $ P.char '_' *> P.notFollowedBy identLetter *> pure Underscore
203+ , LName <$> parseLName
200204 , do uName <- parseUName
201205 (guard (validModuleName uName) >> Qualifier uName <$ P.char '.') <|> pure (UName uName)
202− , Symbol <$> parseSymbol
206+ , Symbol <$> parseSymbol
203207 , StringLiteral <$> parseStringLiteral
204208 , Number <$> parseNumber
205209 ] <* whitespace
@@ -207,16 +211,16 @@ parseToken = P.choice
207211 where
208212 parseLName :: P.Parsec String u String
209213 parseLName = (:) <$> identStart <*> P.many identLetter
210−
214+
211215 parseUName :: P.Parsec String u String
212216 parseUName = (:) <$> P.upper <*> P.many uidentLetter
213−
217+
214218 parseSymbol :: P.Parsec String u String
215219 parseSymbol = P.many1 symbolChar
216−
220+
217221 identStart :: P.Parsec String u Char
218222 identStart = P.lower <|> P.oneOf "_"
219−
223+
220224 identLetter :: P.Parsec String u Char
221225 identLetter = P.alphaNum <|> P.oneOf "_'"
222226
@@ -225,13 +229,13 @@ parseToken = P.choice
225229
226230 symbolChar :: P.Parsec String u Char
227231 symbolChar = P.oneOf opChars
228−
232+
229233 parseStringLiteral :: P.Parsec String u String
230234 parseStringLiteral = blockString <|> PT.stringLiteral tokenParser
231− where
235+ where
232236 delimeter = P.try (P.string "\"\"\"")
233237 blockString = delimeter >> P.manyTill P.anyChar delimeter
234−
238+
235239 parseNumber :: P.Parsec String u (Either Integer Double)
236240 parseNumber = (Right <$> P.try (PT.float tokenParser) <|>
237241 Left <$> P.try (PT.natural tokenParser)) P.<?> "number"
@@ -261,10 +265,10 @@ tokenParser :: PT.GenTokenParser String u Identity
261265tokenParser = PT.makeTokenParser langDef
262266
263267type TokenParser a = P.Parsec [PositionedToken] ParseState a
264−
268+
265269anyToken :: TokenParser PositionedToken
266270anyToken = P.token (prettyPrintToken . ptToken) ptSourcePos Just
267−
271+
268272token :: (Token -> Maybe a) -> TokenParser a
269273token f = P.token (prettyPrintToken . ptToken) ptSourcePos (f . ptToken)
270274
@@ -347,7 +351,10 @@ semi :: TokenParser ()
347351semi = match Semi
348352
349353at :: TokenParser ()
350−at = match At
354+at = match At
355+
356+underscore :: TokenParser ()
357+underscore = match Underscore
351358
352359-- |
353360-- Parse zero or more values separated by semicolons
@@ -408,13 +415,14 @@ uname' s = token go P.<?> show s
408415 where
409416 go (UName s') | s == s' = Just ()
410417 go _ = Nothing
411−
418+
412419symbol :: TokenParser String
413420symbol = token go P.<?> "symbol"
414421 where
415422 go (Symbol s) = Just s
416423 go Colon = Just ":"
417424 go LFatArrow = Just "<="
425+ go At = Just "@"
418426 go _ = Nothing
419427
420428symbol' :: String -> TokenParser ()
@@ -424,7 +432,7 @@ symbol' s = token go P.<?> show s
424432 go Colon | s == ":" = Just ()
425433 go LFatArrow | s == "<=" = Just ()
426434 go _ = Nothing
427−
435+
428436stringLiteral :: TokenParser String
429437stringLiteral = token go P.<?> "string literal"
430438 where
@@ -448,10 +456,10 @@ identifier = token go P.<?> "identifier"
448456 where
449457 go (LName s) | s `notElem` reservedPsNames = Just s
450458 go _ = Nothing
451−
459+
452460validModuleName :: String -> Bool
453461validModuleName s = not ('_' `elem` s)
454−
462+
455463-- |
456464-- A list of purescript reserved identifiers
457465--
@@ -479,7 +487,7 @@ reservedPsNames = [ "data"
479487 , "in"
480488 , "where"
481489 ]
482−
490+
483491reservedTypeNames :: [String]
484492reservedTypeNames = [ "forall", "where" ]
485493
@@ -488,4 +496,4 @@ reservedTypeNames = [ "forall", "where" ]
488496--
489497opChars :: [Char]
490498opChars = ":!#$%&*+./<=>?@\\^|-~"
491−
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+4−4
@@ -135,16 +135,16 @@ literals = mkPattern' match
135135 commentLines :: Comment -> [String]
136136 commentLines (LineComment s) = [s]
137137 commentLines (BlockComment s) = lines s
138−
139− asLine :: String -> StateT PrinterState Maybe String
138+
139+ asLine :: String -> StateT PrinterState Maybe String
140140 asLine s = do
141141 i <- currentIndent
142142 return $ i ++ " * " ++ removeComments s ++ "\n"
143−
143+
144144 removeComments :: String -> String
145145 removeComments ('*' : '/' : s) = removeComments s
146146 removeComments (c : s) = c : removeComments s
147−
147+
148148 removeComments [] = []
149149 match (JSRaw js) = return js
150150 match _ = mzero
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+36−27
@@ -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,11 +69,13 @@ 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
@@ -86,7 +84,7 @@ literals = mkPattern' match
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 ]
@@ -95,7 +93,7 @@ prettyPrintDeclaration _ = 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,18 +114,28 @@ 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 ]
129127prettyPrintDoNotationElement (PositionedDoNotationElement _ _ el) = prettyPrintDoNotationElement el
130128
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+ ]
138+
131139ifThenElse :: Pattern PrinterState Expr ((Expr, Expr), Expr)
132140ifThenElse = mkPattern match
133141 where
@@ -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,17 +197,17 @@ 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 "]"
@@ -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/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+3−3
@@ -52,12 +52,12 @@ createBindingGroups :: ModuleName -> [Declaration] -> Either ErrorStack [Declara
5252createBindingGroups moduleName = mapM f <=< handleDecls
5353
5454 where
55− (f, _, _) = everywhereOnValuesTopDownM return handleExprs return
56−
55+ (f, _, _) = everywhereOnValuesTopDownM return handleExprs return
56+
5757 handleExprs :: Expr -> Either ErrorStack Expr
5858 handleExprs (Let ds val) = flip Let val <$> handleDecls ds
5959 handleExprs other = return other
60−
60+
6161 -- |
6262 -- Replace all sets of mutually-recursive declarations with binding groups
6363 --
src/Language/PureScript/Sugar/Names.hs+41−15
@@ -54,8 +54,8 @@ data Exports = Exports
5454 , exportedTypeClasses :: [ProperName]
5555 -- |
5656 -- The values exported from each module
57− , exportedValues :: [Ident]
5857 --
58+ , exportedValues :: [Ident]
5959 } deriving (Show)
6060
6161-- |
@@ -105,15 +105,26 @@ addEmptyModule env name =
105105--
106106addType :: ExportEnvironment -> ModuleName -> ProperName -> [ProperName] -> Either ErrorStack ExportEnvironment
107107addType env mn name dctors = updateExportedModule env mn $ \m -> do
108− types' <- addExport (exportedTypes m) (name, dctors)
109− return $ m { exportedTypes = types' }
108+ let exTypes = exportedTypes m
109+ let exDctors = snd `concatMap` exTypes
110+ let exClasses = exportedTypeClasses m
111+ when (any ((== name) . fst) exTypes) $ throwMultipleDefError "type" name
112+ when (name `elem` exClasses) $ throwConflictingDefError "Type" "type class" name
113+ forM_ dctors $ \dctor -> do
114+ when (dctor `elem` exDctors) $ throwMultipleDefError "data constructor" dctor
115+ when (dctor `elem` exClasses) $ throwConflictingDefError "Data constructor" "type class" dctor
116+ return $ m { exportedTypes = (name, dctors) : exTypes }
110117
111118-- |
112119-- Adds a class to the export environment.
113120--
114121addTypeClass :: ExportEnvironment -> ModuleName -> ProperName -> Either ErrorStack ExportEnvironment
115122addTypeClass env mn name = updateExportedModule env mn $ \m -> do
116− classes <- addExport (exportedTypeClasses m) name
123+ let exTypes = exportedTypes m
124+ let exDctors = snd `concatMap` exTypes
125+ when (any ((== name) . fst) exTypes) $ throwConflictingDefError "Type class" "type" name
126+ when (name `elem` exDctors) $ throwConflictingDefError "Type class" "data constructor" name
127+ classes <- addExport "type class" (exportedTypeClasses m) name
117128 return $ m { exportedTypeClasses = classes }
118129
119130-- |
@@ -121,17 +132,17 @@ addTypeClass env mn name = updateExportedModule env mn $ \m -> do
121132--
122133addValue :: ExportEnvironment -> ModuleName -> Ident -> Either ErrorStack ExportEnvironment
123134addValue env mn name = updateExportedModule env mn $ \m -> do
124− values <- addExport (exportedValues m) name
135+ values <- addExport "value" (exportedValues m) name
125136 return $ m { exportedValues = values }
126137
127138-- |
128139-- Adds an entry to a list of exports unless it is already present, in which case an error is
129140-- returned.
130141--
131−addExport :: (Eq a, Show a) => [a] -> a -> Either ErrorStack [a]
132−addExport exports name =
142+addExport :: (Eq a, Show a) => String -> [a] -> a -> Either ErrorStack [a]
143+addExport what exports name =
133144 if name `elem` exports
134− then throwError $ mkErrorStack ("Multiple definitions for '" ++ show name ++ "'") Nothing
145+ then throwMultipleDefError what name
135146 else return $ name : exports
136147
137148-- |
@@ -219,17 +230,16 @@ renameInModule imports exports (Module mn decls exps) =
219230 updateValue :: (Maybe SourceSpan, [Ident]) -> Expr -> Either ErrorStack ((Maybe SourceSpan, [Ident]), Expr)
220231 updateValue (_, bound) v@(PositionedValue pos' _ _) = return ((Just pos', bound), v)
221232 updateValue (pos, bound) (Abs (Left arg) val') = return ((pos, arg : bound), Abs (Left arg) val')
222− updateValue (pos, bound) (Let ds val') =
233+ updateValue (pos, bound) (Let ds val') = do
223234 let args = mapMaybe letBoundVariable ds
224− in return ((pos, args ++ bound), Let ds val')
235+ unless (length (nub args) == length args) $
236+ throwError $ maybe id (\p e -> positionError p <> e) pos $ 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)
@@ -324,7 +334,7 @@ findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) pri
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-- |
@@ -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+25−10
@@ -21,12 +21,14 @@
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
@@ -103,7 +105,7 @@ customOperatorTable fixities =
103105 in
104106 map (map (\(name, f, _, a) -> (name, f, a))) groups
105107
106−type Chain = [Either Expr (Qualified Ident)]
108+type Chain = [Either Expr Expr]
107109
108110matchOperators :: [[(Qualified Ident, Expr -> Expr -> Expr, Associativity)]] -> Expr -> Either ErrorStack Expr
109111matchOperators ops = parseChains
@@ -112,11 +114,11 @@ matchOperators ops = parseChains
112114 parseChains b@BinaryNoParens{} = bracketChain (extendChain b)
113115 parseChains other = return other
114116 extendChain :: Expr -> Chain
115− extendChain (BinaryNoParens name l r) = Left l : Right name : extendChain r
117+ extendChain (BinaryNoParens op l r) = Left l : Right op : extendChain r
116118 extendChain other = [Left other]
117119 bracketChain :: Chain -> Either ErrorStack Expr
118120 bracketChain = either (Left . (`mkErrorStack` Nothing) . show) Right . P.parse (P.buildExpressionParser opTable parseValue <* P.eof) "operator expression"
119− opTable = [P.Infix (P.try (parseTicks >>= \ident -> return (\t1 t2 -> App (App (Var ident) t1) t2))) P.AssocLeft]
121+ opTable = [P.Infix (P.try (parseTicks >>= \op -> return (\t1 t2 -> App (App op t1) t2))) P.AssocLeft]
120122 : map (map (\(name, f, a) -> P.Infix (P.try (matchOp name) >> return f) (toAssoc a))) ops
121123 ++ [[ P.Infix (P.try (parseOp >>= \ident -> return (\t1 t2 -> App (App (Var ident) t1) t2))) P.AssocLeft ]]
122124
@@ -134,17 +136,30 @@ parseValue = token (either Just (const Nothing)) P.<?> "expression"
134136parseOp :: P.Parsec Chain () (Qualified Ident)
135137parseOp = token (either (const Nothing) fromOp) P.<?> "operator"
136138 where
137− fromOp q@(Qualified _ (Op _)) = Just q
139+ fromOp (Var q@(Qualified _ (Op _))) = Just q
138140 fromOp _ = Nothing
139141
140−parseTicks :: P.Parsec Chain () (Qualified Ident)
141−parseTicks = token (either (const Nothing) fromOp) P.<?> "infix function"
142+parseTicks :: P.Parsec Chain () Expr
143+parseTicks = token (either (const Nothing) fromOther) P.<?> "infix function"
142144 where
143− fromOp q@(Qualified _ (Ident _)) = Just q
144− fromOp _ = Nothing
145+ fromOther (Var (Qualified _ (Op _))) = Nothing
146+ fromOther v = Just v
145147
146148matchOp :: Qualified Ident -> P.Parsec Chain () ()
147149matchOp op = do
148150 ident <- parseOp
149151 guard $ ident == op
150152
153+desugarOperatorSections :: Module -> SupplyT (Either ErrorStack) Module
154+desugarOperatorSections (Module mn ds exts) = Module mn <$> mapM goDecl ds <*> pure exts
155+ where
156+
157+ goDecl :: Declaration -> SupplyT (Either ErrorStack) Declaration
158+ (goDecl, _, _) = everywhereOnValuesM return goExpr return
159+
160+ goExpr :: Expr -> SupplyT (Either ErrorStack) Expr
161+ goExpr (OperatorSection op (Left val)) = return $ App op val
162+ goExpr (OperatorSection op (Right val)) = do
163+ arg <- Ident <$> freshName
164+ return $ Abs (Left arg) $ App (App op (Var (Qualified Nothing arg))) val
165+ goExpr other = return other
src/Language/PureScript/TypeChecker.hs+1−1
@@ -90,7 +90,7 @@ addTypeClass moduleName pn args implies ds =
9090
9191addTypeClassDictionaries :: [TypeClassDictionaryInScope] -> Check ()
9292addTypeClassDictionaries entries =
93− let mentries = M.fromList [ ((canonicalizeDictionary entry, mn), entry) | entry@TypeClassDictionaryInScope{ tcdName = Qualified mn _ } <- entries ]
93+ let mentries = M.fromList [ ((canonicalizeDictionary entry, mn), entry) | entry@TypeClassDictionaryInScope{ tcdName = Qualified mn _ } <- entries ]
9494 in modify $ \st -> st { checkEnv = (checkEnv st) { typeClassDictionaries = (typeClassDictionaries . checkEnv $ st) `M.union` mentries } }
9595
9696checkDuplicateTypeArguments :: [String] -> Check ()
src/Language/PureScript/TypeChecker/Entailment.hs+23−3
@@ -20,6 +20,7 @@ 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
@@ -199,13 +200,32 @@ entails env moduleName context = solve (sortedNubBy canonicalizeDictionary (filt
199200-- and return a substitution from type variables to types which makes the type heads unify.
200201--
201202typeHeadsAreEqual :: ModuleName -> Environment -> Type -> Type -> Maybe [(String, Type)]
202−typeHeadsAreEqual _ _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []
203−typeHeadsAreEqual _ _ t (TypeVar v) = Just [(v, t)]
203+typeHeadsAreEqual _ _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []
204+typeHeadsAreEqual _ _ t (TypeVar v) = Just [(v, t)]
204205typeHeadsAreEqual _ _ (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
206+typeHeadsAreEqual m e (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m e h1 h2
207+ <*> typeHeadsAreEqual m e t1 t2
206208typeHeadsAreEqual m e (SaturatedTypeSynonym name args) t2 = case expandTypeSynonym' e name args of
207209 Left _ -> Nothing
208210 Right t1 -> typeHeadsAreEqual m e t1 t2
211+typeHeadsAreEqual _ _ REmpty REmpty = Just []
212+typeHeadsAreEqual m e r1@(RCons _ _ _) r2@(RCons _ _ _) =
213+ let (s1, r1') = rowToList r1
214+ (s2, r2') = rowToList r2
215+
216+ int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
217+ sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
218+ sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]
219+ in (++) <$> foldMap (\(t1, t2) -> typeHeadsAreEqual m e t1 t2) int
220+ <*> go sd1 r1' sd2 r2'
221+ where
222+ go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Maybe [(String, Type)]
223+ go [] REmpty [] REmpty = Just []
224+ go [] (TUnknown _) _ _ = Just []
225+ go [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = Just []
226+ go [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = Just []
227+ go sd r [] (TypeVar v) = Just [(v, rowFromList (sd, r))]
228+ go _ _ _ _ = Nothing
209229typeHeadsAreEqual _ _ _ _ = Nothing
210230
211231-- |
src/Language/PureScript/TypeChecker/Kinds.hs+69−42
@@ -14,19 +14,22 @@
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)
2627import Data.Monoid ((<>))
28+
2729import qualified Data.HashMap.Strict as H
2830import qualified Data.Map as M
2931
32+import Control.Arrow (second)
3033import Control.Applicative
3134import Control.Monad.Error
3235import Control.Monad.State
@@ -69,11 +72,19 @@ instance Unifiable Check Kind where
6972-- Infer the kind of a single type
7073--
7174kindOf :: ModuleName -> Type -> Check Kind
72−kindOf _ ty =
75+kindOf _ ty = fst <$> kindOfWithScopedVars ty
76+
77+-- |
78+-- Infer the kind of a single type, returning the kinds of any scoped type variables
79+--
80+kindOfWithScopedVars :: Type -> Check (Kind, [(String, Kind)])
81+kindOfWithScopedVars ty =
7382 rethrow (mkErrorStack "Error checking kind" (Just (TypeError ty)) <>) $
74− fmap (starIfUnknown . tidyUp) . liftUnify $ infer ty
83+ fmap tidyUp . liftUnify $ infer ty
7584 where
76− tidyUp (k, sub) = sub $? k
85+ tidyUp ((k, args), sub) = ( starIfUnknown (sub $? k)
86+ , map (second (starIfUnknown . (sub $?))) args
87+ )
7788
7889-- |
7990-- Infer the kind of a type constructor with a collection of arguments and a collection of associated data constructors
@@ -125,7 +136,7 @@ kindsOfAll moduleName syns tys = fmap tidyUp . liftUnify $ do
125136--
126137solveTypes :: Bool -> [Type] -> [Kind] -> Kind -> UnifyT Kind Check Kind
127138solveTypes isData ts kargs tyCon = do
128− ks <- mapM infer ts
139+ ks <- mapM (fmap fst . infer) ts
129140 when isData $ do
130141 tyCon =?= foldr FunKind Star kargs
131142 forM_ ks $ \k -> k =?= Star
@@ -145,48 +156,64 @@ starIfUnknown k = k
145156-- |
146157-- Infer a kind for a type
147158--
148−infer :: Type -> UnifyT Kind Check Kind
159+infer :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
149160infer ty = rethrow (mkErrorStack "Error inferring type of value" (Just (TypeError ty)) <>) $ infer' ty
150161
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
162+infer' :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
167163infer' (ForAll ident ty _) = do
168164 k1 <- fresh
169165 Just moduleName <- checkCurrentModule <$> get
170− k2 <- bindLocalTypeVariables moduleName [(ProperName ident, k1)] $ infer ty
166+ (k2, args) <- bindLocalTypeVariables moduleName [(ProperName ident, k1)] $ infer ty
171167 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
168+ return (Star, (ident, k1) : args)
188169infer' (KindedType ty k) = do
189− k' <- infer ty
170+ (k', args) <- infer ty
190171 k =?= k'
191− return k'
192−infer' _ = error "Invalid argument to infer"
172+ return (k', args)
173+infer' other = (, []) <$> go other
174+ where
175+ go :: Type -> UnifyT Kind Check Kind
176+ go (ForAll ident ty _) = do
177+ k1 <- fresh
178+ Just moduleName <- checkCurrentModule <$> get
179+ k2 <- bindLocalTypeVariables moduleName [(ProperName ident, k1)] $ go ty
180+ k2 =?= Star
181+ return Star
182+ go (KindedType ty k) = do
183+ k' <- go ty
184+ k =?= k'
185+ return k'
186+ go TypeWildcard = fresh
187+ go (TypeVar v) = do
188+ Just moduleName <- checkCurrentModule <$> get
189+ UnifyT . lift $ lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
190+ go (Skolem v _ _) = do
191+ Just moduleName <- checkCurrentModule <$> get
192+ UnifyT . lift $ lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
193+ go c@(TypeConstructor v) = do
194+ env <- liftCheck getEnv
195+ case M.lookup v (types env) of
196+ Nothing -> UnifyT . lift . throwError $ mkErrorStack "Unknown type constructor" (Just (TypeError c))
197+ Just (kind, _) -> return kind
198+ go (TypeApp t1 t2) = do
199+ k0 <- fresh
200+ k1 <- go t1
201+ k2 <- go t2
202+ k1 =?= FunKind k2 k0
203+ return k0
204+ go REmpty = do
205+ k <- fresh
206+ return $ Row k
207+ go (RCons _ ty row) = do
208+ k1 <- go ty
209+ k2 <- go row
210+ k2 =?= Row k1
211+ return $ Row k1
212+ go (ConstrainedType deps ty) = do
213+ forM_ deps $ \(className, tys) -> do
214+ _ <- go $ foldl TypeApp (TypeConstructor className) tys
215+ return ()
216+ k <- go ty
217+ k =?= Star
218+ return Star
219+ go _ = error "Invalid argument to infer"
src/Language/PureScript/TypeChecker/Monad.hs+13−4
@@ -23,6 +23,7 @@ import qualified Data.Map as M
2323
2424import Control.Applicative
2525import Control.Monad.Error
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--
@@ -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/Skolems.hs+1
@@ -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/Types.hs+24−26
@@ -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
@@ -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,9 +291,10 @@ 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'
299299infer' (PositionedValue pos _ val) = rethrowWithPosition pos $ infer' val
300300infer' _ = error "Invalid argument to infer"
@@ -303,10 +303,11 @@ inferLetBinding :: [Declaration] -> [Declaration] -> Expr -> (Expr -> UnifyT Typ
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
@@ -506,14 +507,15 @@ check' (SuperClassDictionary className tys) _ = do
506507 return $ TypeClassDictionary False (className, tys) dicts
507508check' (TypedValue checkType val ty1) ty2 = do
508509 Just moduleName <- checkCurrentModule <$> get
509− checkTypeKind moduleName ty1
510+ (kind, args) <- liftCheck $ kindOfWithScopedVars ty1
511+ checkTypeKind kind
510512 ty1' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty1
511513 ty2' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty2
512514 val' <- subsumes (Just val) ty1' ty2'
513515 case val' of
514516 Nothing -> throwError . strMsg $ "Unable to check type subsumption"
515517 Just val'' -> do
516− val''' <- if checkType then check val'' ty2' else return val''
518+ val''' <- if checkType then withScopedTypeVars moduleName args (check val'' ty2') else return val''
517519 return $ TypedValue checkType (TypedValue True val''' ty1') ty2'
518520check' (Case vals binders) ret = do
519521 vals' <- mapM infer vals
@@ -561,11 +563,11 @@ check' val ty | containsTypeSynonyms ty = do
561563 ty' <- introduceSkolemScope <=< expandAllTypeSynonyms <=< replaceTypeWildcards $ ty
562564 check val ty'
563565check' val kt@(KindedType ty kind) = do
564− guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
566+ checkTypeKind kind
565567 val' <- check' val ty
566568 return $ TypedValue True val' kt
567569check' (PositionedValue pos _ val) ty =
568− rethrowWithPosition pos $ check val ty
570+ rethrowWithPosition pos $ check' val ty
569571check' val ty = throwError $ mkErrorStack ("Expr does not have type " ++ prettyPrintType ty) (Just (ExprError val))
570572
571573containsTypeSynonyms :: Type -> Bool
@@ -581,18 +583,14 @@ containsTypeSynonyms = everythingOnTypes (||) go where
581583checkProperties :: [(String, Expr)] -> Type -> Bool -> UnifyT Type Check [(String, Expr)]
582584checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
583585 go [] [] REmpty = return []
584− go [] [] u@(TUnknown _) = do u =?= REmpty
585− return []
586+ go [] [] u@(TUnknown _)
587+ | lax = return []
588+ | otherwise = do u =?= REmpty
589+ return []
586590 go [] [] Skolem{} | lax = return []
587591 go [] ((p, _): _) _ | lax = return []
588592 | otherwise = throwError $ mkErrorStack ("Object does not have property " ++ p) (Just (ExprError (ObjectLiteral ps)))
589593 go ((p,_):_) [] REmpty = throwError $ mkErrorStack ("Property " ++ p ++ " is not present in closed object type " ++ prettyPrintRow row) (Just (ExprError (ObjectLiteral ps)))
590− go ((p,v):ps') [] u@(TUnknown _) = do
591− v'@(TypedValue _ _ ty) <- infer v
592− rest <- fresh
593− u =?= RCons p ty rest
594− ps'' <- go ps' [] rest
595− return $ (p, v') : ps''
596594 go ((p,v):ps') ts r =
597595 case lookup p ts of
598596 Nothing -> do
src/Language/PureScript/TypeChecker/Unify.hs+22−1
@@ -130,6 +130,10 @@ unifyRows r1 r2 =
130130 rest <- fresh
131131 u1 =:= rowFromList (sd2, rest)
132132 u2 =:= rowFromList (sd1, rest)
133+ unifyRows' sd1 (SaturatedTypeSynonym name args) sd2 r2' = do
134+ r1' <- expandTypeSynonym name $ args
135+ unifyRows (rowFromList (sd1, r1')) (rowFromList (sd2, r2'))
136+ unifyRows' sd1 r1' sd2 r2'@(SaturatedTypeSynonym _ _) = unifyRows' sd2 r2' sd1 r1'
133137 unifyRows' [] REmpty [] REmpty = return ()
134138 unifyRows' [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = return ()
135139 unifyRows' [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = return ()
@@ -149,6 +153,23 @@ unifiesWith e (SaturatedTypeSynonym name args) t2 =
149153 Left _ -> False
150154 Right t1 -> unifiesWith e t1 t2
151155unifiesWith e t1 t2@(SaturatedTypeSynonym _ _) = unifiesWith e t2 t1
156+unifiesWith _ REmpty REmpty = True
157+unifiesWith e r1@(RCons _ _ _) r2@(RCons _ _ _) =
158+ let (s1, r1') = rowToList r1
159+ (s2, r2') = rowToList r2
160+
161+ int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
162+ sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
163+ sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]
164+ in all (\(t1, t2) -> unifiesWith e t1 t2) int && go sd1 r1' sd2 r2'
165+ where
166+ go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Bool
167+ go [] REmpty [] REmpty = True
168+ go [] (TypeVar v1) [] (TypeVar v2) = v1 == v2
169+ go [] (Skolem _ s1 _) [] (Skolem _ s2 _) = s1 == s2
170+ go _ (TUnknown _) _ _ = True
171+ go _ _ _ (TUnknown _) = True
172+ go _ _ _ _ = False
152173unifiesWith _ _ _ = False
153174
154175-- |
@@ -158,7 +179,7 @@ replaceVarWithUnknown :: String -> Type -> UnifyT Type Check Type
158179replaceVarWithUnknown ident ty = do
159180 tu <- fresh
160181 return $ replaceTypeVars ident tu ty
161−
182+
162183-- |
163184-- Replace type wildcards with unknowns
164185--
tests/Main.hs+5−4
@@ -22,6 +22,7 @@ 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
@@ -35,10 +36,10 @@ readInput inputFiles = forM inputFiles $ \inputFile -> do
3536 return (inputFile, text)
3637
3738loadPrelude :: Either String (String, String, P.Environment)
38−loadPrelude =
39+loadPrelude =
3940 case P.parseModulesFromFiles id [("", P.prelude)] of
4041 Left parseError -> Left (show parseError)
41− 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" [] [] }
4243
4344compile :: P.Options P.Compile -> [FilePath] -> IO (Either String (String, String, P.Environment))
4445compile opts inputFiles = do
@@ -46,7 +47,7 @@ compile opts inputFiles = do
4647 case modules of
4748 Left parseError ->
4849 return (Left $ show parseError)
49− Right ms -> return $ P.compile opts (map snd ms) []
50+ Right ms -> return $ runReaderT (P.compile (map snd ms) []) opts
5051
5152assert :: FilePath -> P.Options P.Compile -> FilePath -> (Either String (String, String, P.Environment) -> IO (Maybe String)) -> IO ()
5253assert preludeExterns opts inputFile f = do
@@ -85,7 +86,7 @@ findNodeProcess = runMaybeT . msum $ map (MaybeT . findExecutable) names
8586
8687main :: IO ()
8788main = do
88− putStrLn "Compiling Prelude"
89+ putStrLn "Compiling Prelude"
8990 case loadPrelude of
9091 Left err -> putStrLn err >> exitFailure
9192 Right (preludeJs, exts, _) -> do