@@ -3,879 +3,15 @@ purescript
33
44[](http://travis-ci.org/paf31/purescript)
55
6−A small strongly, statically typed compile-to-JS language with basic extensible records and type-safe blocks
6+PureScript is a small strongly, statically typed programming language with expressive types, written in and inspired by Haskell, and compiling to Javascript.
77
88Bitcoin donations are gratefully accepted at 14ZhCym28WDuFhocP44tU1dBpCzjX1DvhF.
99
10−## Current Features
10+## Resources
1111
12−- Full Type Inference
13−- Higher Kinded Polymorphism
14−- Support for basic Javascript types
15−- Extensible records
16−- Type-safe blocks with for/while/assignment etc.
17−- Functions with multiple arguments
18−- Pattern matching
19−- Simple FFI
20−- Modules
21−- Rank N Types
22−- Do Notation
23−- Optional tail-call elimination
24−- Type Classes
25−
26−## Try It!
27−
28−Try PureScript in the browser [here](http://tryps.functorial.com/).
29−
30−## License
31−
32−See the `LICENSE` file
33−
34−## Contributing
35−
36−Contributions are always encouraged! Please see `CONTRIBUTING.md` for guidelines.
37−
38−- Join the discussion on FreeNode at <a href="irc://irc.freenode.net/#purescript">#purescript</a>.
39−- Follow @purescript on Twitter for development updates
40−
41−## Installation
42−
43−Install the Haskell Plaform, then `cabal install`
44−
45−## Usage
46−
47−The `psc` executable takes a list of PureScript source files as arguments and by default writes out its errors or output to the console.
48−
49−The following options are supported:
50−
51− -s --stdin
52− Read input from standard input instead of from files
53−
54− -o --output
55− Write the generated Javascript to the specified file
56−
57− -e --foreign imports
58− Write a list of foreign imports declarations to the specified file in addition to generating Javascript output
59−
60− --runtime-type-checks
61− Generate simple runtime type checks for function arguments with simple types.
62−
63− --tco
64− Perform tail-call elimination on the generated Javascript.
65−
66− --no-prelude
67− Do not include the Prelude in the generated Javascript.
68−
69− --magic-do
70− Overload the `do` keyword to inline calls to `bind` for the `Eff` monad, to generate more efficient code.
71−
72− --run-main
73− Generate a call to `Main.main` after all other generated Javascript.
74−
75−## Motivation
76−
77−I was looking for a simple functional language which would compile to JavaScript and have the following characteristics:
78−
79−- Generate simple readable Javascript
80−- Provide the ability to compile to tight loops if necessary
81−- Reasonable type system
82−- Ideally, written in a programming language I would enjoy working in
83−- Provides a simple interface to existing Javascript code
84−
85−I didn't find exactly what I was looking for, so I wrote PureScript. It doesn't have everything right now, but it should serve as a simple core on which to develop new ideas.
86−
87−PureScript is *not* designed to be a general-purpose programming language. The primary use case is as a generator for purely-functional core libraries, with the main application code written in another language.
88−
89−PureScript can also be seen as a trade-off between a theoretically ideal language and one which generates reasonably high performance code.
90−
91−## Hello, PureScript!
92−
93−As an introductory example, here is the usual "Hello World" written in PureScript:
94−
95−```haskell
96−module Main where
97−
98−import Trace
99−
100−main = trace "Hello, World!"
101−```
102−
103−which compiles to the following Javascript, ignoring the Prelude:
104−
105−```javascript
106−var Main;
107−(function (Main) {
108− var main = trace("Hello, World!");
109− Main.main = main;
110−})(Main = Main || {});
111−```
112−
113−The following command will compile and execute the PureScript code above:
114−
115−```
116−psc input.purs --run-main | nodejs
117−```
118−
119−## Another Example
120−
121−The following code defines a `Person` data type and a function to generate a string representation for a `Person`:
122−
123−```haskell
124−data Person = Person { name :: String, age :: Number }
125−
126−foreign import numberToString :: Number -> String
127−
128−showPerson :: Person -> String
129−showPerson (Person o) = o.name ++ ", aged " ++ numberToString(o.age)
130−```
131−
132−Line by line, this reads as follows:
133−
134−- `Person` is a data type with one constructor, also called `Person`
135− - The `Person` constructor takes an object with two properties, `name` which is a `String`, and `age` which is a `Number`
136−- The `numberToString` function is written in Javascript, and converts a `Number` to its `String` representation
137−- The `showPerson` function takes a `Person` and returns a `String`
138−- `showPerson` works by case analysis on its argument, first matching the constructor `Person` and then using string concatenation and object accessors to return its result.
139−
140−The generated Javascript looks like this:
141−
142−```javascript
143−var Person = function (value) {
144− return { ctor: 'Person', value: value };
145−};
146−
147−function showPerson(_1) {
148− if (_1.ctor === "Person") {
149− return _1.value.name + ", aged " + numberToString(_1.value.age);
150− };
151− throw "Failed pattern match";
152−};
153−
154−```
155−
156−## Type System
157−
158−The type system defines the following types:
159−
160−- Primitive Types
161− - Number
162− - String
163− - Boolean
164−- Arrays
165− - E.g. `[String]`, `[[Number]]`
166−- Records
167− - E.g. `{ foo :: String, bar :: Number }`
168−- Tagged Unions
169− - E.g. `data Foo a = Foo | Bar String`
170−- Functions
171− - E.g. `Number -> String`
172− - E.g. `(Number, Number) -> Number`
173− - Functions can have zero or more arguments
174−- Polymorphic types
175− - E.g. `forall a. a -> a`
176−
177−## Primitive Types
178−
179−The three primitive types `String`, `Number` and `Boolean` correspond to their Javascript equivalents at runtime.
180−
181−PureScript supports the same binary and unary operations on primitive types as Javascript, with the following exceptions:
182−
183−- String concatenation is denoted `++` to differentiate it from numeric addition, `+`
184−- PureScript's `==` and `!=` correspond to Javascript's strong equality tests `===` and `!==`
185−
186−Examples:
187−
188−```haskell
189−num = 1 + 2 * 3
190−str = "Hello, " ++ "World!"
191−bool = 1 > 2 || true
192−```
193−
194−## Arrays
195−
196−PureScript arrays correspond to Javascript arrays at runtime, but all elements must have the same type.
197−
198−Array literals look like Javascript array literals: `[1, 2, 3]`
199−
200−Array elements can be read using array index notation `arr !! index`
201−
202−## Records
203−
204−PureScript records correspond to Javascript objects.
205−
206−Record literals look like Javascript object literals: `{ foo: "Foo" }`
207−
208−Properties can be read by using dot notation: `o.foo`
209−
210−## Tagged Unions
211−
212−Tagged unions consist of one or more constructors, each of which takes zero or one arguments.
213−
214−Tagged unions can only be created using their constructors, and deconstructed through pattern matching (see later).
215−
216−For example:
217−
218−```haskell
219−data Foo a = Foo | Bar String
220−
221−runFoo Foo = "It's a Foo"
222−runFoo (Bar s) = "It's a Bar. The string is " ++ s
223−
224−test = runFoo Foo ++ runFoo (Bar "Test")
225−```
226−
227−In the example, Foo is a tagged union type which has two constructors. It's first constructor `Foo` takes no argument, and it's second `Bar` takes one, which must be a String.
228−
229−`runFoo` is an example of pattern matching on a tagged union type to discover its constructor, and the last line shows how `Foo`s are constructed.
230−
231−## Functions
232−
233−Functions in PureScript can have zero or more arguments in general, just like in Javascript.
234−
235−Functions are introduced by using a backslash followed by a list of argument names:
236−
237−```haskell
238−test1 = \a b -> a + b
239−```
240−
241−which would correspond to the Javascript
242−
243−```javascript
244−function test1(a) {
245− return function (b) {
246− return a + b;
247− }
248−}
249−```
250−
251−Multiple argument functions can be introduced by wrapping the arguments in parentheses, and separating them with commas:
252−
253−```haskell
254−test1 = \(a, b) -> a + b
255−```
256−
257−which generates
258−
259−```javascript
260−function test1(a, b) {
261− return a + b;
262−}
263−```
264−
265−In the case of a function with no arguments, the parentheses may be omitted, as follows:
266−
267−```haskell
268−test2 = \ -> 100
269−```
270−
271−which would correspond to the Javascript `function test2() { return 100; }`
272−
273−Multiple-argument and single-argument syntax can be mixed, as follows:
274−
275−```haskell
276−test3 = \a (b, c) d -> a + b + c + d
277−```
278−
279−which generates
280−
281−```javascript
282−function test3(a) {
283− return function (b, c) {
284− return function (d) {
285− return a + b + c + d;
286− }
287− }
288−}
289−```
290−
291−Functions are applied by providing their arguments inside parentheses:
292−
293−```haskell
294−test1(1, 2, 3)
295−test2()
296−```
297−
298−A special case is made in the case of functions with one argument. These functions can be applied without parentheses, and function application associates to the left:
299−
300−```haskell
301−-- has type Number -> Number -> Number -> Number
302−addThree = \a b c -> a + b + c
303−
304−-- has type Number -> Number -> Number
305−addThree 1
306−
307−-- has type Number -> Number
308−addThree 1 2
309−
310−-- has type Number
311−addThree 1 2 3
312−```
313−
314−## Polymorphic Types
315−
316−Expressions defined at the top level may have polymorphic types.
317−
318−Here is an example:
319−
320−```haskell
321−identity x = x
322−```
323−
324−`identity` is inferred to have (polymorphic) type `forall t0. t0 -> t0`. This means that for any type `t0`, `identity` can be given a value of type `t0` and will give back a value of the same type.
325−
326−A type annotation can also be provided:
327−
328−```haskell
329−identity :: forall a. a -> a
330−identity x = x
331−```
332−
333−Functions may also be polymorphic in row types or type variables with other kinds (see "Kind System"):
334−
335−```haskell
336−addProps o = o.foo + o.bar
337−```
338−
339−Here, `addProps` is inferred to have type `forall r. { foo :: Number, bar :: Number | r } -> Number`. That is, it can take any type which has properties `Foo` and `Bar`, and *any other record properties*.
340−
341−So, the following compiles:
342−
343−```haskell
344−addProps { foo: 1, bar: 2, baz: 3 }
345−```
346−
347−but the following does not:
348−
349−```haskell
350−addProps { foo: 1 }
351−```
352−
353−since the `bar` property is missing.
354−
355−Again, a type annotation can be provided if necessary.
356−
357−## Rank N Types
358−
359−It is also possible for the `forall` quantifier to appear on the left of a function arrow, inside types record fields and data constructors, and in type synonyms.
360−
361−In most cases, a type annotation is necessary when using this feature.
362−
363−As an example, we can pass a polymorphic function as an argument to another function:
364−
365−```haskell
366−poly :: (forall a. a -> a) -> Boolean
367−poly f = (f 0 < 1) == f true
368−```
369−
370−Notice that the polymorphic function's type argument is instantiated to both `Number` and `Boolean`.
371−
372−An argument to `poly` must indeed be polymorphic. For example, the following fails:
373−
374−```haskell
375−test = poly (\n -> n + 1)
376−```
377−
378−since the skolemized type variable `a` does not unify with `Number`.
379−
380−## Type Inference
381−
382−All types can be inferred, but annotations can optionally be provided.
383−
384−## Kind System
385−
386−There are two primitive kinds, the kind `*` of types and the kind `!` of effects.
387−
388−For each kind `k` there is also a kind `# k` of rows, with types of kind `k`. For example `# *` is the kind of rows of types, as used to define records, and `# !` is the kind of rows of effects, used to define the monad `Eff` of extensible effects.
389−
390−Higher kinded types are also supported. That is, a type variable can refer to not only a type or a row, but a type constructor, or row constructor etc.
391−
392−## Whitespace
393−
394−Syntax is whitespace sensitive. The general rule of thumb is that declarations which span multiple lines should be indented past the column on which they were first defined on their subsequent lines.
395−
396−That is, the following is valid:
397−
398−```haskell
399−foo = bar(x) +
400− baz(x)
401−```
402−
403−But this is not:
404−
405−```haskell
406−foo = bar(x) +
407−baz(x)
408−```
409−
410−## Blocks
411−
412−Blocks are collections of statements wrapped in braces `{ ... }`. Blocks must return a value of the same type on every branch of execution.
413−
414−The following types of statement are supported:
415−
416−- Variable introduction
417−- Variable assignment
418−- For loops
419−- For-each loops
420−- While loops
421−- If-Then-Else statements
422−
423−Here is an example of a power function defined using a block:
424−
425−```haskell
426−pow n p = {
427− var m = n;
428− for (i <- 0 until p) {
429− m = m * n;
430− }
431− return m;
432− }
433−```
434−
435−Blocks enable local mutation of their variables, but mutation is not allowed in general. The type system prevents mutable variables from escaping their scope.
436−
437−That is, while the example above is valid, the following does not compile:
438−
439−```haskell
440−incr n = {
441− n = n + 1;
442− return n;
443− }
444−```
445−
446−The variable `n` is not mutable, and so the assignment in the first line of the `do` block is not allowed.
447−
448−This function can be rewritten as follows:
449−
450−```haskell
451−incr n = {
452− var m = n;
453− m = m + 1;
454− return m;
455− }
456−```
457−
458−## For Loops
459−
460−For loops look like this:
461−
462−```haskell
463−total = {
464− var n = 0;
465− for (i <- 0 until 10) {
466− n = n + i;
467− }
468− return n;
469− }
470−```
471−
472−The bounds `0` and `10` are inclusive and exclusive respectively.
473−
474−## For-Each Loops
475−
476−For each loops loop over the elements in an array using the `Object.forEach` method. A polyfill may be required for some browsers:
477−
478−```haskell
479−total arr = {
480− var n = 0;
481− foreach (i in arr) {
482− n = n + i;
483− }
484− return n;
485− }
486−```
487−
488−## While Loops
489−
490−The syntax of a while loop is similar to a foreach loop:
491−
492−```haskell
493−log2 n = {
494− var count = 0;
495− var m = n;
496− while (m > 1) {
497− m = m / 2;
498− count = count + 1;
499− }
500− return count;
501− }
502−```
503−
504−## If-Then-Else Statements
505−
506−Else branches are optional, and may contain further `if` statements, just as in Javascript:
507−
508−```haskell
509−collatz n = {
510− var count = 0;
511− var m = n;
512− while (m > 1) {
513− if (m % 2 == 0) {
514− m = m / 2;
515− } else {
516− m = m * 3 + 1;
517− }
518− count = count + 1;
519− }
520− return count;
521− }
522−```
523−
524−## If-Then-Else Expressions
525−
526−The `if`, `then` and `else` keywords can also be used to create conditional expressions. In this case, the `else` block is always required.
527−
528−For example,
529−
530−```haskell
531−conditional = if 2 > 1 then "ok" else "oops"
532−```
533−
534−## Do Notation
535−
536−The `do` keyword introduces simple syntactic sugar for monadic expressions.
537−
538−Here is an example, using the maybe monad:
539−
540−```haskell
541−data Maybe a = Nothing | Just a
542−
543−instance Monad Maybe where
544− ret = Just
545− (>>=) Nothing _ = Nothing
546− (>>=) (Just a) f = f a
547−
548−isEven n | n % 2 == 0 = Just {}
549−isEven _ = Nothing
550−
551−evenSum a b = do
552− n <- a
553− m <- b
554− let sum = n + m
555− isEven sum
556− ret sum
557−```
558−
559−`isEven` adds two values of type `Maybe Number` and returns their sum, if the sum is even. If the sum is odd, `evenSum` returns `Nothing`.
560−
561−This example illustrates the following aspects of `do` notation:
562−
563−- The corresponding type constructor must be an instance of the `Prelude.Monad` type class, which defines the `ret` and `>>=` functions.
564−- Statements can have the following form:
565− - `a <- x` which desugars to `m.bind x (\a -> ...)`
566− - `let a = x` which desugars to `(\a -> ...)(x)`
567− - `x` which desugars to `m.bind x (\_ -> ...)` or just `x` if this is the last statement.
568−
569−Not illustrated here, but equally valid is the use of a binder on the left hand side of `<-` or `=`. For example:
570−
571−```haskell
572−test arr = do
573− (x:y:_) <- arr
574− ret (x + y)
575−```
576−
577−A pattern match failure will generate a runtime exception, just as in the case of a regular `case` statement.
578−
579−## Pattern Matching
580−
581−Pattern matching deconstructs a value to bring zero or more expressions into scope. Pattern matches are introduced with the `case` keyword.
582−
583−Pattern matches have the following general form
584−
585−```haskell
586−case value of
587− pattern -> result
588− -- ...
589− pattern -> result
590−```
591−
592−Pattern matching can also be used in the declaration of functions, as we have already seen:
593−
594−```haskell
595−fn pattern_1 ... pattern_n = result
596−```
597−
598−Any of the above types of pattern are also valid when introducing functions. In addition, patterns can also be grouped in parentheses to introduce multiple-arugument functions. For example,
599−
600−```haskell
601−example x (y, z) w = x * y + z * w
602−```
603−
604−The following pattern types are supported:
605−
606−- Wildcard pattern
607−- Literal patterns
608−- Variable pattern
609−- Array patterns
610−- Cons patterns
611−- Record patterns
612−- Named patterns
613−- Guards
614−
615−Patterns need not be exhaustive. A pattern match failed exception will be thrown at runtime if no pattern matches the input.
616−
617−## Wildcard Patterns
618−
619−The wilcard `_` matches any input and brings nothing into scope:
620−
621−```haskell
622−case x of
623− _ -> 0
624−```
625−
626−## Literal Patterns
627−
628−Literal patterns are provided to match on primitives:
629−
630−```haskell
631−case booleanValue of
632− true -> 0
633− false -> 1
634−
635−case stringValue of
636− "Foo" -> 0
637− _ -> 1
638−
639−case numericValue of
640− 0 -> 0
641− _ -> 1
642−```
643−
644−## Variable Pattern
645−
646−A variable pattern matches any input and binds that input to its name:
647−
648−```haskell
649−case foo(x) of
650− result -> bar(result)
651−```
652−
653−## Array Patterns
654−
655−Array patterns match an input which is an array, and bring its elements into scope.
656−
657−For example:
658−
659−```haskell
660−f = \arr -> case arr of
661− [x] -> x
662− [x, y] -> x * y + f xs
663− _ -> 0
664−```
665−
666−Here, the first pattern only matches arrays of length one, and brings the first element of the array into scope.
667−
668−The second pattern matches arrays with two elements, and brings the first and second elements into scope.
669−
670−## Cons Patterns
671−
672−The head and tail of a non-empty array can be matched by using a cons pattern:
673−
674−```haskell
675−add = \arr -> case arr of
676− [] -> 0
677− x : xs -> x + add xs
678−```
679−
680−`:` associates to the right:
681−
682−```haskell
683−addPairs = \arr -> case arr of
684− x : y : xs -> x * y + addPairs xs
685− _ -> 0
686−```
687−
688−## Record Patterns
689−
690−Record patterns match an input which is a record, and bring its properties into scope.
691−
692−```haskell
693−f = \o -> case o of
694− { foo = "Foo" } -> o.bar
695− _ -> 0
696−```
697−
698−## Nested Patterns
699−
700−The patterns above can be combined to create larger patterns.
701−
702−For example:
703−
704−```haskell
705−f = \o -> case o of
706− { arr = x : _, take = "car" } -> x
707− { arr = _ : x : _, take = "cadr" } -> x
708− _ -> 0
709−```
710−
711−## Named Patterns
712−
713−Named patterns bring additional names into scope when using nested patterns. Any pattern can be named by using the `@` symbol:
714−
715−```haskell
716−f = \arr -> case arr of
717− a@(_ : _ : _) -> true
718− a -> false
719−```
720−
721−Here, in the first pattern, any array with two or more elements will be matched and bound to the variable `a`.
722−
723−## Guards
724−
725−Guards are used to impose additional constraints inside a pattern using boolean-valued expressions, and are introduced with a pipe after the pattern:
726−
727−```haskell
728−evens = \arr -> case arr of
729− [] -> 0
730− x : xs | x % 2 == 0 -> 1 + evens xs
731− _ : xs -> evens xs
732−```
733−
734−When defining a function, guards appear after all patterns:
735−
736−```haskell
737−greater x y | x > y = true
738−greater _ _ = false
739−```
740−
741−## Type Synonyms
742−
743−For convenience, it is possible to declare a synonym for a type using the `type` keyword. Type synonyms can include type arguments.
744−
745−For example:
746−
747−```haskell
748−type Foo = { foo :: Number, bar Number }
749−
750−addFoo :: Foo -> Number
751−addFoo = \o -> o.foo + o.bar
752−```
753−## Record Updates
754−
755−Properties on records can be updated using the following syntax: `o { key = value, ..., key = value }`
756−
757−For example, the following function increments the `foo` property on its argument:
758−
759−```haskell
760−incr = \o -> o { foo = o.foo + 1 }
761−```
762−
763−The generated Javascript assumes the existence of a method called `Object.extend` such that `Object.extend(o, p)` takes an object `o` and generates a shallow copy of `o` including the properties of `p`. A simple JQuery implementation of this specification is
764−
765−```haskell
766−Object.prototype.extend = function(o, p) {
767− return $.extend({}, o, p);
768−};
769−```
770−
771−## Operators
772−
773−In addition to the standard operators, user-defined infix operators can be created by enclosing names in parentheses:
774−
775−E.g. to create a synonym for string concatenation:
776−
777−```haskell
778−(<>) = \s1 s2 -> s1 ++ s2
779−
780−greeting = "Hello" <> "World!"
781−```
782−
783−Regular functions can be used as operators by enclosing their names in backticks:
784−
785−```haskell
786−foo = \x y -> x * y + y
787−
788−test = 10 `foo` 20
789−```
790−
791−Fixity declarations can associate a precedence level, which is a natural number, to a user-defined operator, and specify which way it associates:
792−
793−```haskell
794−infixl 5 <>
795−infixr 7 %%
796−```
797−
798−## Modules
799−
800−Modules are introduced using the `module` keyword. All code must be placed in a module.
801−
802−Introduce a module as follows, with a list of declarations:
803−
804−```haskell
805−module A where
806−
807−id x = x
808−```
809−
810−Names may be qualified by using a dot:
811−
812−```
813−foo = A.foo
814−bar = A.B.bar
815−```
816−
817−All the names in a module can be aliased using the `import` declaration:
818−
819−```haskell
820−import A
821−```
822−
823−You can also limit which names are going to be aliased:
824−
825−```haskell
826−import A.B (bar)
827−```
828−
829−## Foreign Function Interface
830−
831−The `foreign import` keyword declares a value which is defined in Javascript, and its type:
832−
833−```haskell
834−foreign import pow :: (Number, Number) -> Number
835−```
836−
837−To declare a new type with no constructors, use `foreign import data` and provide the kind:
838−
839−```haskell
840−foreign import data IO :: * -> *
841−
842−foreign import console :: {
843− log :: String -> IO {}
844−}
845−```
846−
847−To alias a name of a field defined on a Javascript type to a PureScript function, use `foreign import member`. For example, to define a function `length` which accesses the `length` member of an array:
848−
849−```haskell
850−foreign import member "length" length :: forall a. [a] -> Number
851−```
852−
853−## Type Classes
854−
855−PureScript has basic support for type classes via the `class` and `instance` keywords.
856−
857−Type class instances must be of the form `String`, `Number`, `Boolean`, `[t]` or `C t1 ... tn`, and only a single type class parameter is supported.
858−
859−Type class instances are resolved based on the order in which they appeared in the source files. In particular, overlapping instances are permitted.
860−
861−```haskell
862−class Show a where
863− show :: a -> String
864−
865−instance Show String where
866− show s = s
867−
868−instance Show Boolean where
869− show true = "true"
870− show false = "false"
871−
872−instance (Show a) => Show [a] where
873− show arr = "[" ++ showArray arr ++ "]"
874−
875−showArray :: forall a. (Show a) => [a] -> String
876−showArray [] = ""
877−showArray [x] = show x
878−showArray (x:xs) = show x ++ ", " ++ showArray xs
879−
880−example = show [true, false]
881−```
12+- [Documentation](http://purescript.readthedocs.org/)
13+- [#purescript IRC @ FreeNode](irc://irc.freenode.net/#purescript)
14+- [Twitter](http://twitter.com/purescript)
15+- [Try PureScript!](http://tryps.functorial.com/)
16+- [Release Notes](https://github.com/paf31/purescript/blob/master/RELEASE.md)
17+- [Contributing to PureScript](https://github.com/paf31/purescript/blob/master/CONTRIBUTING.md)