git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Update README.md
e417bffTenor Biel
README.md+246−168
@@ -56,16 +56,18 @@ PureScript can also be seen as a trade-off between a theoretically ideal languag
56
56
57The following code defines a `Person` data type and a function to generate a string representation for a `Person`:
57The following code defines a `Person` data type and a function to generate a string representation for a `Person`:
58
58
59+```haskell
59− data Person = Person
60+data Person = Person
60− { name :: String
61+{ name :: String
61− ; age :: Number
62+; age :: Number
62− }
63+}
63−
64+
64− extern itoa :: Number -> String
65+extern itoa :: Number -> String
65−
66+
66− showPerson :: Person -> String
67+showPerson :: Person -> String
67− showPerson = \p -> case p of
68+showPerson = \p -> case p of
68− Person o -> o.name ++ ", aged " ++ itoa(o.age)
69+Person o -> o.name ++ ", aged " ++ itoa(o.age)
70+```
69
71
70Line by line, this reads as follows:
72Line by line, this reads as follows:
71
73
@@ -77,20 +79,22 @@ Line by line, this reads as follows:
77
79
78The generated Javascript looks like this:
80The generated Javascript looks like this:
79
81
82+```javascript
80− var Person = function (value) {
83+var Person = function (value) {
81− return { ctor: 'Person', value: value };
84+return { ctor: 'Person', value: value };
82− };
85+};
83−
86+
84− var showPerson = function (p) {
87+var showPerson = function (p) {
85− return (function (_0) {
88+return (function (_0) {
86− if (_0.ctor === "Person") {
89+if (_0.ctor === "Person") {
87− var _1 = _0.value;
90+ var _1 = _0.value;
88− var o = _1;
91+ var o = _1;
89− return o.name ++ ", aged " ++ itoa(o.age);
92+ return o.name ++ ", aged " ++ itoa(o.age);
90− }
93+}
91− throw "Failed pattern match";
94+throw "Failed pattern match";
92− })(p);
95+})(p);
93− };
96+};
97+```
94
98
95## Type System
99## Type System
96
100
@@ -124,9 +128,11 @@ PureScript supports the same binary and unary operations on primitive types as J
124
128
125Examples:
129Examples:
126
130
131+```haskell
127− num = 1 + 2 * 3
132+num = 1 + 2 * 3
128− str = "Hello, " ++ "World!"
133+str = "Hello, " ++ "World!"
129− bool = 1 > 2 || true
134+bool = 1 > 2 || true
135+```
130
136
131## Arrays
137## Arrays
132
138
@@ -152,14 +158,16 @@ Tagged unions can only be created using their constructors, and deconstructed th
152
158
153For example:
159For example:
154
160
161+```haskell
155− data Foo a = Foo | Bar String
162+data Foo a = Foo | Bar String
156−
163+
157− runFoo = \foo -> case foo of
164+runFoo = \foo -> case foo of
158− Foo -> "It's a Foo"
165+Foo -> "It's a Foo"
159− Bar s -> "It's a Bar. The string is " ++ s
166+Bar s -> "It's a Bar. The string is " ++ s
160−
167+
161− runFoo Foo ++ runFoo (Bar "Test")
168+runFoo Foo ++ runFoo (Bar "Test")
162−
169+```
170+
163In 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.
171In 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.
164
172
165`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.
173`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.
@@ -170,34 +178,42 @@ Functions in TypeScript can have zero or more arguments in general, just like in
170
178
171Functions are introduced by using a backslash followed by a comma separated list of argument names:
179Functions are introduced by using a backslash followed by a comma separated list of argument names:
172
180
181+```haskell
173− test1 = \a, b, c -> a + b + c
182+test1 = \a, b, c -> a + b + c
174−
183+```
184+
175which would correspond to the Javascript `function test1(a, b, c) { return a + b + c; }`
185which would correspond to the Javascript `function test1(a, b, c) { return a + b + c; }`
176
186
177A function taking no arguments would look like this:
187A function taking no arguments would look like this:
178
188
189+```haskell
179− test2 = \ -> 100
190+test2 = \ -> 100
180−
191+```
192+
181which would correspond to the Javascript `function test2() { return 100; }`
193which would correspond to the Javascript `function test2() { return 100; }`
182
194
183Functions are applied by providing their arguments inside parentheses:
195Functions are applied by providing their arguments inside parentheses:
184
196
197+```haskell
185− test1(1, 2, 3)
198+test1(1, 2, 3)
186− test2()
199+test2()
187−
200+```
201+
188A 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:
202A 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:
189
203
204+```haskell
190− -- has type Number -> Number -> Number -> Number
205+-- has type Number -> Number -> Number -> Number
191− addThree = \a -> \b -> \c -> a + b + c
206+addThree = \a -> \b -> \c -> a + b + c
192−
207+
193− -- has type Number -> Number -> Number
208+-- has type Number -> Number -> Number
194− addThree 1
209+addThree 1
195−
210+
196− -- has type Number -> Number
211+-- has type Number -> Number
197− addThree 1 2
212+addThree 1 2
198−
213+
199− -- has type Number
214+-- has type Number
200− addThree 1 2 3
215+addThree 1 2 3
216+```
201
217
202## Polymorphic Types
218## Polymorphic Types
203
219
@@ -205,28 +221,38 @@ Expressions defined at the top level may have polymorphic types.
205
221
206Here is an example:
222Here is an example:
207
223
224+```haskell
208− identity = \x -> x
225+identity = \x -> x
209−
226+```
227+
210`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.
228`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.
211
229
212A type annotation can also be provided:
230A type annotation can also be provided:
213
231
232+```haskell
214− identity :: forall a. a -> a
233+identity :: forall a. a -> a
215− identity = \x -> x
234+identity = \x -> x
216−
235+```
236+
217Functions may also be polymorphic in row types or type variables with other kinds (see "Kind System"):
237Functions may also be polymorphic in row types or type variables with other kinds (see "Kind System"):
218
238
239+```haskell
219− addProps = \o -> o.foo + o.bar
240+addProps = \o -> o.foo + o.bar
241+```
220
242
221Here, `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*.
243Here, `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*.
222
244
223So, the following compiles:
245So, the following compiles:
224
246
247+```haskell
225− addProps { foo: 1, bar: 2, baz: 3 }
248+addProps { foo: 1, bar: 2, baz: 3 }
249+```
226
250
227but the following does not:
251but the following does not:
228
252
253+```haskell
229− addProps { foo: 1 }
254+addProps { foo: 1 }
255+```
230
256
231since the `bar` property is missing.
257since the `bar` property is missing.
232
258
@@ -246,13 +272,17 @@ Syntax is whitespace sensitive. The general rule of thumb is that declarations w
246
272
247That is, the following is valid:
273That is, the following is valid:
248
274
275+```haskell
249− foo = bar(x) +
276+foo = bar(x) +
250− baz(x)
277+ baz(x)
278+```
251
279
252But this is not:
280But this is not:
253
281
282+```haskell
254− foo = bar(x) +
283+foo = bar(x) +
255− baz(x)
284+baz(x)
285+```
256
286
257## Do Notation
287## Do Notation
258
288
@@ -271,38 +301,46 @@ The following types of statement are supported:
271
301
272Here is an example of a power function defined using a block:
302Here is an example of a power function defined using a block:
273
303
304+```haskell
274− pow = \n, p -> do
305+pow = \n, p -> do
275− var m = n
306+ var m = n
276− for i <- 0 until p:
307+ for i <- 0 until p:
277− m = m * n
308+ m = m * n
278− return m
309+ return m
310+```
279
311
280Blocks enable local mutation of their variables, but mutation is not allowed in general. The type system prevents mutable variables from escaping their scope.
312Blocks enable local mutation of their variables, but mutation is not allowed in general. The type system prevents mutable variables from escaping their scope.
281
313
282That is, while the example above is valid, the following does not compile:
314That is, while the example above is valid, the following does not compile:
283
315
316+```haskell
284− incr = \n -> do
317+incr = \n -> do
285− n = n + 1
318+ n = n + 1
286− return n
319+ return n
320+```
287
321
288The variable `n` is not mutable, and so the assignment in the first line of the `do` block is not allowed.
322The variable `n` is not mutable, and so the assignment in the first line of the `do` block is not allowed.
289
323
290This function can be rewritten as follows:
324This function can be rewritten as follows:
291
325
326+```haskell
292− incr = \n -> do
327+incr = \n -> do
293− var m = n
328+ var m = n
294− m = m + 1
329+ m = m + 1
295− return m
330+ return m
331+```
296
332
297## For Loops
333## For Loops
298
334
299For loops look like this:
335For loops look like this:
300
336
337+```haskell
301− total = do
338+total = do
302− var n = 0
339+ var n = 0
303− for i <- 0 until 10:
340+ for i <- 0 until 10:
304− n = n + i
341+ n = n + i
305− return n
342+ return n
343+```
306
344
307The bounds `0` and `10` are inclusive and exclusive respectively.
345The bounds `0` and `10` are inclusive and exclusive respectively.
308
346
@@ -310,38 +348,44 @@ The bounds `0` and `10` are inclusive and exclusive respectively.
310
348
311For each loops loop over the elements in an array using the `Object.forEach` method. A polyfill may be required for some browsers:
349For each loops loop over the elements in an array using the `Object.forEach` method. A polyfill may be required for some browsers:
312
350
351+```haskell
313− total = \arr -> do
352+total = \arr -> do
314− var n = 0
353+ var n = 0
315− foreach i in arr:
354+ foreach i in arr:
316− n = n + i
355+ n = n + i
317− return n
356+ return n
357+```
318
358
319## While Loops
359## While Loops
320
360
321The syntax of a while loop is similar to a foreach loop:
361The syntax of a while loop is similar to a foreach loop:
322
362
363+```haskell
323− log2 = \n -> do
364+log2 = \n -> do
324− var count = 0
365+ var count = 0
325− var m = n
366+ var m = n
326− while m > 1:
367+ while m > 1:
327− m = m / 2
368+ m = m / 2
328− count = count + 1
369+ count = count + 1
329− return count
370+ return count
371+```
330
372
331## If-Then-Else Statements
373## If-Then-Else Statements
332
374
333Else branches are optional, and may contain further `if` statements, just as in Javascript:
375Else branches are optional, and may contain further `if` statements, just as in Javascript:
334
376
377+```haskell
335− collatz = \n -> do
378+collatz = \n -> do
336− var count = 0
379+ var count = 0
337− var m = n
380+ var m = n
338− while m > 1:
381+ while m > 1:
339− if m % 2 == 0:
382+ if m % 2 == 0:
340− m = m / 2
383+ m = m / 2
341− else:
384+ else:
342− m = m * 3 + 1
385+ m = m * 3 + 1
343− count = count + 1
386+ count = count + 1
344− return count
387+ return count
388+```
345
389
346## If-Then-Else Expressions
390## If-Then-Else Expressions
347
391
@@ -349,7 +393,9 @@ The `if`, `then` and `else` keywords can also be used to create conditional expr
349
393
350For example,
394For example,
351
395
396+```haskell
352− conditional = if 2 > 1 then "ok" else "oops"
397+conditional = if 2 > 1 then "ok" else "oops"
398+```
353
399
354## Pattern Matching
400## Pattern Matching
355
401
@@ -357,10 +403,12 @@ Pattern matching deconstructs a value to bring zero or more expressions into sco
357
403
358Pattern matches have the following general form
404Pattern matches have the following general form
359
405
406+```haskell
360− case value of
407+case value of
361− pattern -> result
408+ pattern -> result
362− ...
409+ -- ...
363− pattern -> result
410+ pattern -> result
411+```
364
412
365The following pattern types are supported:
413The following pattern types are supported:
366
414
@@ -378,31 +426,37 @@ Patterns need not be exhaustive. A pattern match failed exception will be thrown
378
426
379The wilcard `_` matches any input and brings nothing into scope:
427The wilcard `_` matches any input and brings nothing into scope:
380
428
429+```haskell
381− case x of
430+case x of
382− _ -> 0
431+ _ -> 0
432+```
383
433
384## Literal Patterns
434## Literal Patterns
385
435
386Literal patterns are provided to match on primitives:
436Literal patterns are provided to match on primitives:
387
437
438+```haskell
388− case booleanValue of
439+case booleanValue of
389− true -> 0
440+ true -> 0
390− false -> 1
441+ false -> 1
391−
442+
392− case stringValue of
443+case stringValue of
393− "Foo" -> 0
444+ "Foo" -> 0
394− _ -> 1
445+ _ -> 1
395−
446+
396− case numericValue of
447+case numericValue of
397− 0 -> 0
448+ 0 -> 0
398− _ -> 1
449+ _ -> 1
450+```
399
451
400## Variable Pattern
452## Variable Pattern
401
453
402A variable pattern matches any input and binds that input to its name:
454A variable pattern matches any input and binds that input to its name:
403
455
456+```haskell
404− case foo(x) of
457+case foo(x) of
405− result -> bar(result)
458+ result -> bar(result)
459+```
406
460
407## Array Patterns
461## Array Patterns
408
462
@@ -410,10 +464,12 @@ Array patterns match an input which is an array, and bring its elements into sco
410
464
411For example:
465For example:
412
466
467+```haskell
413− f = \arr -> case arr of
468+f = \arr -> case arr of
414− [x] -> x
469+ [x] -> x
415− [x, y : xs] -> x * y + f(xs)
470+ [x, y : xs] -> x * y + f(xs)
416− _ -> 0
471+ _ -> 0
472+```
417
473
418Here, the first pattern only matches arrays of length one, and brings the first element of the array into scope.
474Here, the first pattern only matches arrays of length one, and brings the first element of the array into scope.
419
475
@@ -423,9 +479,11 @@ The second pattern matches arrays with two or more elements, and brings the firs
423
479
424Record patterns match an input which is a record, and bring its properties into scope.
480Record patterns match an input which is a record, and bring its properties into scope.
425
481
482+```haskell
426− f = \o -> case o of
483+f = \o -> case o of
427− { foo = "Foo" } -> o.bar
484+ { foo = "Foo" } -> o.bar
428− _ -> 0
485+ _ -> 0
486+```
429
487
430## Nested Patterns
488## Nested Patterns
431
489
@@ -433,54 +491,65 @@ The patterns above can be combined to create larger patterns.
433
491
434For example:
492For example:
435
493
494+```haskell
436− f = \o -> case o of
495+f = \o -> case o of
437− { arr = [x:_], take = "car" } -> x
496+ { arr = [x:_], take = "car" } -> x
438− { arr = [_,x:_], take = "cadr" } -> x
497+ { arr = [_,x:_], take = "cadr" } -> x
439− _ -> 0
498+ _ -> 0
499+```
440
500
441## Named Patterns
501## Named Patterns
442
502
443Named patterns bring additional names into scope when using nested patterns. Any pattern can be named by using the `@` symbol:
503Named patterns bring additional names into scope when using nested patterns. Any pattern can be named by using the `@` symbol:
444
504
505+```haskell
445− f = \arr -> case arr of
506+f = \arr -> case arr of
446− a@[_,_:_] -> a
507+ a@[_,_:_] -> a
447− a -> a
508+ a -> a
448−
509+```
510+
449Here, in the first pattern, any array with two or more elements will be matched and bound to the variable `a`.
511Here, in the first pattern, any array with two or more elements will be matched and bound to the variable `a`.
450
512
451## Guards
513## Guards
452
514
453Guards are used to impose additional constraints inside a pattern using boolean-valued expressions, and are introduced with a pipe after the pattern:
515Guards are used to impose additional constraints inside a pattern using boolean-valued expressions, and are introduced with a pipe after the pattern:
454
516
517+```haskell
455− evens = \arr -> case arr of
518+evens = \arr -> case arr of
456− [] -> 0
519+ [] -> 0
457− [x:xs] | x % 2 == 0 -> 1 + evens xs
520+ [x:xs] | x % 2 == 0 -> 1 + evens xs
458− [_:xs] -> evens xs
521+ [_:xs] -> evens xs
459−
522+```
523+
460## Type Synonyms
524## Type Synonyms
461
525
462For convenience, it is possible to declare a synonym for a type using the `type` keyword. Type synonyms can include type arguments.
526For convenience, it is possible to declare a synonym for a type using the `type` keyword. Type synonyms can include type arguments.
463
527
464For example:
528For example:
465
529
530+```haskell
466− type Foo = { foo :: Number, bar Number }
531+type Foo = { foo :: Number, bar Number }
467−
532+
468− addFoo :: Foo -> Number
533+addFoo :: Foo -> Number
469− addFoo = \o -> o.foo + o.bar
534+addFoo = \o -> o.foo + o.bar
470−
535+```
471## Record Updates
536## Record Updates
472
537
473Properties on records can be updated using the following syntax: `o { key = value, ..., key = value }`
538Properties on records can be updated using the following syntax: `o { key = value, ..., key = value }`
474
539
475For example, the following function increments the `foo` property on its argument:
540For example, the following function increments the `foo` property on its argument:
476
541
542+```haskell
477− incr = \o -> o { foo = o.foo + 1 }
543+incr = \o -> o { foo = o.foo + 1 }
544+```
478
545
479The 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
546The 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
480
547
548+```haskell
481− Object.prototype.extend = function(o, p) {
549+Object.prototype.extend = function(o, p) {
482− return $.extend({}, o, p);
550+ return $.extend({}, o, p);
483− };
551+};
552+```
484
553
485## Operators
554## Operators
486
555
@@ -488,31 +557,40 @@ In addition to the standard operators, user-defined infix operators can be creat
488
557
489E.g. to create a synonym for string concatenation:
558E.g. to create a synonym for string concatenation:
490
559
560+```haskell
491− (<>) = \s1 -> \s2 -> s1 ++ s2
561+(<>) = \s1 -> \s2 -> s1 ++ s2
492−
562+
493− greeting = "Hello" <> "World!"
563+greeting = "Hello" <> "World!"
494−
564+```
565+
495Regular functions can be used as operators by enclosing their names in backticks:
566Regular functions can be used as operators by enclosing their names in backticks:
496
567
568+```haskell
497− foo = \x -> \y -> x * y + y
569+foo = \x -> \y -> x * y + y
498−
570+
499− test = 10 `foo` 20
571+test = 10 `foo` 20
572+```
500
573
501Fixity declarations can associate a precedence level, which is a natural number, to a user-defined operator, and specify which way it associates:
574Fixity declarations can associate a precedence level, which is a natural number, to a user-defined operator, and specify which way it associates:
502
575
576+```haskell
503− infixl 5 <>
577+infixl 5 <>
504− infixr 7 %%
578+infixr 7 %%
579+```
505
580
506## Foreign Function Interface
581## Foreign Function Interface
507
582
508The `extern` keyword declares a value which is defined in Javascript, and its type:
583The `extern` keyword declares a value which is defined in Javascript, and its type:
509
584
585+```haskell
510− extern pow :: (Number, Number) -> Number
586+extern pow :: (Number, Number) -> Number
511−
587+```
588+
512To declare a new type with no constructors, use `extern data` and provide the kind:
589To declare a new type with no constructors, use `extern data` and provide the kind:
513
590
514− extern data IO :: * -> *
591+extern data IO :: * -> *
515
592
516− extern console :: {
593+extern console :: {
517− log :: String -> IO {}
594+ log :: String -> IO {}
518− }
595+}
596+```