@@ -19,6 +19,7 @@ Bitcoin donations are gratefully accepted at 14ZhCym28WDuFhocP44tU1dBpCzjX1DvhF.
19- Simple FFI
19- Simple FFI
21- Rank N Types
21- Rank N Types
@@ -331,7 +332,7 @@ since the `bar` property is missing.
332Again, a type annotation can be provided if necessary.
333Again, a type annotation can be provided if necessary.
334−## Rank N Types (Experimental Feature)
335+## Rank N Types
336It 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.
337It 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,7 +361,11 @@ All types can be inferred, but annotations can optionally be provided.
361## Kind System
362## Kind System
364+There are two primitive kinds, the kind `*` of types and the kind `!` of effects.
366+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.
363−There are two primitive kinds, the kind `*` of types and the kind `#` of rows. 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.
368+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.
365## Whitespace
370## Whitespace
@@ -392,7 +397,6 @@ The following types of statement are supported:
392- For-each loops
397- For-each loops
393- While loops
398- While loops
394- If-Then-Else statements
399- If-Then-Else statements
397Here is an example of a power function defined using a block:
401Here is an example of a power function defined using a block:
@@ -494,17 +498,6 @@ collatz n = {
494 return count;
498 return count;
498−## Naked Expressions as Statements
500−Any expression with the empty type `{ }` can be used as a statement in a block. For example, method calls which return `{ }`:
504− console.log "Adding two numbers"
509## If-Then-Else Expressions
502## If-Then-Else Expressions
@@ -516,6 +509,52 @@ For example,
516conditional = if 2 > 1 then "ok" else "oops"
509conditional = if 2 > 1 then "ok" else "oops"
514+The `do` keyword introduces simple syntactic sugar for monadic expressions.
516+Here is an example, using the maybe monad:
519+data Maybe a = Nothing | Just a
521+bindMaybe Nothing _ = Nothing
522+bindMaybe (Just a) f = f a
524+maybe = { ret: Just, bind: bindMaybe }
526+isEven n | n % 2 == 0 = Just {}
529+evenSum a b = maybe do
537+`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`.
539+This example illustrates the following aspects of `do` notation:
541+- The `do` keyword is preceded by a value `m` which is a record. The record must contain fields `ret` and `bind` which determine the monad which will be used in the computation.
542+- Statements can have the following form:
543+ - `a <- x` which desugars to `m.bind x (\a -> ...)`
544+ - `let a = x` which desugars to `(\a -> ...)(x)`
545+ - `return a` which desugars to `m.ret a`
546+ - `x` which desugars to `m.bind x (\_ -> ...)` or just `x` if this is the last statement.
548+Not illustrated here, but equally valid is the use of a binder on the left hand side of `<-` or `=`. For example:
556+A pattern match failure will generate a runtime exception, just as in the case of a regular `case` statement.
519## Pattern Matching
558## Pattern Matching
521Pattern matching deconstructs a value to bring zero or more expressions into scope. Pattern matches are introduced with the `case` keyword.
560Pattern matching deconstructs a value to bring zero or more expressions into scope. Pattern matches are introduced with the `case` keyword.