@@ -0,0 +1,235 @@
3+The type system defines the following types:
10+ - E.g. `[String]`, `[[Number]]`
12+ - E.g. `{ foo :: String, bar :: Number }`
14+ - E.g. `data Foo a = Foo | Bar String`
16+ - E.g. `Number -> String`
17+ - E.g. `(Number, Number) -> Number`
18+ - Functions can have zero or more arguments
20+ - E.g. `forall a. a -> a`
24+The three primitive types `String`, `Number` and `Boolean` correspond to their Javascript equivalents at runtime.
26+PureScript supports the same binary and unary operations on primitive types as Javascript, with the following exceptions:
28+- String concatenation is denoted `++` to differentiate it from numeric addition, `+`
29+- PureScript's `==` and `!=` correspond to Javascript's strong equality tests `===` and `!==`
35+str = "Hello, " ++ "World!"
41+PureScript arrays correspond to Javascript arrays at runtime, but all elements must have the same type.
43+Array literals look like Javascript array literals: `[1, 2, 3]`
45+Array elements can be read using array index notation `arr !! index`
49+PureScript records correspond to Javascript objects.
51+Record literals look like Javascript object literals: `{ foo: "Foo" }`
53+Properties can be read by using dot notation: `o.foo`
57+Tagged unions consist of one or more constructors, each of which takes zero or one arguments.
59+Tagged unions can only be created using their constructors, and deconstructed through pattern matching (see later).
64+data Foo a = Foo | Bar String
66+runFoo Foo = "It's a Foo"
67+runFoo (Bar s) = "It's a Bar. The string is " ++ s
69+test = runFoo Foo ++ runFoo (Bar "Test")
72+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.
74+`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.
78+Functions in PureScript can have zero or more arguments in general, just like in Javascript.
80+Functions are introduced by using a backslash followed by a list of argument names:
86+which would correspond to the Javascript
90+ return function (b) {
96+Multiple argument functions can be introduced by wrapping the arguments in parentheses, and separating them with commas:
99+test1 = \(a, b) -> a + b
105+function test1(a, b) {
110+In the case of a function with no arguments, the parentheses may be omitted, as follows:
116+which would correspond to the Javascript `function test2() { return 100; }`
118+Multiple-argument and single-argument syntax can be mixed, as follows:
121+test3 = \a (b, c) d -> a + b + c + d
128+ return function (b, c) {
129+ return function (d) {
130+ return a + b + c + d;
136+Functions are applied by providing their arguments inside parentheses:
143+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:
146+-- has type Number -> Number -> Number -> Number
147+addThree = \a b c -> a + b + c
149+-- has type Number -> Number -> Number
152+-- has type Number -> Number
161+Expressions defined at the top level may have polymorphic types.
169+`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.
171+A type annotation can also be provided:
174+identity :: forall a. a -> a
178+Functions may also be polymorphic in row types or type variables with other kinds (see "Kind System"):
181+addProps o = o.foo + o.bar
184+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*.
186+So, the following compiles:
189+addProps { foo: 1, bar: 2, baz: 3 }
192+but the following does not:
198+since the `bar` property is missing.
200+Again, a type annotation can be provided if necessary.
204+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.
206+In most cases, a type annotation is necessary when using this feature.
208+As an example, we can pass a polymorphic function as an argument to another function:
211+poly :: (forall a. a -> a) -> Boolean
212+poly f = (f 0 < 1) == f true
215+Notice that the polymorphic function's type argument is instantiated to both `Number` and `Boolean`.
217+An argument to `poly` must indeed be polymorphic. For example, the following fails:
220+test = poly (\n -> n + 1)
223+since the skolemized type variable `a` does not unify with `Number`.
227+All types can be inferred, but annotations can optionally be provided.
231+There are two primitive kinds, the kind `*` of types and the kind `!` of effects.
233+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.
235+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.