You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 16f16bf
Browse filesBrowse the repository at this point in the historyBrowse files
in λ(c : LFix P) → c (C a) (λ(q : P (C a)) → merge {
15280
15283
Left = λ(fa : F a (C a)) → fix (F a) functorFa fa
15281
15284
, Right = λ(ca : C a) → ca
@@ -15288,7 +15291,7 @@ let filterableLFixEither
15288
15291
Suppose a type constructor has a monad's methods with respect to one type parameter while the other type parameter is held fixed.
15289
15292
It turns out we can then apply a universal quantifier to the fixed type parameter and obtain a new monad.
15290
15293
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.
15292
15295
Then apply the universal quantifier to `t`.
15293
15296
The result is the type constructor we denote by `Codensity F a`:
15294
15297
@@ -15311,7 +15314,7 @@ let monadCodensity : ∀(F : Type → Type) → Monad (Codensity F)
15311
15314
in { pure, bind }
15312
15315
```
15313
15316
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.
15315
15318
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`:
15316
15319
15317
15320
```dhall
@@ -15345,18 +15348,18 @@ let monadComposedCodensity : ∀(F : Type → Type) → Functor F → ∀(M : Ty
15345
15348
in functorF.fmap (M (M t)) (M t) (monadJoin M monadM t) fmmt : F (M t)
15346
15349
in { pure, bind }
15347
15350
```
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.
15349
15352
15350
15353
### Monads with recursive types
15351
15354
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.
15355
15355
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.
15357
15357
Some often used monads of that kind are the list-like and the tree-like monads.
15358
15358
Examples of list-like monads are the standard `List` and the non-empty list.
15359
15359
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
+
15360
15363
#### The `List` monad
15361
15364
15362
15365
Although `List` is a built-in type in Dhall,
@@ -15445,12 +15448,8 @@ let exampleNEL1345 : NEL Natural = toNEL Natural [ 1, 3, 4 ] 5
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-likedata 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.
15745
15746
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.
15749
15750
15751
+
Here is a formal definition:
15750
15752
The **free monad** on a functor `F` is the functor `Free F` recursively defined by:
15751
15753
15752
15754
```haskell
@@ -15762,7 +15764,7 @@ We just curry the function type to make the implementation easier:
15762
15764
```dhall
15763
15765
let FreeMonad : ∀(F : Type → Type) → Type → Type
15764
15766
= λ(F : Type → Type) → λ(a : Type) →
15765
-
∀(r : Type) → (a → r) → (F r → r) → r
15767
+
∀(r : Type) → (a → r) → (F r → r) → r
15766
15768
```
15767
15769
15768
15770
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
15799
15801
let FrTree/join = monadJoin FrTree (monadFreeMonad D)
15800
15802
```
15801
15803
15802
-
We will also need a `Show` implementation and the monadic `join` method:
15804
+
We will also need a `Show` evidence for `FrTree`:
15803
15805
15804
15806
```dhall
15805
15807
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
15851
15853
let InfFreeMonad = λ(F : Type → Type) → λ(a : Type) → GFix (λ(r : Type) → Either a (F r))
15852
15854
```
15853
15855
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`.
15857
15857
15858
15858
To implement the `bind` method, we use the "seed" type that can switch between two monad types (`InfFreeMonad F a` and `InfFreeMonad F b`).
15859
15859
Once we encounter a value of type `a`, we switch to `InfFreeMonad F b`.
0 commit comments