@@ -19,6 +19,7 @@ Bitcoin donations are gratefully accepted at 14ZhCym28WDuFhocP44tU1dBpCzjX1DvhF.
1919- Simple FFI
2020- Modules
2121- Rank N Types
22+- Do Notation
2223
2324## Try It!
2425
@@ -331,7 +332,7 @@ since the `bar` property is missing.
331332
332333Again, a type annotation can be provided if necessary.
333334
334−## Rank N Types (Experimental Feature)
335+## Rank N Types
335336
336337It 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.
337338
@@ -360,7 +361,11 @@ All types can be inferred, but annotations can optionally be provided.
360361
361362## Kind System
362363
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.
364+There are two primitive kinds, the kind `*` of types and the kind `!` of effects.
365+
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.
367+
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.
364369
365370## Whitespace
366371
@@ -392,7 +397,6 @@ The following types of statement are supported:
392397- For-each loops
393398- While loops
394399- If-Then-Else statements
395−- Naked expressions
396400
397401Here is an example of a power function defined using a block:
398402
@@ -494,17 +498,6 @@ collatz n = {
494498 return count;
495499 }
496500```
497−
498−## Naked Expressions as Statements
499−
500−Any expression with the empty type `{ }` can be used as a statement in a block. For example, method calls which return `{ }`:
501−
502−```haskell
503−example n m = {
504− console.log "Adding two numbers"
505− return n + m;
506− }
507−```
508501
509502## If-Then-Else Expressions
510503
@@ -516,6 +509,52 @@ For example,
516509conditional = if 2 > 1 then "ok" else "oops"
517510```
518511
512+## Do Notation
513+
514+The `do` keyword introduces simple syntactic sugar for monadic expressions.
515+
516+Here is an example, using the maybe monad:
517+
518+```haskell
519+data Maybe a = Nothing | Just a
520+
521+bindMaybe Nothing _ = Nothing
522+bindMaybe (Just a) f = f a
523+
524+maybe = { ret: Just, bind: bindMaybe }
525+
526+isEven n | n % 2 == 0 = Just {}
527+isEven _ = Nothing
528+
529+evenSum a b = maybe do
530+ n <- a
531+ m <- b
532+ let sum = n + m
533+ isEven sum
534+ return sum
535+```
536+
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`.
538+
539+This example illustrates the following aspects of `do` notation:
540+
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.
547+
548+Not illustrated here, but equally valid is the use of a binder on the left hand side of `<-` or `=`. For example:
549+
550+```haskell
551+test arr = do
552+ (x:y:_) <- arr
553+ return x + y
554+```
555+
556+A pattern match failure will generate a runtime exception, just as in the case of a regular `case` statement.
557+
519558## Pattern Matching
520559
521560Pattern matching deconstructs a value to bring zero or more expressions into scope. Pattern matches are introduced with the `case` keyword.