Skip to content

Commit 16f16bf

Browse files
committed
corrections in chapter 17
1 parent 4763e9f commit 16f16bf

1 file changed

Lines changed: 30 additions & 30 deletions

File tree

‎tutorial/programming_dhall.md‎

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3762,7 +3762,7 @@ Any monoid is a semigroup, but not all semigroups are monoids, because no suitab
37623762
Given a `Monoid` evidence for a type `t`, we can automatically derive a `Semigroup` evidence by just selecting the `append` method:
37633763

37643764
```dhall
3765-
let semigroupViaMonoid: ∀(t : Type) → Monoid t → Semigroup t
3765+
let semigroupViaMonoid : ∀(t : Type) → Monoid t → Semigroup t
37663766
= λ(t : Type) → λ(monoidT : Monoid t) → monoidT.{append}
37673767
```
37683768

@@ -14728,7 +14728,7 @@ So, it is not possible to compute the final value of type `L (F a)`.
1472814728
## Monads and their combinators
1472914729

1473014730
In the chapter "Typeclasses" we have seen some examples of specific monads such as `Reader`, `Writer`, and `State`.
14731-
We will now look at general combinators that create new monads.
14731+
We will now implement a number of general combinators that create new monads.
1473214732

1473314733
### Constant functors and the identity functor
1473414734

@@ -14768,7 +14768,7 @@ let monadProduct : ∀(F : Type → Type) → Monad F → ∀(G : Type → Type)
1476814768
in { pure, bind }
1476914769
```
1477014770

14771-
### Co-product types
14771+
### Co-product types: free pointed monads
1477214772

1477314773
In general, a co-product of two monads is not a monad.
1477414774
But there is one exception: when one of the monads is the identity monad.
@@ -15127,7 +15127,7 @@ let arrowMContraFilterable : ∀(M : Type → Type) → ∀(F : Type → Type)
1512715127
Just as for the ordinary filterable (contra)functors, we can implement four constructions for $M$-filterable (contra)functors.
1512815128

1512915129
Suppose `F` is a type constructor with two type parameters, and we are imposing a universal or an existential quantifier on the second type parameter.
15130-
Then we will get new type constructors defined as: $$G ~ x = \forall y. ~ F ~ x ~ y$$ $$H ~ x = \exists y. ~ F ~ x ~ y$$
15130+
Then we will get new type constructors defined as: $$G ~ x = \forall y. ~ F ~ x ~ y \qquad , \qquad H ~ x = \exists y. ~ F ~ x ~ y$$
1513115131

1513215132
Imposing a quantifier on `y` preserves the $M$-filterable properties of `F x y` with respect to `x` (while `y` is held fixed).
1513315133
It does not matter whether `F x y` is covariant, contravariant, or neither with respect to `y`.
@@ -15275,7 +15275,10 @@ let filterableLFixEither
1527515275
-- Need a function of type C (M a) → C a.
1527615276
-- Define P such that LFix P = C (M a).
1527715277
let P = F (M a)
15278-
let functorFa : Functor (F a) = { fmap = λ(x : Type) → λ(y : Type) → λ(f : x → y) → bifunctorF.bimap a a (identity a) x y f }
15278+
let functorFa : Functor (F a) =
15279+
{ fmap = λ(x : Type) → λ(y : Type) → λ(f : x → y) →
15280+
bifunctorF.bimap a a (identity a) x y f
15281+
}
1527915282
in λ(c : LFix P) → c (C a) (λ(q : P (C a)) → merge {
1528015283
Left = λ(fa : F a (C a)) → fix (F a) functorFa fa
1528115284
, Right = λ(ca : C a) → ca
@@ -15288,7 +15291,7 @@ let filterableLFixEither
1528815291
Suppose a type constructor has a monad's methods with respect to one type parameter while the other type parameter is held fixed.
1528915292
It turns out we can then apply a universal quantifier to the fixed type parameter and obtain a new monad.
1529015293

15291-
As an example, take the continuation monad `Continuation R a = (a → R) → R` and replace the type parameter `R` by the type expression `F t`, where `F` is some type constructor and `t` is a new type parameter.
15294+
As an example, take the continuation monad (`Continuation R a = (a → R) → R`) and replace the type parameter `R` by the type expression `F t`, where `F` is some type constructor and `t` is a new type parameter.
1529215295
Then apply the universal quantifier to `t`.
1529315296
The result is the type constructor we denote by `Codensity F a`:
1529415297

@@ -15311,7 +15314,7 @@ let monadCodensity : ∀(F : Type → Type) → Monad (Codensity F)
1531115314
in { pure, bind }
1531215315
```
1531315316

15314-
We can generalize this idea to a combinator that imposes a universal quantifier on an extra type parameter in a given monad.
15317+
In general, one may impose a universal quantifier on an extra type parameter in a given monad.
1531515318
If `M a b` is a monad with respect to `b` for fixed `a` then `N b = ∀(a : Type) → M a b` is a monad with respect to the free type parameter `b`:
1531615319

1531715320
```dhall
@@ -15345,18 +15348,18 @@ let monadComposedCodensity : ∀(F : Type → Type) → Functor F → ∀(M : Ty
1534515348
in functorF.fmap (M (M t)) (M t) (monadJoin M monadM t) fmmt : F (M t)
1534615349
in { pure, bind }
1534715350
```
15348-
This monad is _not_ obtained by imposing a universal quantifier on another monad; the type constructor `(a → F t) → F (M t)` is not a monad with respect to `a` when `t` is a fixed type.
15351+
This monad is _not_ obtained by imposing a universal quantifier on another monad; the type constructor `(a → F t) → F (M t)` is not necessarily a monad with respect to `a` when `t` is a fixed type.
1534915352

1535015353
### Monads with recursive types
1535115354

15352-
There does not seem to exist a combinator that produces a monad out of a fixpoint of an arbitrary type constructor that has some properties.
15353-
15354-
The "free monad" is a recursive combinator that takes an arbitrary functor and builds a new monad out of that.
1535515355

15356-
We begin by looking at specific known monads that have recursive types.
15356+
Here we will look at specific known monads that have recursive types.
1535715357
Some often used monads of that kind are the list-like and the tree-like monads.
1535815358
Examples of list-like monads are the standard `List` and the non-empty list.
1535915359

15360+
An example of a tree-like monad is the "free monad".
15361+
It is a recursive combinator that takes an arbitrary functor and builds a new monad.
15362+
1536015363
#### The `List` monad
1536115364

1536215365
Although `List` is a built-in type in Dhall,
@@ -15445,12 +15448,8 @@ let exampleNEL1345 : NEL Natural = toNEL Natural [ 1, 3, 4 ] 5
1544515448
let _ = assert : showNELNat exampleNEL1345 ≡ "[| 1, 3, 4, 5 |]"
1544615449
```
1544715450

15448-
Let us implement a `Monad` evidence for `NEL`.
15449-
15450-
It is in any case not obvious how to implement the `bind` method for a given type constructor.
15451-
Not all type constructors are monads; for those type constructors, an implementation of `bind` that satisfies the laws is impossible.
15452-
15453-
With `NEL`, one finds that the trick we used for `ListC` no longer works: we cannot create a function of type `a → r → r` inside the body of `bind`.
15451+
We now turn to finding a `Monad` evidence for `NEL`.
15452+
It turns out that the trick we used for `ListC` no longer works: we cannot create a function of type `a → r → r` inside the body of `bind`.
1545415453
So, we need to use a different approach.
1545515454

1545615455
The type of `bind` is `NEL a → (a → NEL b) → NEL b`.
@@ -15621,9 +15620,11 @@ It turns out that `BTreeE` is a monad.
1562115620
Its `bind` operation will remove leaves and sub-trees corresponding to `None`.
1562215621

1562315622
To implement this operation more easily, we use a trick that this book calls the **Church-Yoneda identity**.
15624-
It says that, for any functors `F` and `G`, the type `G (LFix F)` is isomorphic to the following type:
15623+
It says that, for any functors `F` and `G`, there is the following type equivalence (isomorphism):
1562515624

15626-
`∀(r : Type) → (F r → r) → G r`
15625+
```haskell
15626+
G (LFix F) ≅ ∀(r : Type) → (F r → r) → G r
15627+
```
1562715628

1562815629

1562915630
So, we may encode the type `Optional (TreeC a)` equivalently like this:
@@ -15740,13 +15741,14 @@ let _ = assert : exampleResult ≡ expectedResult
1574015741

1574115742
#### The free monad
1574215743

15743-
The binary tree is an example of a "tree-like" monad, that is, a monad whose data structure has the shape of a tree.
15744-
Other examples of tree-like monads are trees that branch in three instead of in two sub-trees, or trees with more complicated branching shape, with extra data on each branch point, and so on.
15744+
Tree-like data structures can have different shapes.
15745+
Data can be stored on leaves and/or on branch points; branchings can be in two, in three, or in a variable number of subtrees.
1574515746

15746-
In many cases, the choice of branching can be described by a functor `F`.
15747-
The binary tree corresponds to choosing `F a = Pair a a`.
15748-
Tree-like monads of that kind can be implemented by a general combinator known as the "free monad".
15747+
There is a general combinator known as the "free monad" that describes a specific kind of tree-like structures where
15748+
data is only stored on leaves while the choice of branching is described by a functor `F`.
15749+
For instance, the binary tree (`Tree2`) corresponds to choosing `F a = Pair a a` as the branching functor.
1574915750

15751+
Here is a formal definition:
1575015752
The **free monad** on a functor `F` is the functor `Free F` recursively defined by:
1575115753

1575215754
```haskell
@@ -15762,7 +15764,7 @@ We just curry the function type to make the implementation easier:
1576215764
```dhall
1576315765
let FreeMonad : ∀(F : Type → Type) → Type → Type
1576415766
= λ(F : Type → Type) → λ(a : Type) →
15765-
∀(r : Type) → (a → r) → (F r → r) → r
15767+
∀(r : Type) → (a → r) → (F r → r) → r
1576615768
```
1576715769

1576815770
To implement a monad's methods for `FreeMonad F`, we write:
@@ -15799,7 +15801,7 @@ let frBranch : ∀(a : Type) → FrTree a → FrTree a → FrTree a
1579915801
let FrTree/join = monadJoin FrTree (monadFreeMonad D)
1580015802
```
1580115803

15802-
We will also need a `Show` implementation and the monadic `join` method:
15804+
We will also need a `Show` evidence for `FrTree`:
1580315805

1580415806
```dhall
1580515807
let showFrTree : ∀(a : Type) → Show a → Show (FrTree a)
@@ -15851,9 +15853,7 @@ The "infinite free monad" is the greatest fixpoint of the same pattern functor u
1585115853
let InfFreeMonad = λ(F : Type → Type) → λ(a : Type) → GFix (λ(r : Type) → Either a (F r))
1585215854
```
1585315855
It is not a free monad in the mathematical sense, as it does not satisfy some of the laws required for free monads.
15854-
Bit it is nevertheless a monad for any functor `F`.
15855-
15856-
todo: check space before colon in exported code
15856+
But it is nevertheless a monad for any functor `F`.
1585715857

1585815858
To implement the `bind` method, we use the "seed" type that can switch between two monad types (`InfFreeMonad F a` and `InfFreeMonad F b`).
1585915859
Once we encounter a value of type `a`, we switch to `InfFreeMonad F b`.

0 commit comments

Comments
 (0)