diff --git a/sample100pages.pdf b/sample100pages.pdf
index 6b47fe2fd..ab250a4dd 100644
Binary files a/sample100pages.pdf and b/sample100pages.pdf differ
diff --git a/sofp-src/lyx/sofp-appendices.lyx b/sofp-src/lyx/sofp-appendices.lyx
index de87d0524..f57a30c5e 100644
--- a/sofp-src/lyx/sofp-appendices.lyx
+++ b/sofp-src/lyx/sofp-appendices.lyx
@@ -5312,7 +5312,7 @@ Another use of
\end_inset
-algebras is in formulating properties of
-\begin_inset Formula $P$
+\begin_inset Formula $FM$
\end_inset
-typeclasses.
@@ -5320,7 +5320,7 @@ Another use of
status open
\begin_layout Plain Layout
-\begin_inset Formula $P$
+\begin_inset Formula $FM$
\end_inset
-typeclass
@@ -5328,8 +5328,8 @@ status open
\end_inset
- A
-\begin_inset Formula $P$
+ An
+\begin_inset Formula $FM$
\end_inset
-typeclass is a
@@ -5342,7 +5342,7 @@ status open
\end_inset
-\begin_inset Formula $P$
+\begin_inset Formula $FM$
\end_inset
-typeclass
@@ -5393,7 +5393,7 @@ tagless final
\end_inset
pattern), or more generally to Church encodings of free
-\begin_inset Formula $P$
+\begin_inset Formula $FM$
\end_inset
-typeclasses that involve functions of type
@@ -5751,7 +5751,7 @@ laws
\end_inset
, and
-\begin_inset Formula $P$
+\begin_inset Formula $FM$
\end_inset
-typeclasses.
@@ -5759,7 +5759,7 @@ laws
status open
\begin_layout Plain Layout
-\begin_inset Formula $P$
+\begin_inset Formula $FM$
\end_inset
-typeclass
@@ -11156,8 +11156,7 @@ This concludes the proof of the profunctor commutativity law.
\end_inset
-Similarly, we can prove the commutativity laws for bifunctors and bi-contrafunct
-ors.
+Similarly, we can prove the commutativity laws for bifunctors:
\end_layout
\begin_layout Subsubsection
@@ -11304,8 +11303,9 @@ noprefix "false"
.
That naturality law holds by assumption.
+
\begin_inset Note Note
-status open
+status collapsed
\begin_layout Plain Layout
The proofs that do not use naturality laws will need to repeat the same
@@ -12173,13 +12173,6 @@ name "sec:Parametricity-theorem-for-relations"
\end_inset
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Relations-between-types"
-
-\end_inset
-
-
\end_layout
\begin_layout Standard
@@ -12591,6 +12584,13 @@ must be an identity function.
\begin_layout Subsection
Relations between values of different types
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Relations-between-types"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -23361,7 +23361,8 @@ Strong dinaturality does
\emph on
not
\emph default
- hold when the type signature involves deeply nested functions such as
+ hold when the type contains deeply nested higher-order functions such as
+
\begin_inset Formula $F^{R}\triangleq\forall A.\,(\left(A\rightarrow R\right)\rightarrow A)\rightarrow A$
\end_inset
@@ -23385,8 +23386,7 @@ noprefix "false"
\end_inset
).
- To prove that, one needs to use more advanced techniques that use the relationa
-l naturality law in its full generality.
+ To prove that, one needs to use more advanced techniques.
The wedge law still holds for functions of type
\begin_inset Formula $F^{R}$
\end_inset
@@ -28603,8 +28603,8 @@ We will now do structural analysis to describe the profunctors with the
status open
\begin_layout Plain Layout
-The following derivations are adapted from these unpublished talk slides
- by V.
+The following derivations are adapted from the following unpublished talk
+ slides by V.
\begin_inset space ~
\end_inset
@@ -29643,11 +29643,11 @@ noprefix "false"
\end_inset
-\series bold
+\end_layout
-\begin_inset Formula $\quad$
-\end_inset
+\begin_layout Standard
+\series bold
(b)
\series default
@@ -29745,11 +29745,11 @@ noprefix "false"
(b)
\series default
The type signature
-\begin_inset Formula $\forall A.\,(F^{A}\rightarrow G^{A})\rightarrow L^{A,A}$
+\begin_inset Formula $(F^{A}\rightarrow G^{A})\rightarrow L^{A,A}$
\end_inset
needs to be expressed as
-\begin_inset Formula $\forall A.\,K^{A,A}\rightarrow L^{A,A}$
+\begin_inset Formula $K^{A,A}\rightarrow L^{A,A}$
\end_inset
with some profunctor
@@ -29757,11 +29757,11 @@ noprefix "false"
\end_inset
.
- We define
+ Then we can write
\begin_inset Formula $K^{X,Y}\triangleq M^{Y,X}\rightarrow N^{X,Y}$
\end_inset
- with suitably chosen profunctors
+ with the profunctors
\begin_inset Formula $M$
\end_inset
@@ -29769,7 +29769,7 @@ noprefix "false"
\begin_inset Formula $N$
\end_inset
-.
+ chosen appropriately.
Reasoning as before, we find that the profunctors
\begin_inset Formula $M$
\end_inset
@@ -32065,6 +32065,13 @@ noprefix "false"
Universal type quantifiers.
Notation.
Using Yoneda identities
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Universal-type-quantifiers"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -32313,7 +32320,17 @@ bound type parameter
\emph on
free
\emph default
- in the type expression
+
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+free type parameter
+\end_layout
+
+\end_inset
+
+in the type expression
\begin_inset Formula $F^{X}$
\end_inset
@@ -33083,9 +33100,6 @@ Simplify the type
\begin_layout Subparagraph
Solution
-\end_layout
-
-\begin_layout Standard
\begin_inset Foot
status collapsed
@@ -33118,6 +33132,10 @@ Dan Doel
\end_inset
+
+\end_layout
+
+\begin_layout Standard
Swap the curried arguments in the given type and get:
\begin_inset Formula
\begin{align*}
@@ -34120,7 +34138,7 @@ higher-order functor
\begin_inset Formula $P\leadsto F$
\end_inset
- the type
+ the function type
\begin_inset Formula $\forall A.\,P^{A}\rightarrow F^{A}$
\end_inset
@@ -34733,7 +34751,7 @@ noprefix "false"
\end_layout
\begin_layout Standard
-Note that the Yoneda lemma cannot be used to prove Eq.
+Note that the Yoneda identities cannot be used to prove Eq.
\begin_inset space ~
\end_inset
@@ -34748,7 +34766,7 @@ noprefix "false"
\end_inset
).
- The Yoneda lemma only applies to types of the form
+ The covariant Yoneda identity only applies to types of the form
\begin_inset Formula $\forall X.\,(A\rightarrow X)\rightarrow F^{X}$
\end_inset
@@ -34873,7 +34891,7 @@ Proof
\begin_inset Formula $F^{\bbnum 0}\neq\bbnum 0$
\end_inset
-, it is sufficient to implement any function
+, it is sufficient to produce a function
\begin_inset Formula $f$
\end_inset
@@ -34882,7 +34900,7 @@ Proof
\end_inset
.
- The code for that function is:
+ Such a function exists:
\begin_inset Formula
\[
f:F^{\bbnum 0}\rightarrow T\quad,\quad\quad f(p^{:F^{\bbnum 0}})\triangleq\forall X.\,q^{:F^{X}\rightarrow X}\rightarrow q(p\triangleright\text{absurd}^{\uparrow F})\quad.
@@ -34949,7 +34967,7 @@ noprefix "false"
\series bold
(b)
\series default
- if we implement any function
+ if we implement a function
\begin_inset Formula $g$
\end_inset
@@ -36725,6 +36743,13 @@ noprefix "false"
\begin_layout Subsection
The Church-Yoneda identity and its applications
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:The-Church-Yoneda-identity"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -37288,7 +37313,7 @@ noprefix "false"
\end_inset
-(nested fixpoint lemma)
+ (nested fixpoint lemma)
\end_layout
\begin_layout Standard
@@ -38170,6 +38195,13 @@ noprefix "false"
\begin_layout Subsection
Non-disjunctive type constructors
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Non-disjunctive-type-constructors"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -40032,12 +40064,12 @@ A type constructor
\end_inset
.
- (Compare with item
+ (Item
\series bold
(b)
\series default
- to see that a type constructor can be lifting-to-full and lifting-to-empty
- at the same time.)
+ shows that the same type constructor can be lifting-to-full and lifting-to-empt
+y.)
\end_layout
\begin_layout Standard
@@ -40084,6 +40116,74 @@ not
is lifting-to-empty.
\end_layout
+\begin_layout Standard
+A type constructor
+\begin_inset Formula $P$
+\end_inset
+
+ is
+\emph on
+not
+\emph default
+ lifting-to-empty when:
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(i)
+\series default
+
+\begin_inset Formula $P^{A}\triangleq A\rightarrow A$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(j)
+\series default
+
+\begin_inset Formula $P^{A}\triangleq Z+K^{A}$
+\end_inset
+
+ where
+\begin_inset Formula $K$
+\end_inset
+
+ is arbitrary and
+\begin_inset Formula $Z\neq\bbnum 0$
+\end_inset
+
+ is a fixed type.
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(k)
+\series default
+
+\begin_inset Formula $P^{A}\triangleq K^{A}\rightarrow L^{A}$
+\end_inset
+
+ where
+\begin_inset Formula $K$
+\end_inset
+
+ is arbitrary and
+\begin_inset Formula $L$
+\end_inset
+
+ is
+\emph on
+not
+\emph default
+ lifting-to-empty.
+\end_layout
+
\begin_layout Subparagraph
Proof
\end_layout
@@ -40150,7 +40250,7 @@ Proof
\end_inset
-where
+Here
\begin_inset Formula $q:A\rightarrow Q^{A}$
\end_inset
@@ -40158,13 +40258,20 @@ where
\begin_inset Formula $r:A\rightarrow R^{A}$
\end_inset
- are some functions (that we could assume to exist, for the purpose of this
- example).
+ are some functions that will exist for some
+\begin_inset Formula $Q$
+\end_inset
+
+ and
+\begin_inset Formula $R$
+\end_inset
+
+.
The function
\begin_inset Formula $f$
\end_inset
- returns different parts of the disjunction
+ returns different parts of the disjunctive type
\begin_inset Formula $Q^{A}+R^{A}$
\end_inset
@@ -40185,7 +40292,8 @@ disjunctive information
\begin_inset Quotes erd
\end_inset
-; that is,
+.
+ We say that
\begin_inset Formula $P$
\end_inset
@@ -40444,11 +40552,11 @@ any
\begin_inset Formula $r^{:A\leftrightarrow B}$
\end_inset
- is lifted to a relation
-\begin_inset Formula $r^{\updownarrow K}$
+ is lifted to a non-empty relation
+\begin_inset Formula $r^{\updownarrow K}\neq\emptyset$
\end_inset
- that is non-empty.
+.
As
\begin_inset Formula $L$
\end_inset
@@ -40496,220 +40604,19 @@ noprefix "false"
\begin_inset Formula $r^{\updownarrow K}\ogreaterthan\emptyset=\emptyset$
\end_inset
-.
-
-\begin_inset Formula $\square$
-\end_inset
-
-
-\end_layout
-
-\begin_layout Standard
-The following examples will help build up more intuition.
-\end_layout
-
-\begin_layout Subsubsection
-Example
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Example-undisjunctive-type-constructors"
-
-\end_inset
-
-
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Example-undisjunctive-type-constructors"
-plural "false"
-caps "false"
-noprefix "false"
-
-\end_inset
-
-
-\begin_inset Index idx
-status collapsed
-
-\begin_layout Plain Layout
-examples
-\end_layout
-
-\end_inset
-
-
-\end_layout
-
-\begin_layout Standard
-
-\series bold
-(a)
-\series default
- Show that
-\begin_inset Formula $P^{A}\triangleq A\rightarrow A$
-\end_inset
-
- is lifting-to-full but
-\emph on
-not
-\emph default
- lifting-to-empty.
-\end_layout
-
-\begin_layout Standard
-
-\series bold
-(b)
-\series default
- Show that
-\begin_inset Formula $P^{A}\triangleq\bbnum 1+A\rightarrow A$
-\end_inset
-
- is both lifting-to-full and lifting-to-empty.
-\end_layout
-
-\begin_layout Standard
-
-\series bold
-(c)
-\series default
- Show that
-\begin_inset Formula $P^{A}\triangleq F^{A}\rightarrow A$
-\end_inset
-
- is lifting-to-full for any
-\begin_inset Formula $F$
-\end_inset
-
-.
-\end_layout
-
-\begin_layout Standard
-
-\series bold
-(d)
-\series default
- Show that
-\begin_inset Formula $P^{A}\triangleq\underbrace{A\times...\times A}_{n\text{ times, }n\geq1}$
-\end_inset
-
- is both lifting-to-full and lifting-to-empty.
-\end_layout
-
-\begin_layout Standard
-It follows from Statement
-\begin_inset space ~
-\end_inset
-
-
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-undisjunctive-type-constructors-relational"
-plural "false"
-caps "false"
-noprefix "false"
-
-\end_inset
-
- that all those type constructors denoted by
-\begin_inset Formula $P$
-\end_inset
-
- are non-disjunctive.
- Then it follows that, for any type constructors
-\begin_inset Formula $F$
-\end_inset
-
-,
-\begin_inset Formula $G$
-\end_inset
-
- (not necessarily covariant or contravariant):
-\end_layout
-
-\begin_layout Standard
-
-\series bold
-(e)
-\series default
-
-\begin_inset Formula $\forall A.\,F^{A}+G^{A}\cong(\forall A.\,F^{A})+(\forall A.\,G^{A})$
-\end_inset
-
.
\end_layout
\begin_layout Standard
\series bold
-(f)
+(i)
\series default
-
-\begin_inset Formula $\forall A.\,\underbrace{A\times...\times A}_{n\text{ times, }n\geq1}\rightarrow F^{A}+G^{A}\cong(\forall A.\,A\times...\times A\rightarrow F^{A})+(\forall A.\,A\times...\times A\rightarrow G^{A})$
-\end_inset
-
-.
-\end_layout
-
-\begin_layout Subparagraph
-Solution
-\end_layout
-
-\begin_layout Standard
-
-\series bold
-(a)
-\series default
- We know from Statement
-\begin_inset space ~
-\end_inset
-
-
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-undisjunctive-type-constructors-structural"
-plural "false"
-caps "false"
-noprefix "false"
-
-\end_inset
-
-(c) that
-\begin_inset Formula $L^{A}\triangleq A$
-\end_inset
-
- is lifting-to-full.
- It follows from Statement
-\begin_inset space ~
-\end_inset
-
-
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-undisjunctive-type-constructors-structural"
-plural "false"
-caps "false"
-noprefix "false"
-
-\end_inset
-
-(d) with
-\begin_inset Formula $K^{A}\triangleq L^{A}\triangleq A$
-\end_inset
-
- that
-\begin_inset Formula $P$
-\end_inset
-
- is also lifting-to-full.
-\end_layout
-
-\begin_layout Standard
-To show that
+ To show that
\begin_inset Formula $P$
\end_inset
- is not lifting-to-empty, it is sufficient to demonstrate that for any relation
-
+ is not lifting-to-empty, we need to prove that for any relation
\begin_inset Formula $r^{:A\leftrightarrow B}$
\end_inset
@@ -40760,16 +40667,441 @@ If we choose
\end_inset
.
- This is true for any
+ This holds for any
\begin_inset Formula $r$
\end_inset
.
- So,
+ So, for any
+\begin_inset Formula $r$
+\end_inset
+
+ there exist
+\begin_inset Formula $x$
+\end_inset
+
+,
+\begin_inset Formula $y$
+\end_inset
+
+ such that
\begin_inset Formula $(x,y)\in r^{\updownarrow P}$
\end_inset
- holds.
+.
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(j)
+\series default
+ Lifting any relation
+\begin_inset Formula $r^{:A\leftrightarrow B}$
+\end_inset
+
+ to
+\begin_inset Formula $P$
+\end_inset
+
+, we find:
+\begin_inset Formula
+\[
+r^{\updownarrow P}=\text{id}^{:Z\leftrightarrow Z}\boxplus r^{\updownarrow K}\quad.
+\]
+
+\end_inset
+
+By assumption
+\begin_inset Formula $Z\neq\bbnum 0$
+\end_inset
+
+, so we may choose a value
+\begin_inset Formula $z^{:Z}$
+\end_inset
+
+ and set
+\begin_inset Formula $x^{:P^{A}}\triangleq z+\bbnum 0^{:A}$
+\end_inset
+
+ and
+\begin_inset Formula $y^{:P^{B}}\triangleq z+\bbnum 0^{:B}$
+\end_inset
+
+.
+ The values
+\begin_inset Formula $x$
+\end_inset
+
+,
+\begin_inset Formula $y$
+\end_inset
+
+ are always in the relation
+\begin_inset Formula $\text{id}^{:Z\leftrightarrow Z}\boxplus r^{\updownarrow K}$
+\end_inset
+
+ for any
+\begin_inset Formula $r$
+\end_inset
+
+.
+ It follows that
+\begin_inset Formula $r^{\updownarrow P}$
+\end_inset
+
+ is not empty for any
+\begin_inset Formula $r$
+\end_inset
+
+.
+
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(k)
+\series default
+ We need to show that for any types
+\begin_inset Formula $A$
+\end_inset
+
+,
+\begin_inset Formula $B$
+\end_inset
+
+ and for any
+\begin_inset Formula $r^{:A\leftrightarrow B}$
+\end_inset
+
+ there exist values
+\begin_inset Formula $x^{:P^{A}}$
+\end_inset
+
+,
+\begin_inset Formula $y^{:P^{B}}$
+\end_inset
+
+ such that
+\begin_inset Formula $(x,y)\in r^{\updownarrow P}$
+\end_inset
+
+.
+ By assumption,
+\begin_inset Formula $L$
+\end_inset
+
+ is
+\emph on
+not
+\emph default
+ lifting-to-empty, so for any types
+\begin_inset Formula $A$
+\end_inset
+
+,
+\begin_inset Formula $B$
+\end_inset
+
+ and for any
+\begin_inset Formula $r^{:A\leftrightarrow B}$
+\end_inset
+
+ there exist values
+\begin_inset Formula $p^{:L^{A}}$
+\end_inset
+
+,
+\begin_inset Formula $q^{:L^{B}}$
+\end_inset
+
+ such that
+\begin_inset Formula $(p,q)\in r^{\updownarrow L}$
+\end_inset
+
+.
+ We choose
+\begin_inset Formula $x\triangleq\_^{:K^{A}}\rightarrow p$
+\end_inset
+
+ and
+\begin_inset Formula $y\triangleq\_^{:K^{B}}\rightarrow q$
+\end_inset
+
+.
+ We will now show that
+\begin_inset Formula $(x,y)\in r^{\updownarrow P}$
+\end_inset
+
+.
+ Since
+\begin_inset Formula $P^{A}=K^{A}\rightarrow L^{A}$
+\end_inset
+
+, the lifting to
+\begin_inset Formula $P$
+\end_inset
+
+ is given via the pair mapper:
+\begin_inset Formula
+\[
+(x,y)\in r^{\updownarrow P}\quad\text{means}\quad\forall(a^{:K^{A}},b^{:K^{B}}):\quad\text{if}\quad(a,b)\in r^{\updownarrow K}\quad\text{then}\quad(x(a),y(b))\in r^{\updownarrow L}\quad.
+\]
+
+\end_inset
+
+We have defined
+\begin_inset Formula $x$
+\end_inset
+
+ and
+\begin_inset Formula $y$
+\end_inset
+
+ as constant functions that always return
+\begin_inset Formula $p$
+\end_inset
+
+ and
+\begin_inset Formula $q$
+\end_inset
+
+.
+ So, we always have
+\begin_inset Formula $(x(a),y(b))\in r^{\updownarrow L}$
+\end_inset
+
+ for any
+\begin_inset Formula $a$
+\end_inset
+
+,
+\begin_inset Formula $b$
+\end_inset
+
+.
+ It follows that
+\begin_inset Formula $(x,y)\in r^{\updownarrow P}$
+\end_inset
+
+.
+
+\begin_inset Formula $\square$
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+The following examples will help build up more intuition.
+\end_layout
+
+\begin_layout Subsubsection
+Example
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Example-undisjunctive-type-constructors"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-undisjunctive-type-constructors"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\begin_inset Index idx
+status collapsed
+
+\begin_layout Plain Layout
+examples
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(a)
+\series default
+ Show that
+\begin_inset Formula $P^{A}\triangleq A\times F^{A}\rightarrow A$
+\end_inset
+
+ is lifting-to-full for any
+\begin_inset Formula $F$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(b)
+\series default
+ Show that
+\begin_inset Formula $P^{A}\triangleq\bbnum 1+F^{A}\rightarrow A$
+\end_inset
+
+ is both lifting-to-full and lifting-to-empty for any
+\begin_inset Formula $F$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(c)
+\series default
+ Show that
+\begin_inset Formula $P^{A}\triangleq F^{A}\rightarrow A$
+\end_inset
+
+ is lifting-to-full for any
+\begin_inset Formula $F$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(d)
+\series default
+ Show that
+\begin_inset Formula $P^{A}\triangleq\underbrace{A\times...\times A}_{n\text{ times, }n\geq1}$
+\end_inset
+
+ is both lifting-to-full and lifting-to-empty.
+\end_layout
+
+\begin_layout Standard
+It follows from Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-undisjunctive-type-constructors-relational"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ that all the above type constructors denoted by
+\begin_inset Formula $P$
+\end_inset
+
+ are non-disjunctive.
+
+\end_layout
+
+\begin_layout Standard
+For any type constructors
+\begin_inset Formula $F$
+\end_inset
+
+,
+\begin_inset Formula $G$
+\end_inset
+
+ (not necessarily covariant or contravariant):
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(e)
+\series default
+
+\begin_inset Formula $\forall A.\,F^{A}+G^{A}\cong(\forall A.\,F^{A})+(\forall A.\,G^{A})$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(f)
+\series default
+
+\begin_inset Formula $\forall A.\,\underbrace{A\times...\times A}_{n\text{ times, }n\geq1}\rightarrow F^{A}+G^{A}\cong(\forall A.\,A\times...\times A\rightarrow F^{A})+(\forall A.\,A\times...\times A\rightarrow G^{A})$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Subparagraph
+Solution
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(a)
+\series default
+ We know from Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-undisjunctive-type-constructors-structural"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+(c) that
+\begin_inset Formula $L^{A}\triangleq A$
+\end_inset
+
+ is lifting-to-full.
+ It follows from Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-undisjunctive-type-constructors-structural"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+(d) with
+\begin_inset Formula $K^{A}\triangleq A\times F^{A}$
+\end_inset
+
+ and
+\begin_inset Formula $L^{A}\triangleq A$
+\end_inset
+
+ that
+\begin_inset Formula $P$
+\end_inset
+
+ is also lifting-to-full.
\end_layout
\begin_layout Standard
@@ -40811,7 +41143,7 @@ noprefix "false"
\end_inset
(d) with
-\begin_inset Formula $K^{A}\triangleq\bbnum 1+A$
+\begin_inset Formula $K^{A}\triangleq\bbnum 1+F^{A}$
\end_inset
and
@@ -40841,7 +41173,11 @@ noprefix "false"
\end_inset
-(h) if we prove that
+(j) with
+\begin_inset Formula $Z=\bbnum 1$
+\end_inset
+
+ to see that
\begin_inset Formula $K^{A}$
\end_inset
@@ -40849,42 +41185,30 @@ noprefix "false"
\emph on
not
\emph default
- lifting-to-empty.
- Lifting any relation
-\begin_inset Formula $r^{:A\leftrightarrow B}$
-\end_inset
-
- to
-\begin_inset Formula $K$
+ lifting-to-empty, while we know that
+\begin_inset Formula $L^{A}$
\end_inset
-, we find:
-\begin_inset Formula
-\[
-r^{\updownarrow K}=\text{id}^{:\bbnum 1\leftrightarrow\bbnum 1}\boxplus r\quad.
-\]
-
+ is lifting-to-empty.
+ It follows from Statement
+\begin_inset space ~
\end_inset
-The pair of values
-\begin_inset Formula $x^{:K^{A}}\triangleq1+\bbnum 0^{:A}$
-\end_inset
- and
-\begin_inset Formula $y^{:K^{B}}\triangleq1+\bbnum 0^{:B}$
-\end_inset
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-undisjunctive-type-constructors-structural"
+plural "false"
+caps "false"
+noprefix "false"
- are always in the relation
-\begin_inset Formula $\text{id}\boxplus r$
\end_inset
-.
- In this way, we have shown that
-\begin_inset Formula $r^{\updownarrow K}$
+(h) that
+\begin_inset Formula $K$
\end_inset
- is not empty.
-
+ is lifting-to-empty.
\end_layout
\begin_layout Standard
@@ -40912,14 +41236,24 @@ noprefix "false"
\begin_layout Standard
Note that the type expression
-\begin_inset Formula $\bbnum 1+A\rightarrow A$
+\begin_inset Formula $\bbnum 1+F^{A}\rightarrow A$
\end_inset
- contains a disjunctive type but can be rewritten equivalently as
-\begin_inset Formula $P^{A}\cong(\bbnum 1\rightarrow A)\times(A\rightarrow A)$
+ appears to contain a disjunctive type but can be rewritten equivalently
+ as
+\begin_inset Formula $P^{A}\cong(\bbnum 1\rightarrow A)\times(F^{A}\rightarrow A)$
\end_inset
, which no longer contains a disjunctive type.
+ (If
+\begin_inset Formula $F^{A}$
+\end_inset
+
+ is disjunctive then
+\begin_inset Formula $F^{A}\rightarrow A$
+\end_inset
+
+ can be rewritten similarly.)
\end_layout
\begin_layout Standard
@@ -41097,68 +41431,390 @@ noprefix "false"
\end_layout
\begin_layout Standard
-We will now show some application of these techniques.
-\end_layout
+Table
+\begin_inset space ~
+\end_inset
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-application-full-relation"
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:Non-disjunctive-type-constructions"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ shows some general formulas for non-disjunctive type constructors that
+ follow from Statement
+\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-application-full-relation"
+reference "subsec:Statement-undisjunctive-type-constructors-structural"
plural "false"
caps "false"
noprefix "false"
\end_inset
-
+.
\end_layout
\begin_layout Standard
-Suppose
-\begin_inset Formula $F$
-\end_inset
+\begin_inset Float table
+wide false
+sideways false
+status open
- is any lifting-to-full type constructor that is not identically void (
-\begin_inset Formula $F^{A}\neq0$
-\end_inset
+\begin_layout Plain Layout
+\align center
+\begin_inset Tabular
+
+
+
+
+
+|
+\begin_inset Text
- for some
-\begin_inset Formula $A$
-\end_inset
+\begin_layout Plain Layout
-).
- Under assumptions of parametricity, we have the following type isomorphisms:
+\series bold
+\size footnotesize
+Construction
\end_layout
-\begin_layout Standard
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
\series bold
-(a)
-\series default
- For any fixed type
-\begin_inset Formula $P$
+\size footnotesize
+Assumptions
+\end_layout
+
\end_inset
+ |
+
+
+|
+\begin_inset Text
-:
-\begin_inset Formula
-\[
-\forall A.\,F^{A}\rightarrow P\cong P\quad.
-\]
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq A$
\end_inset
\end_layout
-\begin_layout Standard
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq G^{A}\rightarrow A$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+For any
+\begin_inset Formula $G^{A}$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq G^{A}\rightarrow H^{A}$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $H$
+\end_inset
+
+ is lifting-to-full,
+\begin_inset Formula $G$
+\end_inset
+
+ is any type constructor
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq A\times G^{A}\rightarrow H^{A}$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+For any
+\begin_inset Formula $G^{A}$
+\end_inset
+
+ and for any
+\begin_inset Formula $H^{A}$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq(Z+K^{A}\rightarrow A\times G^{A})\rightarrow H^{A}$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+For any
+\begin_inset Formula $G^{A}$
+\end_inset
+
+,
+\begin_inset Formula $H^{A}$
+\end_inset
+
+,
+\begin_inset Formula $K^{A}$
+\end_inset
+
+, and a fixed type
+\begin_inset Formula $Z\neq\bbnum 0$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq((L^{A}\rightarrow Z+K^{A})\rightarrow A\times G^{A})\rightarrow H^{A}$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+For any
+\begin_inset Formula $G^{A}$
+\end_inset
+
+,
+\begin_inset Formula $H^{A}$
+\end_inset
+
+,
+\begin_inset Formula $K^{A}$
+\end_inset
+
+,
+\begin_inset Formula $L^{A}$
+\end_inset
+
+, and
+\begin_inset Formula $Z\neq\bbnum 0$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+\begin_inset Caption Standard
+
+\begin_layout Plain Layout
+Lifting-to-full type constructors.
+\begin_inset CommandInset label
+LatexCommand label
+name "tab:Non-disjunctive-type-constructions"
+
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+We will now show some application of these techniques.
+\end_layout
+
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-application-full-relation"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-application-full-relation"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Suppose
+\begin_inset Formula $F$
+\end_inset
+
+ is any lifting-to-full type constructor that is not identically void (
+\begin_inset Formula $F^{A}\neq\bbnum 0$
+\end_inset
+
+ for some
+\begin_inset Formula $A$
+\end_inset
+
+).
+ Under assumptions of parametricity, we have the following type isomorphisms:
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(a)
+\series default
+ For any fixed type
+\begin_inset Formula $P$
+\end_inset
+
+:
+\begin_inset Formula
+\[
+\forall A.\,F^{A}\rightarrow P\cong P\quad.
+\]
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
\series bold
(b)
@@ -41409,7 +42065,7 @@ Since
that satisfy the relational naturality law.
This proves the required type equivalence.
\begin_inset Note Note
-status open
+status collapsed
\begin_layout Plain Layout
@@ -41860,7 +42516,7 @@ Under assumptions of parametricity:
\end_inset
- The
+The
\begin_inset Quotes eld
\end_inset
@@ -41923,6 +42579,26 @@ t_{n,k}^{A}\triangleq p^{:(A\rightarrow A)\rightarrow A}\rightarrow p(a_{1}^{:A}
\begin_layout Subparagraph
Proof
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+See
+\family typewriter
+
+\begin_inset CommandInset href
+LatexCommand href
+target "https://cstheory.stackexchange.com/questions/53855/"
+literal "false"
+
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -42560,8 +43236,20 @@ status open
\end_inset
.
- If we imagine that [X] were an ordinary argument (not a type parameter),
- we would apply the standard type identities:
+ If we imagine that
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+[X]
+\end_layout
+
+\end_inset
+
+ were an ordinary argument (not a type parameter), we would apply the standard
+ type identities:
\begin_inset Formula
\begin{align*}
& A\rightarrow B\times C\cong(A\rightarrow B)\times(A\rightarrow C)\quad,\\
@@ -42661,7 +43349,7 @@ X
\end_inset
- is a type parameter, not a value parameter, so it is invalid to use ordinary
+ is a type parameter, not a value parameter, and it is invalid to use ordinary
type identities such as
\begin_inset Formula $A\rightarrow R\rightarrow B\cong R\rightarrow A\rightarrow B$
\end_inset
@@ -42696,7 +43384,7 @@ Proof
\series bold
(a)
\series default
- This isomorphism is shown in Example
+ This isomorphism is proved in Example
\begin_inset space ~
\end_inset
@@ -42711,7 +43399,11 @@ noprefix "false"
\end_inset
(e).
- It is a
+
+\end_layout
+
+\begin_layout Standard
+It is a
\begin_inset Quotes eld
\end_inset
@@ -43395,7 +44087,7 @@ For any strictly positive bifunctor
, we have:
\begin_inset Formula
\[
-\forall A.\,S^{P^{A},Q^{A}}\cong S^{\forall A.\,P^{A},\forall A.\,Q^{A}}\quad.
+\forall A.\,S^{P^{A},\,Q^{A}}\cong S^{\forall A.\,P^{A},\,\forall A.\,Q^{A}}\quad.
\]
\end_inset
@@ -43560,9 +44252,9 @@ The functor
.) We get:
\begin_inset Formula
\begin{align*}
- & \forall A.\,F^{P^{A}}=\forall A.\,S^{P^{A},F^{P^{A}}}\\
-\text{inductive assumption}:\quad & \cong S^{\forall A.\,P^{A},\gunderline{\forall A.\,F^{P^{A}}}}\\
-\text{inductive assumption}:\quad & \cong S^{\forall A.\,P^{A},F^{\forall A.\,P^{A}}}=F^{\forall A.\,P^{A}}\quad.
+ & \forall A.\,F^{P^{A}}=\forall A.\,S^{P^{A},\,F^{P^{A}}}\\
+\text{inductive assumption}:\quad & \cong S^{\forall A.\,P^{A},\,\gunderline{\forall A.\,F^{P^{A}}}}\\
+\text{inductive assumption}:\quad & \cong S^{\forall A.\,P^{A},\,F^{\forall A.\,P^{A}}}=F^{\forall A.\,P^{A}}\quad.
\end{align*}
\end_inset
@@ -43606,7 +44298,7 @@ noprefix "false"
\end_inset
-
+
\end_layout
\begin_layout Standard
@@ -44272,6 +44964,39 @@ noprefix "false"
\begin_inset Formula $F$
\end_inset
+.
+ (See Definition
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Definition-strictly-positive-functor"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.) It is unknown if this holds for covariant functors
+\begin_inset Formula $F$
+\end_inset
+
+ that are not strictly positive; see Problem
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "par:Problem-Peirce-law-1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
.
\end_layout
@@ -44492,58 +45217,66 @@ not
\end_layout
\begin_layout Subsection
-The Jaskelioff-O'Connor theorem for simple types
-\end_layout
+Existential type quantifiers.
+ Co-Yoneda identities
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Existential-type-quantifiers"
-\begin_layout Standard
-The Jaskelioff-O'Connor theorem
-\begin_inset Foot
-status open
+\end_inset
-\begin_layout Plain Layout
-See
-\family typewriter
-\begin_inset CommandInset href
-LatexCommand href
-target "https://arxiv.org/abs/1402.1699"
-literal "false"
+\end_layout
-\end_inset
+\begin_layout Standard
+The Yoneda identities allow us in many cases to simplify type expressions
+ with universal quantifiers.
+ Similar identities hold for existentially quantified types.
+\end_layout
+\begin_layout Standard
+For the purposes of this and the following sections, we define the existential
+ quantifier via Eq.
+\begin_inset space ~
+\end_inset
-\end_layout
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:existential-via-universal-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
- is a type equivalence between certain type constructors quantified over
- a typeclass.
- This section proves a version of that theorem that holds for simple types
- belonging to a
-\begin_inset Formula $P$
+):
+\begin_inset Formula
+\[
+\exists C.\,F^{C}\cong\forall D.\,\big(\forall C.\,(F^{C}\rightarrow D)\big)\rightarrow D\quad.
+\]
+
\end_inset
--typeclass.
- Then the theorem gives a general type formula for the free construction
- of any
-\begin_inset Formula $P$
+Here
+\begin_inset Formula $F$
\end_inset
--typeclass.
+ is any type constructor (not necessarily covariant or contravariant).
\end_layout
\begin_layout Subsubsection
Statement
\begin_inset CommandInset label
LatexCommand label
-name "subsec:Statement-JOC-theorem-simple-types"
+name "subsec:Statement-co-Yoneda-two-identities"
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-JOC-theorem-simple-types"
+reference "subsec:Statement-co-Yoneda-two-identities"
plural "false"
caps "false"
noprefix "false"
@@ -44554,88 +45287,71 @@ noprefix "false"
\end_layout
\begin_layout Standard
-The free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass instance
-\begin_inset Formula $E^{T}$
+For any functor
+\begin_inset Formula $F$
\end_inset
- generated by a type
-\begin_inset Formula $T$
+ and any contrafunctor
+\begin_inset Formula $H$
\end_inset
- is equivalent to the type defined by:
+, the following identities hold:
\begin_inset Formula
-\begin{equation}
-E^{T}\cong\forall(A\in P\text{-typeclass}).\,(T\rightarrow A)\rightarrow A\quad.\label{eq:free-typeclass-via-church-encoding}
-\end{equation}
+\begin{align*}
+\text{\textbf{(a)} }\text{covariant co-Yoneda identity}:\quad & \exists A.\,(A\rightarrow R)\times F^{A}\cong F^{R}\quad,\\
+\text{\textbf{(b)} }\text{contravariant co-Yoneda identity}:\quad & \exists A.\,(R\rightarrow A)\times H^{A}\cong H^{R}\quad.
+\end{align*}
\end_inset
-Here the quantifier goes only over the types
-\begin_inset Formula $A$
-\end_inset
- that belong to the
-\begin_inset Formula $P$
-\end_inset
+\end_layout
--typeclass.
- It is also assumed that the type in the right-hand side of Eq.
+\begin_layout Subparagraph
+Proof
+\end_layout
+
+\begin_layout Standard
+We use Eq.
\begin_inset space ~
\end_inset
(
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:free-typeclass-via-church-encoding"
+reference "eq:existential-via-universal-Yoneda"
plural "false"
caps "false"
noprefix "false"
\end_inset
-) admits only functions that satisfy the naturality law with respect to
-
-\begin_inset Formula $A$
+) to express
+\begin_inset Formula $\exists A$
\end_inset
-.
-\end_layout
+ via
+\begin_inset Formula $\forall A$
+\end_inset
-\begin_layout Subparagraph
-Proof
+.
+
\end_layout
\begin_layout Standard
-One of the defining properties of the free typeclass constructor
-\begin_inset Formula $E$
-\end_inset
-
- is the one-to-one correspondence between functions of type
-\begin_inset Formula $T\rightarrow A$
-\end_inset
-
- and
-\begin_inset Formula $P$
-\end_inset
-
--typeclass morphisms of type
-\begin_inset Formula $E^{T}\rightarrow A$
-\end_inset
-
-.
- Denoting by
-\begin_inset Formula $E^{T}\overset{P}{\rightarrow}A$
-\end_inset
- the type of those morphisms, we have:
+\series bold
+(a)
+\series default
+ We write:
\begin_inset Formula
-\[
-\forall(A\in P\text{-typeclass}).\,(T\rightarrow A)\rightarrow A\cong\forall(A\in P\text{-typeclass}).\,(E^{T}\overset{P}{\rightarrow}A)\rightarrow A\quad.
-\]
+\begin{align*}
+\text{expect to equal }F^{R}:\quad & \exists A.\,(A\rightarrow R)\times F^{A}\\
+\text{definition of }\exists\text{ in Eq.~}(\ref{eq:existential-via-universal-Yoneda}):\quad & \cong\forall B.\,\big(\forall A.\,\gunderline{(A\rightarrow R)\times F^{A}}\rightarrow B\big)\rightarrow B\\
+\text{uncurry arguments}:\quad & \cong\forall B.\,\big(\gunderline{\forall A.\,(A\rightarrow R)\rightarrow F^{A}\rightarrow B}\big)\rightarrow B\\
+\text{contravariant Yoneda identity}:\quad & \cong\gunderline{\forall B.\,\big(F^{R}\rightarrow B\big)\rightarrow B}\\
+\text{covariant Yoneda identity}:\quad & \cong F^{R}\quad.
+\end{align*}
\end_inset
@@ -44643,231 +45359,140 @@ One of the defining properties of the free typeclass constructor
\end_layout
\begin_layout Standard
-All types
-\begin_inset Formula $A$
-\end_inset
-
- belonging to the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass are
-\begin_inset Formula $E$
-\end_inset
--monad algebras, and those algebras form a category.
- Now we use the Yoneda identity in that category:
+\series bold
+(b)
+\series default
+ We write:
\begin_inset Formula
-\[
-\forall(A\in P\text{-typeclass}).\,(X\overset{P}{\rightarrow}A)\rightarrow A\cong X\quad,
-\]
-
-\end_inset
-
-where
-\begin_inset Formula $X$
-\end_inset
-
- is any fixed type that also belongs to the
-\begin_inset Formula $P$
-\end_inset
+\begin{align*}
+\text{expect to equal }H^{R}:\quad & \exists A.\,(R\rightarrow A)\times H^{A}\\
+\text{definition of }\exists\text{ in Eq.~}(\ref{eq:existential-via-universal-Yoneda}):\quad & \cong\forall B.\,\big(\forall A.\,\gunderline{(R\rightarrow A)\times H^{A}}\rightarrow B\big)\rightarrow B\\
+\text{uncurry arguments}:\quad & \cong\forall B.\,\big(\gunderline{\forall A.\,(R\rightarrow A)\rightarrow H^{A}\rightarrow B}\big)\rightarrow B\\
+\text{covariant Yoneda identity}:\quad & \cong\gunderline{\forall B.\,\big(H^{R}\rightarrow B\big)\rightarrow B}\\
+\text{covariant Yoneda identity}:\quad & \cong H^{R}\quad.
+\end{align*}
--typeclass.
- We use this identity with
-\begin_inset Formula $X=E^{T}$
\end_inset
- and obtain:
-\begin_inset Formula
-\[
-\forall(A\in P\text{-typeclass}).\,(E^{T}\overset{P}{\rightarrow}A)\rightarrow A\cong E^{T}\quad,
-\]
-
-\end_inset
-as required.
-
\begin_inset Formula $\square$
\end_inset
\end_layout
-\begin_layout Subsection
-The Jaskelioff-O'Connor theorem for type constructors
-\end_layout
-
\begin_layout Standard
-The full formulation of the theorem involves functor typeclasses instead
- of typeclasses for simple types.
- The theorem applies to all
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses for functors.
- Those typeclasses have method signatures of the form
-\begin_inset Formula $\forall A.\,(P^{F})^{A}\rightarrow F^{A}$
-\end_inset
-
-, where
-\begin_inset Formula $P$
-\end_inset
-
- is a functor on functors (the kind of
-\begin_inset Formula $P$
-\end_inset
-
- is
-\begin_inset Formula $(*\rightarrow*)\rightarrow*\rightarrow*$
-\end_inset
-
-) and functions of type
-\begin_inset Formula $(P^{F})^{A}\rightarrow F^{A}$
-\end_inset
-
- are restricted to natural transformations between functors
-\begin_inset Formula $P^{F}$
+To build up intuition, let us substitute
+\begin_inset Formula $R=\bbnum 0$
\end_inset
and
-\begin_inset Formula $F$
-\end_inset
-
-.
- Examples of well-known
-\begin_inset Formula $P$
+\begin_inset Formula $R=\bbnum 1$
\end_inset
--typeclasses of that form are pointed functors, filterable functors, applicative
- functors, and monads.
+ into the co-Yoneda identities:
\end_layout
\begin_layout Subsubsection
Statement
\begin_inset CommandInset label
LatexCommand label
-name "subsec:Statement-Jaskelioff-OConnor"
+name "subsec:Statement-co-Yoneda-two-identities-1"
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-Jaskelioff-OConnor"
+reference "subsec:Statement-co-Yoneda-two-identities-1"
plural "false"
caps "false"
noprefix "false"
\end_inset
- (Jaskelioff-O'Connor)
+
\end_layout
\begin_layout Standard
-Given any fixed
-\begin_inset Formula $P$
-\end_inset
-
--typeclass for functors, denote by
-\begin_inset Formula $E$
-\end_inset
-
- the constructor of free instances of that typeclass: if
-\begin_inset Formula $T$
-\end_inset
+The following type equivalences hold:
+\begin_inset Formula
+\begin{align*}
+\text{\textbf{(a)} for any functor }F:\quad & \exists A.\,F^{A}\cong F^{\bbnum 1}\quad,\\
+\text{\textbf{(b)} for any contrafunctor }F:\quad & \exists A.\,H^{A}\cong H^{\bbnum 0}\quad.
+\end{align*}
- is any functor then the functor
-\begin_inset Formula $E^{T}$
\end_inset
- is guaranteed to be an instance of the
-\begin_inset Formula $P$
-\end_inset
--typeclass.
- Suppose
-\begin_inset Formula $A$
-\end_inset
+\end_layout
-,
-\begin_inset Formula $B$
-\end_inset
+\begin_layout Subparagraph
+Proof
+\end_layout
-,
-\begin_inset Formula $C$
+\begin_layout Standard
+For
+\series bold
+(a)
+\series default
+, set
+\begin_inset Formula $R=\bbnum 1$
\end_inset
- are some fixed types.
- Then the following type equivalence holds:
+ in the covariant co-Yoneda identity:
\begin_inset Formula
-\begin{align}
- & \forall(F\in P\text{-typeclass}).\,(A\rightarrow F^{B})\rightarrow F^{C}\cong(E^{R})^{C}\quad,\label{eq:jaskelioff-o-connor-theorem}\\
-\text{where }R\text{ is defined by}:\quad & R^{T}\triangleq A\times(B\rightarrow T)\quad.\nonumber
-\end{align}
-
-\end_inset
-
-Here, it is assumed that the type
-\begin_inset Formula $(A\rightarrow F^{B})\rightarrow F^{C}$
-\end_inset
+\begin{align*}
+\text{left-hand side}:\quad & \exists A.\,(\gunderline{A\rightarrow\bbnum 1})\times F^{A}\cong\exists A.\,\bbnum 1\times F^{A}\cong\exists A.\,F^{A}\quad,\\
+\text{right-hand side}:\quad & F^{\bbnum 1}\quad.
+\end{align*}
- is restricted to functions satisfying the naturality law with respect to
-
-\begin_inset Formula $F$
\end_inset
-.
-\end_layout
-\begin_layout Subparagraph
-Proof
\end_layout
\begin_layout Standard
-Denote by
-\begin_inset Formula $K\overset{P}{\rightarrow}L$
-\end_inset
-
- the type of
-\begin_inset Formula $P$
+For
+\series bold
+(b)
+\series default
+, set
+\begin_inset Formula $R=\bbnum 0$
\end_inset
--typeclass morphisms between functors
-\begin_inset Formula $K$
-\end_inset
+ in the contravariant co-Yoneda identity:
+\begin_inset Formula
+\begin{align*}
+\text{left-hand side}:\quad & \exists A.\,(\gunderline{\bbnum 0\rightarrow A})\times H^{A}\cong\exists A.\,\bbnum 1\times H^{A}\cong\exists A.\,H^{A}\quad,\\
+\text{right-hand side}:\quad & H^{\bbnum 0}\quad.
+\end{align*}
- and
-\begin_inset Formula $L$
\end_inset
- that belong to the typeclass.
- (The full type signature of a
-\begin_inset Formula $P$
+
+\begin_inset Formula $\square$
\end_inset
--typeclass morphism is
-\begin_inset Formula $\forall A.\,K^{A}\overset{P}{\rightarrow}L^{A}$
-\end_inset
-.)
\end_layout
\begin_layout Standard
-We will prove the type equivalence
-\begin_inset space ~
+With these properties, we get the following examples of type equivalences:
+\begin_inset Formula
+\begin{align*}
+ & \exists A.\,A\cong\bbnum 1\quad,\quad\quad\exists A.\,A\rightarrow R\cong\bbnum 1\quad,\quad\quad\exists A.\,A+R\cong\bbnum 1+R\quad,\\
+ & \exists A.\,(R\rightarrow A)\times(A\rightarrow S)\cong R\rightarrow S\quad,\quad\quad\exists A.\,(A\rightarrow R)\times A\times A\cong R\times R\quad.
+\end{align*}
+
\end_inset
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:jaskelioff-o-connor-theorem"
-plural "false"
-caps "false"
-noprefix "false"
-\end_inset
+\end_layout
-) in three steps.
+\begin_layout Paragraph
+Remarks
\end_layout
\begin_layout Standard
@@ -44875,364 +45500,3080 @@ noprefix "false"
\series bold
(1)
\series default
- Use the Yoneda identity to obtain this type equivalence:
-\begin_inset Formula
-\[
-A\rightarrow F^{B}\cong\forall X.\,R^{X}\rightarrow F^{X}\quad.
-\]
+ The Scala type
+\begin_inset listings
+inline true
+status open
-\end_inset
+\begin_layout Plain Layout
-To derive this formula, write:
-\begin_inset Formula
-\begin{align*}
- & A\rightarrow F^{B}\\
-\text{covariant Yoneda identity}:\quad & \cong A\rightarrow\forall X.\,(B\rightarrow X)\rightarrow F^{X}\\
-\text{move }\forall X\text{ to front}:\quad & \cong\forall X.\,A\rightarrow(B\rightarrow X)\rightarrow F^{X}\\
-\text{uncurry the function}:\quad & \cong\forall X.\,A\times(B\rightarrow X)\rightarrow F^{X}=\forall X.\,R^{X}\rightarrow F^{X}\quad.
-\end{align*}
+Any
+\end_layout
\end_inset
-In the first line of this derivation, we have used the assumption that
-\begin_inset Formula $F$
+ closely corresponds to the type
+\begin_inset Formula $\exists X.\,X$
\end_inset
- is a (covariant) functor.
-\end_layout
+, which is equivalent to
+\begin_inset listings
+inline true
+status open
-\begin_layout Standard
+\begin_layout Plain Layout
-\series bold
-(2)
-\series default
- By the universal property of the free
-\begin_inset Formula $P$
-\end_inset
+Unit
+\end_layout
--typeclass runner, for any functor
-\begin_inset Formula $F$
\end_inset
- that belongs to the
-\begin_inset Formula $P$
-\end_inset
+.
+ The advantage of using
+\begin_inset listings
+inline true
+status open
--typeclass and for any functor
-\begin_inset Formula $R$
-\end_inset
+\begin_layout Plain Layout
- (not necessarily a member of the
-\begin_inset Formula $P$
-\end_inset
+Any
+\end_layout
--typeclass) there is a one-to-one correspondence between
-\begin_inset Formula $P$
\end_inset
--typeclass morphisms
-\begin_inset Formula $E^{R}\overset{P}{\rightarrow}F$
-\end_inset
+ instead of
+\begin_inset listings
+inline true
+status open
- and natural transformations
-\begin_inset Formula $R\leadsto F$
-\end_inset
+\begin_layout Plain Layout
-.
- In other words, there is a type equivalence between the following types
- (where we wrote out the full type signatures):
-\begin_inset Formula
-\[
-\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X}\cong\forall X.\,R^{X}\rightarrow F^{X}\quad.
-\]
+Unit
+\end_layout
\end_inset
-Now we set
-\begin_inset Formula $R^{T}\triangleq A\times(B\rightarrow T)$
+ is that
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Any
+\end_layout
+
+\end_inset
+
+ is understood by the Scala compiler as a supertype of
+\emph on
+all
+\emph default
+ Scala types (while
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Unit
+\end_layout
+
+\end_inset
+
+ is not).
+ Indeed, for any type
+\begin_inset Formula $T$
+\end_inset
+
+ there is an injective function
+\begin_inset Formula $T\rightarrow\exists X.\,X$
+\end_inset
+
+, which corresponds to a function of type
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+T => Any
+\end_layout
+
+\end_inset
+
+ in Scala:
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+def toAny[T](t: T): Any = t
+\end_layout
+
+\end_inset
+
+ This is just an identity function that relabels the types.
+ So, this function establishes the subtyping relation
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+T <: Any
+\end_layout
+
+\end_inset
+
+.
+
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(2)
+\series default
+ The type equivalence
+\begin_inset Formula $\exists X.\,X\cong\bbnum 1$
+\end_inset
+
+ may appear counterintuitive.
+ The unit type has only one distinct value; but there are infinitely many
+ ways of creating a value of type
+\begin_inset Formula $\exists X.\,X$
+\end_inset
+
+.
+ We may take any value
+\begin_inset Formula $t:T$
+\end_inset
+
+ of any type
+\begin_inset Formula $T$
+\end_inset
+
+ and
+\begin_inset Quotes eld
+\end_inset
+
+pack
+\begin_inset Quotes erd
+\end_inset
+
+ that value into a value of type
+\begin_inset Formula $\exists X.\,X$
+\end_inset
+
+ by hiding the type
+\begin_inset Formula $T$
+\end_inset
+
+, similarly to the function
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+toAny
+\end_layout
+
+\end_inset
+
+.
+\begin_inset listings
+lstparams "mathescape=true"
+inline false
+status open
+
+\begin_layout Plain Layout
+
+sealed trait ExistsX // Implements the type $
+\backslash
+color{dkgreen}
+\backslash
+exists X.
+\backslash
+,X$.
+\end_layout
+
+\begin_layout Plain Layout
+
+final case class ExistsX0[X](x: X)
+\end_layout
+
+\begin_layout Plain Layout
+
+def hide[T](t: T): ExistsX = ExistsX0[T](t)
+\end_layout
+
+\begin_layout Plain Layout
+
+val x1: ExistsX = hide(123)
+\end_layout
+
+\begin_layout Plain Layout
+
+val x2: ExistsX = hide(124)
+\end_layout
+
+\begin_layout Plain Layout
+
+val x3: ExistsX = hide(
+\begin_inset Quotes eld
+\end_inset
+
+abc
+\begin_inset Quotes erd
+\end_inset
+
+)
+\end_layout
+
+\end_inset
+
+This code may suggest that we are able to create many different values of
+ type
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+ExistsX
+\end_layout
+
+\end_inset
+
+.
+ How can it be that
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+ExistsX
+\end_layout
+
+\end_inset
+
+ is equivalent to a unit type with a single distinct value? The reason is
+ that no fully parametric functions will be able to detect any difference
+ between all those values.
+ A fully parametric function may pattern-match on
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+ExistsX0(x)
+\end_layout
+
+\end_inset
+
+ but must treat the type of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+x
+\end_layout
+
+\end_inset
+
+ as arbitrary and unknown, with no operations available for computing anything
+ out of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+x
+\end_layout
+
+\end_inset
+
+.
+ So, there will be no way to determine the actual type and value of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+x
+\end_layout
+
+\end_inset
+
+ and to make any decisions based on them.
+ A computer's memory will probably store different bit patterns when representin
+g
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+hide(123)
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+hide(124)
+\end_layout
+
+\end_inset
+
+.
+ But that difference remains unobservable in fully parametric code.
+
+\begin_inset Formula $\square$
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+We may use Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:existential-via-universal-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) to replace the existential quantifier by the universal one when proving
+ properties of existentially quantified types.
+\end_layout
+
+\begin_layout Subsubsection
+Example
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Example-simple-existential-derivation"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-simple-existential-derivation"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+examples
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Show that
+\begin_inset Formula $\exists A.\,F^{A}\rightarrow A\cong\bbnum 1$
+\end_inset
+
+ for any type constructor
+\begin_inset Formula $F$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Subparagraph
+Solution
+\end_layout
+
+\begin_layout Standard
+Use Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:existential-via-universal-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) and write:
+\begin_inset Formula
+\[
+\exists A.\,F^{A}\rightarrow A=\forall B.\,(\forall A.\,(F^{A}\rightarrow A)\rightarrow B)\rightarrow B\quad.
+\]
+
+\end_inset
+
+Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-application-full-relation"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ with
+\begin_inset Formula $P^{A}\triangleq F^{A}\rightarrow A$
+\end_inset
+
+ and
+\begin_inset Formula $K\triangleq B$
+\end_inset
+
+ shows that
+\begin_inset Formula $\forall A.\,(F^{A}\rightarrow A)\rightarrow B\cong B$
+\end_inset
+
+ as the type constructor
+\begin_inset Formula $F^{A}\rightarrow A$
+\end_inset
+
+ is
+\begin_inset Quotes eld
+\end_inset
+
+lifting-to-full
+\begin_inset Quotes erd
+\end_inset
+
+ by Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-undisjunctive-type-constructors-structural"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+(c, d).
+ So, we get:
+\begin_inset Formula
+\[
+\exists A.\,F^{A}\rightarrow A=\forall B.\,B\rightarrow B\cong\bbnum 1\quad.
+\]
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subsubsection
+Example
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Example-simple-existential-derivation-1-1"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-simple-existential-derivation-1-1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Let
+\begin_inset Formula $P$
+\end_inset
+
+ and
+\begin_inset Formula $Q$
+\end_inset
+
+ be any type constructors.
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(a)
+\series default
+ If
+\begin_inset Formula $P^{A}\cong Q^{A}$
+\end_inset
+
+ for all
+\begin_inset Formula $A$
+\end_inset
+
+ then
+\begin_inset Formula $\exists A.\,P^{A}\cong\exists A.\,Q^{A}$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(b)
+\series default
+ For arbitrary
+\begin_inset Formula $P$
+\end_inset
+
+ and
+\begin_inset Formula $Q$
+\end_inset
+
+:
+\begin_inset Formula
+\[
+\exists A.\,P^{A}+Q^{A}\cong(\exists A.\,P^{A})+(\exists A.\,Q^{A})\quad.
+\]
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(c)
+\series default
+ Show that following type identities do
+\emph on
+not
+\emph default
+ hold in general:
+\begin_inset Formula
+\begin{align*}
+ & \exists A.\,P^{A}\times Q^{A}\not\cong(\exists A.\,P^{A})\times(\exists A.\,Q^{A})\quad,\\
+ & R\rightarrow(\exists A.\,P^{A})\not\cong\exists A.\,R\rightarrow P^{A}\quad.
+\end{align*}
+
+\end_inset
+
+(Similar identities do hold for the universal quantifiers; see Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-general-identities-forall"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.)
+\end_layout
+
+\begin_layout Subparagraph
+Solution
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(a)
+\series default
+ Suppose we have an isomorphism:
+\begin_inset Formula
+\[
+f^{A}:P^{A}\rightarrow Q^{A}\quad,\quad\quad g^{A}:Q^{A}\rightarrow P^{A}\quad.
+\]
+
+\end_inset
+
+The types
+\begin_inset Formula $\exists A.\,P^{A}$
+\end_inset
+
+ and
+\begin_inset Formula $\exists A.\,Q^{A}$
+\end_inset
+
+ are equivalent to some type expressions involving only universal quantifiers
+ and the type constructors
+\begin_inset Formula $P$
+\end_inset
+
+,
+\begin_inset Formula $Q$
+\end_inset
+
+.
+\begin_inset Formula
+\begin{align*}
+ & \exists A.\,P^{A}\cong\exists A.\,Q^{A}\\
+\text{is the same as}:\quad & \forall D.\,(\forall A.\,P^{A}\rightarrow D)\rightarrow D\cong\forall D.\,(\forall A.\,Q^{A}\rightarrow D)\rightarrow D\quad.
+\end{align*}
+
+\end_inset
+
+Then we can apply Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-isomorphism-under-type-constructor"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ repeatedly to show that those type expressions are isomorphic as types:
+\begin_inset Formula
+\begin{align*}
+ & \forall A.\,P^{A}\rightarrow D\cong\forall A.\,Q^{A}\rightarrow D\quad,\\
+ & (\forall A.\,P^{A}\rightarrow D)\rightarrow D\cong(\forall A.\,Q^{A}\rightarrow D)\rightarrow D\quad,\\
+ & \forall D.\,(\forall A.\,P^{A}\rightarrow D)\rightarrow D\cong\forall D.\,(\forall A.\,Q^{A}\rightarrow D)\rightarrow D\quad.
+\end{align*}
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(b)
+\series default
+ Use Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:existential-via-universal-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) and write:
+\begin_inset Formula
+\begin{align*}
+ & \exists A.\,P^{A}+Q^{A}=\forall B.\,(\forall A.\,\gunderline{P^{A}+Q^{A}\rightarrow B})\rightarrow B\\
+ & =\forall B.\,(\forall A.\,(P^{A}\rightarrow B)\times(Q^{A}\rightarrow B))\rightarrow B\\
+ & =\forall B.\,(\gunderline{\forall A.\,P^{A}\rightarrow B})\times(\gunderline{\forall A.\,Q^{A}\rightarrow B})\rightarrow B\\
+\text{use Eq.\,(\ref{eq:existential-via-universal})}:\quad & =\forall B.\,(\gunderline{(\exists A.\,P^{A})\rightarrow B)\times((\exists A.\,Q^{A})\rightarrow B})\rightarrow B\\
+ & =\forall B.\,\big((\exists A.\,P^{A})+(\exists A.\,Q^{A})\,\gunderline{\rightarrow B\big)\rightarrow B}\\
+\text{Yoneda identity}:\quad & =(\exists A.\,P^{A})+(\exists A.\,Q^{A})\quad.
+\end{align*}
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(c)
+\series default
+ The first counter-example is found via the co-Yoneda identity itself:
+\begin_inset Formula
+\[
+\exists A.\,(A\rightarrow R)\times F^{A}\cong F^{R}\quad.
+\]
+
+\end_inset
+
+Splitting the left-hand side into a product of two existential types, we
+ get:
+\begin_inset Formula
+\[
+(\exists A.\,(A\rightarrow R))\times(\exists A.\,F^{A})\cong\bbnum 1\times F^{\bbnum 1}\cong F^{\bbnum 1}\quad.
+\]
+
+\end_inset
+
+But the last type is not equivalent to
+\begin_inset Formula $F^{R}$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+The second counter-example is with the following type:
+\begin_inset Formula
+\[
+P^{A}\triangleq(A\rightarrow Q)\times A\quad.
+\]
+
+\end_inset
+
+Here
+\begin_inset Formula $Q$
+\end_inset
+
+ is a fixed type.
+ By the co-Yoneda identity, we have
+\begin_inset Formula $\exists A.\,P^{A}\cong Q$
+\end_inset
+
+ and so
+\begin_inset Formula $R\rightarrow(\exists A.\,P^{A})\cong R\rightarrow Q$
+\end_inset
+
+.
+ Now let us simplify the other side:
+\begin_inset Formula
+\begin{align*}
+ & \exists A.\,R\rightarrow P^{A}=\exists A.\,R\rightarrow(A\rightarrow Q)\times A\\
+ & \quad\cong\exists A.\,(R\rightarrow A\rightarrow Q)\times(R\rightarrow A)\\
+\text{co-Yoneda identity}:\quad & \quad\cong R\rightarrow R\rightarrow Q\quad.
+\end{align*}
+
+\end_inset
+
+The last type is not equivalent to
+\begin_inset Formula $R\rightarrow Q$
+\end_inset
+
+.
+
+\begin_inset Formula $\square$
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-commute-existential"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-commute-existential"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ (co-Fubini theorem)
+\end_layout
+
+\begin_layout Standard
+For any type constructor
+\begin_inset Formula $P$
+\end_inset
+
+ with two parameters (not necessarily covariant or contravariant):
+\begin_inset Formula
+\[
+\exists A.\,\exists B.\,P^{A,B}\cong\exists B.\,\exists A.\,P^{A,B}\quad.
+\]
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subparagraph
+Proof
+\end_layout
+
+\begin_layout Standard
+We rewrite
+\begin_inset Formula $\exists A.\,\exists B.\,P^{A,B}$
+\end_inset
+
+ via universal quantifiers:
+\begin_inset Formula
+\begin{align*}
+ & \gunderline{\exists A.}\,\exists B.\,P^{A,B}\\
+\text{use Eq.\,(\ref{eq:existential-via-universal-Yoneda})}:\quad & \cong\forall D.\,\big(\forall A.\,\gunderline{(\exists B.\,P^{A,B})\rightarrow D})\rightarrow D\\
+\text{use Eq.\,(\ref{eq:existential-via-universal})}:\quad & \cong\forall D.\,\big(\forall A.\,\forall B.\,P^{A,B}\rightarrow D)\rightarrow D\quad.
+\end{align*}
+
+\end_inset
+
+If we rewrite
+\begin_inset Formula $\exists B.\,\exists A.\,P^{A,B}$
+\end_inset
+
+ similarly, we will get:
+\begin_inset Formula
+\[
+\exists B.\,\exists A.\,P^{A,B}\cong\forall D.\,\big(\forall B.\,\forall A.\,P^{A,B}\rightarrow D)\rightarrow D\quad.
+\]
+
+\end_inset
+
+Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-Fubini-theorem"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ gives
+\begin_inset Formula $\forall A.\,\forall B.\,P^{A,B}\cong\forall B.\,\forall A.\,P^{A,B}$
+\end_inset
+
+, completing the proof.
+
+\begin_inset Formula $\square$
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Now we will prove some more technical properties of existential types.
+\end_layout
+
+\begin_layout Standard
+In the next two statements, we work with a fixed type constructor
+\begin_inset Formula $P$
+\end_inset
+
+, which is not assumed to be covariant or contravariant.
+ For brevity, we denote:
+\begin_inset Formula
+\[
+E\triangleq\forall B.\,(\forall A.\,P^{A}\rightarrow B)\rightarrow B\quad.
+\]
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-identity-law-of-pack"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-identity-law-of-pack"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Values of type
+\begin_inset Formula $E$
+\end_inset
+
+ are constructed via the standard function
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pack
+\end_layout
+
+\end_inset
+
+ that has the following type signature:
+\begin_inset Formula
+\begin{align*}
+ & \text{pack}:\forall T.\,P^{T}\rightarrow E\quad,\\
+\text{or equivalently}:\quad & \text{pack}:\forall T.\,P^{T}\rightarrow\forall B.\,(\forall A.\,P^{A}\rightarrow B)\rightarrow B\quad,\\
+ & \text{pack}^{T}(p^{:P^{T}})\triangleq\forall B.\,\big(k^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow k^{T}(p)\quad.
+\end{align*}
+
+\end_inset
+
+Then the
+\series bold
+identity law
+\series default
+ of
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+identity laws!of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pack
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pack
+\end_layout
+
+\end_inset
+
+ holds: for any value
+\begin_inset Formula $e:E$
+\end_inset
+
+,
+\begin_inset Formula
+\begin{equation}
+e^{E}(\text{pack})=e\quad.\label{eq:identity-law-of-pack}
+\end{equation}
+
+\end_inset
+
+It is assumed that all values
+\begin_inset Formula $e^{:E}$
+\end_inset
+
+ obey their naturality law:
+\begin_inset Formula
+\begin{equation}
+\text{for all }f^{:B\rightarrow C},k^{:\forall A.\,P^{A}\rightarrow B}:\quad f(e^{B}(k))=e^{C}(\forall A.\,k^{A}\bef f)\quad.\label{eq:naturality-law-of-e-derivation1}
+\end{equation}
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subparagraph
+Proof
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+The author thanks
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+Dan Doel
+\end_layout
+
+\end_inset
+
+Dan Doel for assistance with the proof of this statement.
+ See the discussion at
+\family typewriter
+
+\begin_inset CommandInset href
+LatexCommand href
+target "https://cstheory.stackexchange.com/questions/54124"
+literal "false"
+
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Both sides of Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:identity-law-of-pack"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) have type
+\begin_inset Formula $E$
+\end_inset
+
+.
+ Since
+\begin_inset Formula $E$
+\end_inset
+
+ is a type of functions with a type parameter, the two sides can be applied
+ to an arbitrary type
+\begin_inset Formula $U$
+\end_inset
+
+ and an arbitrary value
+\begin_inset Formula $u:\forall A.\,P^{A}\rightarrow U$
+\end_inset
+
+ to get two values of type
+\begin_inset Formula $U$
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align*}
+\text{both sides of}:\quad & e^{E}(\text{pack})\overset{?}{=}e\\
+\text{can be applied to }U\text{ and }u\text{ and yield}:\quad & \big(e^{E}(\text{pack})\big)^{U}(u)\overset{?}{=}e^{U}(u)\quad.
+\end{align*}
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+So, let us prove that for all types
+\begin_inset Formula $U$
+\end_inset
+
+ and all values
+\begin_inset Formula $u:\forall A.\,P^{A}\rightarrow U$
+\end_inset
+
+,
+\begin_inset Formula
+\begin{equation}
+\big(e^{E}(\text{pack})\big)^{U}(u)\overset{?}{=}e^{U}(u)\quad.\label{eq:identity-law-of-pack-derivation1}
+\end{equation}
+
+\end_inset
+
+To prove the last equation, we will rewrite it in the form of the naturality
+ law
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:naturality-law-of-e-derivation1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) by finding suitable parameters
+\begin_inset Formula $B$
+\end_inset
+
+,
+\begin_inset Formula $C$
+\end_inset
+
+,
+\begin_inset Formula $f$
+\end_inset
+
+, and
+\begin_inset Formula $k$
+\end_inset
+
+.
+ Once we manage to do that, the proof of Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:identity-law-of-pack"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) will be completed.
+
+\end_layout
+
+\begin_layout Standard
+The left-hand side of Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:identity-law-of-pack-derivation1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) will match the left-hand side of Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:naturality-law-of-e-derivation1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) if we assign
+\begin_inset Formula $B=E$
+\end_inset
+
+,
+\begin_inset Formula $k=\text{pack}$
+\end_inset
+
+, and
+\begin_inset Formula $f(e)\triangleq e^{U}(u)$
+\end_inset
+
+.
+ The type of
+\begin_inset Formula $f$
+\end_inset
+
+ must be
+\begin_inset Formula $B\rightarrow C$
+\end_inset
+
+; since
+\begin_inset Formula $f(e)$
+\end_inset
+
+ has type
+\begin_inset Formula $U$
+\end_inset
+
+, we need to set
+\begin_inset Formula $C=U$
+\end_inset
+
+.
+ With these assignments, the right-hand side of Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:naturality-law-of-e-derivation1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) becomes:
+\begin_inset Formula
+\[
+e^{C}(k\bef f)=e^{U}(\forall A.\,\text{pack}^{A}\bef f)\quad.
+\]
+
+\end_inset
+
+This will be equal to the right-hand side
+\begin_inset Formula $e^{U}(u)$
+\end_inset
+
+ of Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:identity-law-of-pack-derivation1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) if we show that:
+\begin_inset Formula
+\[
+\forall A.\,\text{pack}^{A}\bef f\overset{?}{=}u\quad.
+\]
+
+\end_inset
+
+Substitute the definitions of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pack
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset Formula $f$
+\end_inset
+
+, renaming
+\begin_inset Formula $A$
+\end_inset
+
+ to
+\begin_inset Formula $T$
+\end_inset
+
+:
+\begin_inset Formula
+\[
+\forall T.\,\text{pack}^{T}\bef f=\forall T.\,p^{:P^{T}}\rightarrow f\big(\forall B.\,\big(q^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow q^{T}(p)\big)\quad.
+\]
+
+\end_inset
+
+The function
+\begin_inset Formula $f$
+\end_inset
+
+ substitutes
+\begin_inset Formula $B=U$
+\end_inset
+
+ and
+\begin_inset Formula $q=u$
+\end_inset
+
+ into its function parameter:
+\begin_inset Formula
+\[
+f\big(\forall B.\,\big(q^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow q^{T}(p)\big)=\big(\forall B.\,\big(q^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow q^{T}(p)\big)^{U}(u)=u^{T}(p)\quad.
+\]
+
+\end_inset
+
+So, we find:
+\begin_inset Formula
+\[
+\forall T.\,\text{pack}^{T}\bef f=\forall T.\,p^{:P^{T}}\rightarrow u^{T}(p)=\forall T.\,u^{T}=u\quad.
+\]
+
+\end_inset
+
+This completes the proof.
+
+\begin_inset Formula $\square$
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Finally, here is the key property required for proving the equivalence of
+ two formulations of existential types, Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:existential-via-universal"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) and Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:existential-via-universal-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+\end_layout
+
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-function-extension-rule"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-function-extension-rule"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+The following type isomorphism holds:
+\begin_inset Formula
+\begin{align*}
+ & E\rightarrow R=(\exists A.\,P^{A})\rightarrow R\cong\forall C.\,P^{C}\rightarrow R\quad,\\
+\text{or equivalently}:\quad & \big(\forall B.\,(\forall A.\,P^{A}\rightarrow B)\rightarrow B\big)\rightarrow R\cong\forall C.\,P^{C}\rightarrow R\quad,
+\end{align*}
+
+\end_inset
+
+where
+\begin_inset Formula $R$
+\end_inset
+
+ is a fixed type.
+ In this isomorphism, it is assumed that the type
+\begin_inset Formula $E$
+\end_inset
+
+ contains only functions
+\begin_inset Formula $e^{:E}$
+\end_inset
+
+ that obey the naturality law
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:naturality-law-of-e-derivation1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+
+\end_layout
+
+\begin_layout Standard
+This isomorphism can be also formulated via code like this:
+\begin_inset Formula
+\begin{equation}
+\text{for all }e^{:E}\text{ and }r^{:E\rightarrow R}:\quad r(e)=e^{R}(\forall C.\,\text{pack}^{C}\bef r)\quad,\label{eq:surjectivity-of-pack}
+\end{equation}
+
+\end_inset
+
+where the standard function
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pack
+\end_layout
+
+\end_inset
+
+ was defined in the proof of Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-identity-law-of-pack"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+ Any function
+\begin_inset Formula $r$
+\end_inset
+
+ that consumes values of type
+\begin_inset Formula $e$
+\end_inset
+
+ can be expressed via application of
+\begin_inset Formula $r$
+\end_inset
+
+ to values constructed via
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pack
+\end_layout
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Subparagraph
+Proof
+\end_layout
+
+\begin_layout Standard
+The isomorphism is shown by defining two functions (
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+inF
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+outF
+\end_layout
+
+\end_inset
+
+):
+\begin_inset Formula
+\begin{align*}
+ & \text{inF}:(\forall C.\,P^{C}\rightarrow R)\rightarrow E\rightarrow R\quad,\\
+ & \text{inF}\triangleq k^{:\forall C.\,P^{C}\rightarrow R}\rightarrow e^{:E}\rightarrow e^{R}(k)\quad,\\
+ & \text{outF}:(E\rightarrow R)\rightarrow\forall C.\,P^{C}\rightarrow R\quad,\\
+ & \text{outF}\triangleq r^{:E\rightarrow R}\rightarrow\forall C.\,p^{:P^{C}}\rightarrow r(\text{pack}^{C}(p))=r^{:E\rightarrow R}\rightarrow\forall C.\,\text{pack}^{C}\bef r\quad,
+\end{align*}
+
+\end_inset
+
+and by proving that those functions are inverses of each other.
+\end_layout
+
+\begin_layout Standard
+Without the type annotations, the code of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+inF
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+outF
+\end_layout
+
+\end_inset
+
+ is:
+\begin_inset Formula
+\[
+\text{inF}=k\rightarrow q\rightarrow q(k)\quad,\quad\quad\text{outF}=r\rightarrow p\rightarrow r(k\rightarrow k(p))\quad.
+\]
+
+\end_inset
+
+Now it is quick to prove one direction of isomorphism (
+\begin_inset Formula $\text{inF}\bef\text{outF}\overset{?}{=}\text{id}$
+\end_inset
+
+):
+\begin_inset Formula
+\begin{align*}
+\text{expect to equal }\text{id}:\quad & \text{inF}\bef\text{outF}=k\rightarrow\text{outF}\,(q\rightarrow q(k))\\
+ & =k\rightarrow p\rightarrow(q\rightarrow q(k))(k\rightarrow k(p))\\
+ & =k\rightarrow\gunderline{p\rightarrow k(p)}=k\rightarrow k=\text{id}\quad.
+\end{align*}
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+The other direction (
+\begin_inset Formula $\text{outF}\bef\text{inF}\overset{?}{=}\text{id}$
+\end_inset
+
+) requires more work.
+ The argument of the function
+\begin_inset Formula $\text{outF}\bef\text{inF}$
+\end_inset
+
+ has type
+\begin_inset Formula $E\rightarrow R$
+\end_inset
+
+, and we need to show that for any function
+\begin_inset Formula $r^{:E\rightarrow R}$
+\end_inset
+
+ the following equation holds:
+\begin_inset Formula
+\[
+\text{inF}\,(\text{outF}\,(r))\overset{?}{=}r\quad,\quad\text{or equivalently}:\quad r\triangleright\text{outF}\triangleright\text{inF}\overset{?}{=}r\quad.
+\]
+
+\end_inset
+
+The last equation is between functions of type
+\begin_inset Formula $E\rightarrow R$
+\end_inset
+
+; we may apply both sides to an arbitrary value
+\begin_inset Formula $e^{:E}$
+\end_inset
+
+ and require that the results (of type
+\begin_inset Formula $R$
+\end_inset
+
+) should be equal:
+\begin_inset Formula
+\[
+\big(r\triangleright\text{outF}\triangleright\text{inF}\big)(e)\overset{?}{=}r(e)\quad.
+\]
+
+\end_inset
+
+We begin by subtituting the definitions of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+inF
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+outF
+\end_layout
+
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align*}
+\text{expect to equal }r(e):\quad & e\triangleright\big(r\triangleright\text{outF}\triangleright\text{inF}\big)=e\triangleright\big((\forall A.\,p^{:P^{A}}\rightarrow r(\text{pack}^{A}(p)))\triangleright\text{inF}\big)\\
+ & =e^{R}\big(\forall A.\,p^{:P^{A}}\rightarrow r(\text{pack}^{A}(p))\big)=e^{R}(\forall A.\,\text{pack}^{A}\bef r)\quad.
+\end{align*}
+
+\end_inset
+
+Since
+\begin_inset Formula $e$
+\end_inset
+
+ is unknown and arbitrary, we can make progress in the proof only if we
+ use the naturality law of
+\begin_inset Formula $e$
+\end_inset
+
+ as given by Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:naturality-law-of-e-derivation1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ We assign
+\begin_inset Formula $B=E$
+\end_inset
+
+,
+\begin_inset Formula $C=R$
+\end_inset
+
+,
+\begin_inset Formula $f=r$
+\end_inset
+
+,
+\begin_inset Formula $k=\text{pack}$
+\end_inset
+
+ in that law and obtain:
+\begin_inset Formula
+\[
+r(e^{E}(\text{pack}))=e^{R}(\forall A.\,\text{pack}^{A}\bef r)\quad.
+\]
+
+\end_inset
+
+By the identity law of pack (Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-identity-law-of-pack"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+),
+\begin_inset Formula $e^{E}(\text{pack})=e$
+\end_inset
+
+.
+ So, we conclude the derivation:
+\begin_inset Formula
+\begin{align*}
+\text{expect to equal }r(e):\quad & e\triangleright\big(r\triangleright\text{outF}\triangleright\text{inF}\big)=\gunderline{e^{R}(\forall A.\,\text{pack}^{A}\bef r)}\\
+\text{naturality law of }e:\quad & =r(\gunderline{e^{E}(\text{pack})})\\
+\text{identity law of }\text{pack}:\quad & =r(e)\quad.
+\end{align*}
+
+\end_inset
+
+We have proved the isomorphism and also verified Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:surjectivity-of-pack"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+
+\begin_inset Formula $\square$
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subsection
+Greatest fixpoints and the Church-co-Yoneda identity
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:The-greatest-fixpoints-and-Church-co-Yoneda"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+We have seen that the least fixpoints of functors are expressed via the
+ Church encoding type that involves a universally quantified higher-order
+ function.
+ An analogous encoding (with an existentially quantified type) exists for
+ greatest fixpoints.
+ We will now prove some properties of that encoding.
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+This section follows the logic given in P.
+\begin_inset space ~
+\end_inset
+
+Wadler's paper
+\begin_inset Quotes eld
+\end_inset
+
+Recursive types for free
+\begin_inset Quotes erd
+\end_inset
+
+, except that we
+\emph on
+define
+\emph default
+ existential types by Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:existential-via-universal-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) via the universal quantifier.
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+We work with a fixed covariant functor
+\begin_inset Formula $F$
+\end_inset
+
+ and denote by
+\begin_inset Formula $C$
+\end_inset
+
+ the following Church-encoded type:
+\begin_inset Formula
+\[
+C\triangleq\exists A.\,(A\rightarrow F^{A})\times A\quad.
+\]
+
+\end_inset
+
+We will prove that
+\begin_inset Formula $C$
+\end_inset
+
+ is the greatest fixpoint of the type equation
+\begin_inset Formula $X\cong F^{X}$
+\end_inset
+
+; that is,
+\begin_inset Formula $C=\nu X.\,F^{X}$
+\end_inset
+
+.
+
+\end_layout
+
+\begin_layout Standard
+First, we define some auxiliary functions that work with the type
+\begin_inset Formula $C$
+\end_inset
+
+ and prove their properties.
+\end_layout
+
+\begin_layout Standard
+The function
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfold
+\end_layout
+
+\end_inset
+
+ constructs values of type
+\begin_inset Formula $C$
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align*}
+ & \text{unfold}:\forall T.\,(T\rightarrow F^{T})\times T\rightarrow C\quad,\\
+ & \text{unfold}^{T}(u^{:T\rightarrow F^{T}}\times t^{:T})\triangleq\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R}\rightarrow p^{T}(u\times t)\quad.
+\end{align*}
+
+\end_inset
+
+Note that
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfold
+\end_layout
+
+\end_inset
+
+ is the same as the function
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pack
+\end_layout
+
+\end_inset
+
+ from Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-identity-law-of-pack"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ if we set
+\begin_inset Formula $E=C$
+\end_inset
+
+ and
+\begin_inset Formula $P^{A}\triangleq(A\rightarrow F^{A})\times A$
+\end_inset
+
+ in the definition of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pack
+\end_layout
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+By parametricity, the function
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfold
+\end_layout
+
+\end_inset
+
+ satisfies a relational naturality law: for all types
+\begin_inset Formula $A$
+\end_inset
+
+,
+\begin_inset Formula $B$
+\end_inset
+
+ and all functions
+\begin_inset Formula $f^{:A\rightarrow B}$
+\end_inset
+
+,
+\begin_inset Formula
+\begin{equation}
+\text{if}\quad u\bef f^{\uparrow F}=f\bef v\quad\text{then}\quad\text{unfold}^{A}(u^{:A\rightarrow F^{A}}\times a^{:A})=\text{unfold}^{B}(v^{:B\rightarrow F^{B}}\times f(a))\quad.\label{eq:relational-naturality-law-of-unfold}
+\end{equation}
+
+\end_inset
+
+In category theory, the precondition
+\begin_inset Formula $u\bef f^{\uparrow F}=f\bef v$
+\end_inset
+
+ is known as the
+\begin_inset Quotes eld
+\end_inset
+
+
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebra morphism law
+\begin_inset Quotes erd
+\end_inset
+
+ of
+\begin_inset Formula $f$
+\end_inset
+
+.
+ Let us give some definitions for reference:
+\end_layout
+
+\begin_layout Subsubsection
+Definition
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Definition-F-coalgebra"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Definition-F-coalgebra"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Given a functor
+\begin_inset Formula $F$
+\end_inset
+
+, a type
+\begin_inset Formula $A$
+\end_inset
+
+ together with a function
+\begin_inset Formula $u:A\rightarrow F^{A}$
+\end_inset
+
+ is called an
+\begin_inset Formula $F$
+\end_inset
+
+
+\series bold
+-coalgebra
+\series default
+.
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebra
+\end_layout
+
+\end_inset
+
+ The type
+\begin_inset Formula $A$
+\end_inset
+
+ is called the
+\series bold
+carrier
+\series default
+ of the
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebra, and the function
+\begin_inset Formula $u$
+\end_inset
+
+ is called the
+\series bold
+structure map
+\series default
+ of the
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebra.
+ (Keep in mind that
+\begin_inset Formula $u$
+\end_inset
+
+ is not universally quantified over
+\begin_inset Formula $A$
+\end_inset
+
+; it is a function that only works with a single, specified type
+\begin_inset Formula $A$
+\end_inset
+
+.
+ For a given type
+\begin_inset Formula $A$
+\end_inset
+
+, there could be several different structure maps
+\begin_inset Formula $u$
+\end_inset
+
+,
+\begin_inset Formula $u^{\prime}$
+\end_inset
+
+, and so on; each of them will then define a different
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebra.)
+\end_layout
+
+\begin_layout Standard
+If
+\begin_inset Formula $A$
+\end_inset
+
+ and
+\begin_inset Formula $B$
+\end_inset
+
+ are two
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebras with structure maps
+\begin_inset Formula $u:A\rightarrow F^{A}$
+\end_inset
+
+ and
+\begin_inset Formula $v:B\rightarrow F^{B}$
+\end_inset
+
+ then a function
+\begin_inset Formula $f:A\rightarrow B$
+\end_inset
+
+ is called an
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebra morphism if this law holds:
+\begin_inset Preview
+
+\begin_layout Standard
+\begin_inset Formula
+\[
+\xymatrix{\xyScaleY{2.3pc}\xyScaleX{2.5pc}A\ar[d]\sb(0.4){u}\ar[r]\sp(0.5){f} & B\ar[d]\sp(0.4){v}\\
+F^{A}\ar[r]\sp(0.5){f^{\uparrow F}} & F^{B}
+}
+\]
+
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
+\begin_inset Formula
+\[
+u\bef f^{\uparrow F}=f\bef v\quad.
+\]
+
+\end_inset
+
+This is the
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebra morphism law of
+\begin_inset Formula $f$
+\end_inset
+
+.
+
+\begin_inset Formula $\square$
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+It is also helpful to define a function
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfoldF
+\end_layout
+
+\end_inset
+
+ that constructs values of type
+\begin_inset Formula $F^{C}$
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align*}
+ & \text{unfoldF}:\forall T.\,(T\rightarrow F^{T})\times T\rightarrow F^{C}\quad,\\
+ & \text{unfoldF}^{T}(u^{:T\rightarrow F^{T}}\times t^{:T})\triangleq t\triangleright u\triangleright\big(a^{:T}\rightarrow\text{unfold}^{T}(u\times a)\big)^{\uparrow F}\quad.
+\end{align*}
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+The isomorphism
+\begin_inset Formula $C\cong F^{C}$
+\end_inset
+
+ will be implemented via two functions:
+\begin_inset Formula
+\[
+\text{fix}:F^{C}\rightarrow C\quad,\quad\quad\text{unfix}:C\rightarrow F^{C}\quad,
+\]
+
+\end_inset
+
+which we define via
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfold
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfoldF
+\end_layout
+
+\end_inset
+
+ like this:
+\begin_inset Formula
+\begin{align*}
+ & \text{unfix}:C\rightarrow F^{C}\quad,\quad\quad\text{unfix}\triangleq c^{:C}\rightarrow c^{F^{C}}(\forall A.\,\text{unfoldF}^{A})=c^{:C}\rightarrow c^{F^{C}}(\text{unfoldF})\quad,\\
+ & \text{fix}:F^{C}\rightarrow C\quad,\quad\quad\text{fix}\triangleq p^{:F^{C}}\rightarrow\text{unfold}^{F^{C}}(\text{unfix}^{\uparrow F}\times p)\quad.
+\end{align*}
+
+\end_inset
+
+Because of these functions,
+\begin_inset Formula $C$
+\end_inset
+
+ is at the same time an
+\begin_inset Formula $F$
+\end_inset
+
+-algebra and an
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebra.
+\end_layout
+
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-coalgebra-morphism-unfold"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-coalgebra-morphism-unfold"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+For any
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebra
+\begin_inset Formula $A$
+\end_inset
+
+ with a structure map
+\begin_inset Formula $u:A\rightarrow F^{A}$
+\end_inset
+
+, denote by
+\begin_inset Formula $\psi_{u}^{A}$
+\end_inset
+
+ the following function of type
+\begin_inset Formula $A\rightarrow C$
+\end_inset
+
+:
+\begin_inset Formula
+\[
+\psi_{u}^{A}:A\rightarrow C\quad,\quad\quad\psi_{u}^{A}\triangleq a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\quad.
+\]
+
+\end_inset
+
+Then
+\begin_inset Formula $\psi_{u}^{A}$
+\end_inset
+
+ is an
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebra morphism of type
+\begin_inset Formula $A\rightarrow C$
+\end_inset
+
+.
+
+\end_layout
+
+\begin_layout Subparagraph
+Proof
+\end_layout
+
+\begin_layout Standard
+Write the
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebra morphism law for that function:
+\begin_inset Formula
+\[
+u\bef\big(a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\big)^{\uparrow F}\overset{?}{=}\big(a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\big)\bef v\quad.
+\]
+
+\end_inset
+
+Apply both sides to an arbitrary value
+\begin_inset Formula $t^{:A}$
\end_inset
and obtain:
\begin_inset Formula
\[
-(A\rightarrow F^{B})\rightarrow F^{C}\cong(\forall X.\,R^{X}\rightarrow F^{X})\rightarrow F^{C}\cong(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\quad.
+t\triangleright u\triangleright(a\rightarrow\text{unfold}^{A}(u\times a))^{\uparrow F}\overset{?}{=}\text{unfix}\,(\text{unfold}^{A}(u\times t))\quad.
\]
\end_inset
-So, the left-hand side of Eq.
+Begin with the right-hand side:
+\begin_inset Formula
+\begin{align*}
+ & \text{unfix}\,(\text{unfold}^{A}(u\times t))\\
+\text{definition of }\text{unfix}:\quad & =(\text{unfold}^{A}(u\times t))^{F^{C}}(\text{unfoldF})\\
+\text{definition of }\text{unfold}:\quad & =\text{unfoldF}^{A}(u\times t)\\
+\text{definition of }\text{unfoldF}:\quad & =t\triangleright u\triangleright\big(a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\big)^{\uparrow F}\quad.
+\end{align*}
+
+\end_inset
+
+This is now equal to the left-hand side.
+
+\begin_inset Formula $\square$
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-identity-law-of-unfold"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-identity-law-of-unfold"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+The function
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfold
+\end_layout
+
+\end_inset
+
+ satisfies an
+\series bold
+identity law
+\series default
+:
+\begin_inset Formula
+\[
+\text{for all }c^{:C}:\quad\text{unfold}^{C}(\text{unfix}\times c)\overset{?}{=}c\quad.
+\]
+
+\end_inset
+
+This law
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+identity laws!of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfold
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+ is similar to the identity law of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pack
+\end_layout
+
+\end_inset
+
+ (Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-identity-law-of-pack"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+\end_layout
+
+\begin_layout Subparagraph
+Proof
+\end_layout
+
+\begin_layout Standard
+Apply Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-identity-law-of-pack"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+, which gives
+\begin_inset Formula $e^{E}(\text{pack})=e$
+\end_inset
+
+, and substitute
+\begin_inset Formula $E=C$
+\end_inset
+
+,
+\begin_inset Formula $e=c$
+\end_inset
+
+,
+\begin_inset Formula $P^{A}=(A\rightarrow F^{A})\times A$
+\end_inset
+
+, and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfold
+\end_layout
+
+\end_inset
+
+ instead of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pack
+\end_layout
+
+\end_inset
+
+.
+ We obtain:
+\begin_inset Formula
+\begin{equation}
+c=c^{C}(\text{unfold})\quad.\label{eq:unfold-id-law-derivation1}
+\end{equation}
+
+\end_inset
+
+Now use the law
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:surjectivity-of-pack"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) where we substitute
+\begin_inset Formula $E=R=C$
+\end_inset
+
+ and
+\begin_inset Formula $e=c$
+\end_inset
+
+:
+\begin_inset Formula
+\[
+\text{for all }r^{:C\rightarrow C}:\quad r(c)=c^{C}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times a^{:A}\rightarrow r(\text{unfold}^{A}(u\times a))\big)\quad.
+\]
+
+\end_inset
+
+We will use this law with the function
+\begin_inset Formula $r$
+\end_inset
+
+ defined by:
+\begin_inset Formula
+\[
+r:C\rightarrow C\quad,\quad\quad r(c)\triangleq\text{unfold}^{C}(\text{unfix}\times c)\quad.
+\]
+
+\end_inset
+
+Then we get:
+\begin_inset Formula
+\begin{align}
+ & \text{unfold}^{C}(\text{unfix}\times c)=r(c)=c^{C}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times a^{:A}\rightarrow r(\text{unfold}^{A}(u\times a))\big)\nonumber \\
+ & =c^{C}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times a^{:A}\rightarrow\text{unfold}^{C}(\text{unfix}\times\text{unfold}^{A}(u\times a)))\big)\quad.\label{eq:unfold-id-law-derivation3}
+\end{align}
+
+\end_inset
+
+Now we apply the naturality law
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:relational-naturality-law-of-unfold"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) with
+\begin_inset Formula $B=C$
+\end_inset
+
+,
+\begin_inset Formula $f=a\rightarrow\text{unfold}^{A}(u\times a)$
+\end_inset
+
+, and
+\begin_inset Formula $v=\text{unfix}$
+\end_inset
+
+:
+\begin_inset Formula
+\begin{equation}
+\text{unfold}^{A}(u\times a)=\text{unfold}^{C}(\text{unfix}\times\text{unfold}^{A}(u\times a)))\quad.\label{eq:unfold-id-law-derivation2}
+\end{equation}
+
+\end_inset
+
+The precondition of this law (
+\begin_inset Formula $u\bef f^{\uparrow F}\overset{?}{=}f\bef v$
+\end_inset
+
+) is the
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebra morphism law of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfold
+\end_layout
+
+\end_inset
+
+, and it has been demonstrated in Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-coalgebra-morphism-unfold"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+ So, Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:unfold-id-law-derivation2"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) holds.
+
+\end_layout
+
+\begin_layout Standard
+Finally, we can finish the proof:
+\begin_inset Formula
+\begin{align*}
+\text{expect to equal }c:\quad & \text{unfold}^{C}(\text{unfix}\times c)\\
+\text{use Eq.~(\ref{eq:unfold-id-law-derivation3})}:\quad & =c^{C}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times a^{:A}\rightarrow\gunderline{\text{unfold}^{C}(\text{unfix}\times\text{unfold}^{A}(u\times a)))}\big)\\
+\text{use Eq.~(\ref{eq:unfold-id-law-derivation2})}:\quad & =c^{C}\big(\gunderline{\forall A.\,u^{:A\rightarrow F^{A}}\times a^{:A}\rightarrow\text{unfold}^{A}(u\times a)}\big)=c^{C}(\text{unfold})\\
+\text{use Eq.~(\ref{eq:unfold-id-law-derivation1})}:\quad & =c\quad.
+\end{align*}
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-greatest-fixpoint-church-encoding"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-greatest-fixpoint-church-encoding"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+The functions
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+fix
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfix
+\end_layout
+
+\end_inset
+
+ are inverses to each other.
+\end_layout
+
+\begin_layout Subparagraph
+Proof
+\end_layout
+
+\begin_layout Standard
+Translate the existential quantifier via Eq.
\begin_inset space ~
\end_inset
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:jaskelioff-o-connor-theorem"
-plural "false"
-caps "false"
-noprefix "false"
-
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:existential-via-universal-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) and write
+\begin_inset Formula $C$
+\end_inset
+
+ as:
+\begin_inset Formula
+\[
+C\triangleq\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R)\rightarrow R\quad.
+\]
+
+\end_inset
+
+We need to verify that:
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(1)
+\series default
+ For any
+\begin_inset Formula $c:C$
+\end_inset
+
+ we have
+\begin_inset Formula $\text{fix}\,(\text{unfix}\,(c))=c$
\end_inset
-) is equivalent to:
-\begin_inset Formula
-\[
-\forall(F\in P\text{-typeclass}).\,(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\quad.
-\]
+.
+\end_layout
+
+\begin_layout Standard
+\series bold
+(2)
+\series default
+ For any
+\begin_inset Formula $q:F^{C}$
\end_inset
+ we have
+\begin_inset Formula $\text{unfix}\,(\text{fix}\,(q))=q$
+\end_inset
+.
\end_layout
\begin_layout Standard
-
+To prove item
\series bold
-(3)
+(1)
\series default
- We use the covariant Yoneda identity in the category of functors that belong
- to the
-\begin_inset Formula $P$
+:
+\begin_inset Formula
+\begin{align*}
+\text{expect to equal }c:\quad & \gunderline{\text{fix}}\,(\text{unfix}\,(c))\\
+\text{definition of }\text{fix}:\quad & =\text{unfold}^{F^{C}}(\text{unfix}^{\uparrow F}\times\text{unfix}\,(c))\\
+\text{naturality law of }\text{unfold}:\quad & =\text{unfold}^{C}(\text{unfix}\times c)\\
+\text{identity law of }\text{unfold}:\quad & =c\quad.
+\end{align*}
+
\end_inset
--typeclass.
- As we have found in Section
+Here we applied the naturality law
\begin_inset space ~
\end_inset
-
+(
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Imposing-laws-of-P-typeclasses-via-monad-algebras"
+reference "eq:relational-naturality-law-of-unfold"
plural "false"
caps "false"
noprefix "false"
\end_inset
-, all those functors are
-\begin_inset Formula $E$
+) with
+\begin_inset Formula $A=C$
\end_inset
--monad algebras, which form a category.
- The
-\begin_inset Formula $P$
+,
+\begin_inset Formula $B=F^{C}$
\end_inset
--typeclass morphisms are in one-to-one correspondence with the
-\begin_inset Formula $E$
+,
+\begin_inset Formula $a=c$
\end_inset
--monad algebra morphisms.
- Therefore, we may write the covariant Yoneda identity for that category
- as:
+,
+\begin_inset Formula $f=\text{unfix}$
+\end_inset
+
+,
+\begin_inset Formula $u=\text{unfix}$
+\end_inset
+
+, and
+\begin_inset Formula $v=\text{unfix}^{\uparrow F}$
+\end_inset
+
+.
+ To verify the precondition of that law, write:
\begin_inset Formula
\[
-\forall(F\in P\text{-typeclass}).\,(\forall X.\,Q^{X}\overset{P}{\rightarrow}F^{X})\rightarrow S^{F}\cong S^{Q}\quad,
+u\bef f^{\uparrow F}\overset{?}{=}f\bef v\quad,\quad\text{or equivalently:}\quad\text{unfix}\bef\text{unfix}^{\uparrow F}\overset{?}{=}\text{unfix}\bef\text{unfix}^{\uparrow F}\quad.
\]
\end_inset
-where
-\begin_inset Formula $Q$
-\end_inset
+This holds trivially.
+\end_layout
- is any fixed functor from the
-\begin_inset Formula $P$
-\end_inset
+\begin_layout Standard
+To prove item
+\series bold
+(2)
+\series default
+, write:
+\begin_inset Formula
+\begin{align*}
+\text{expect to equal }q:\quad & \text{unfix}\,(\gunderline{\text{fix}\,(q)})\\
+\text{definition of }\text{fix}:\quad & =\gunderline{\text{unfix}}\,\big(\text{unfold}^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\big)\\
+\text{definition of }\text{unfold}:\quad & =\text{unfix}\,\big(\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R}\rightarrow p^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\big)\\
+\text{definition of }\text{unfix}:\quad & =\big(\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R}\rightarrow p^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\big)^{F^{C}}(\text{unfoldF})\\
+\text{apply function}:\quad & =\text{unfoldF}^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\\
+\text{definition of }\text{unfoldF}:\quad & =q\triangleright\gunderline{\text{unfix}^{\uparrow F}\bef\big(a^{:F^{C}}\rightarrow\text{unfold}\,(\text{unfix}^{\uparrow F}\times a)\big)^{\uparrow F}}\\
+\text{composition under }^{\uparrow F}:\quad & =q\triangleright\big(x^{:C}\rightarrow\gunderline{\text{unfold}\,(\text{unfix}^{\uparrow F}\times\text{unfix}\,(x))}\big)^{\uparrow F}\\
+\text{definition of }\text{fix}:\quad & =q\triangleright\big(x^{:C}\rightarrow\gunderline{\text{fix}\,(\text{unfix}\,(x))}\big)^{\uparrow F}\\
+\text{item \textbf{(1)}}:\quad & =q\triangleright\gunderline{(x^{:C}\rightarrow x)^{\uparrow F}}=x\triangleright\text{id}=q\quad.
+\end{align*}
--typeclass,
-\begin_inset Formula $S^{F}$
\end_inset
- is any type expression that is covariant in
-\begin_inset Formula $F$
-\end_inset
-, and the naturality law with respect to
-\begin_inset Formula $F$
+\begin_inset Formula $\square$
\end_inset
- is assumed to hold.
- We will use this Yoneda identity with
-\begin_inset Formula $Q=E^{R}$
-\end_inset
-, and set
-\begin_inset Formula $S^{F}$
-\end_inset
+\end_layout
- to just
-\begin_inset Formula $F^{C}$
+\begin_layout Standard
+It follows that
+\begin_inset Formula $C$
\end_inset
- (the application of
-\begin_inset Formula $F$
+ is a fixpoint of the type equation
+\begin_inset Formula $C\cong F^{C}$
\end_inset
- to the fixed type
+.
+ To show that
\begin_inset Formula $C$
\end_inset
-).
- Then we get:
-\begin_inset Formula
-\[
-\forall(F\in P\text{-typeclass}).\,(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\cong(E^{R})^{C}\quad.
-\]
+ is indeed the
+\emph on
+greatest
+\emph default
+ fixpoint, we need to prove that for any other fixpoint
+\begin_inset Formula $T$
+\end_inset
+ there exists a unique fixpoint-preserving morphism
+\begin_inset Formula $\psi^{T}:T\rightarrow C$
\end_inset
-The last type is the right-hand side of Eq.
+.
+ Similarly to what we saw in Statement
\begin_inset space ~
\end_inset
-(
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:jaskelioff-o-connor-theorem"
+reference "subsec:Statement-fixpoint-preserving-fix"
plural "false"
caps "false"
noprefix "false"
\end_inset
-).
- So, Eq.
-\begin_inset space ~
+, it is sufficient to check that
+\begin_inset Formula $\psi^{T}$
\end_inset
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:jaskelioff-o-connor-theorem"
-plural "false"
-caps "false"
-noprefix "false"
-
+ is an
+\begin_inset Formula $F$
\end_inset
-) holds.
+-coalgebra morphism.
\end_layout
-\begin_layout Standard
-Let us now derive the code that implements the type equivalence
-\begin_inset space ~
-\end_inset
-
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:jaskelioff-o-connor-theorem"
-plural "false"
-caps "false"
-noprefix "false"
-
-\end_inset
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-greatest-fixpoint-Church-encoding-morphism"
-) in the direction of right-to-left.
- Suppose we are given a value
-\begin_inset Formula $q$
\end_inset
- of the type in the right-hand side of Eq.
-\begin_inset space ~
-\end_inset
-(
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:jaskelioff-o-connor-theorem"
+reference "subsec:Statement-greatest-fixpoint-Church-encoding-morphism"
plural "false"
caps "false"
noprefix "false"
\end_inset
-):
-\begin_inset Formula
-\[
-q:(E^{R})^{C}\quad.
-\]
-\end_inset
+\end_layout
-We need to retrace step
-\series bold
-(3)
-\series default
- above and convert this
-\begin_inset Formula $q$
+\begin_layout Standard
+For any
+\begin_inset Formula $F$
\end_inset
- to a function
-\begin_inset Formula $f$
+-coalgebra
+\begin_inset Formula $A$
\end_inset
- of type:
-\begin_inset Formula
-\[
-f:\forall(F\in P\text{-typeclass}).\,(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\quad.
-\]
-
+ with a structure map
+\begin_inset Formula $u:A\rightarrow F^{A}$
\end_inset
-The required function
-\begin_inset Formula $f$
+, there exists a unique
+\begin_inset Formula $F$
\end_inset
- is defined by:
-\begin_inset Formula
-\[
-f^{F}\big(k^{:\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X}}\big)\triangleq k^{C}(q)\quad.
-\]
-
+-algebra morphism
+\begin_inset Formula $\psi_{u}^{A}$
\end_inset
+ of type
+\begin_inset Formula $A\rightarrow C$
+\end_inset
-\end_layout
+.
+ The function
+\begin_inset Formula $\psi_{u}^{A}$
+\end_inset
-\begin_layout Standard
-Continue by retracing step
+ is known as an
\series bold
-(2)
+anamorphism
\series default
-, converting
-\begin_inset Formula $f$
-\end_inset
- to a function
-\begin_inset Formula $g$
-\end_inset
+\begin_inset Index idx
+status open
- of type:
-\begin_inset Formula
-\[
-g:\forall(F\in P\text{-typeclass}).\,(\forall X.\,R^{X}\rightarrow F^{X})\rightarrow F^{C}\quad.
-\]
+\begin_layout Plain Layout
+anamorphism
+\end_layout
\end_inset
-The function
-\begin_inset Formula $g$
+ and was defined as in Statement
+\begin_inset space ~
\end_inset
- is defined by:
-\begin_inset Formula
-\[
-g^{F}\big(k^{:\forall X.\,R^{X}\rightarrow F^{X}}\big)\triangleq f^{F}\big(\forall Y.\,r^{:(E^{R})^{Y}}\rightarrow\text{run}_{E}^{R,Y}(k)(r)\big)\quad,
-\]
-\end_inset
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-coalgebra-morphism-unfold"
+plural "false"
+caps "false"
+noprefix "false"
-where the universal runner (
-\begin_inset Formula $\text{run}_{E}^{T,Y}$
\end_inset
-) has type:
+:
\begin_inset Formula
\[
-\text{run}_{E}^{T,Y}:(\forall X.\,T^{X}\rightarrow F^{X})\rightarrow(E^{T})^{Y}\rightarrow F^{Y}\quad.
+\psi_{u}^{A}:A\rightarrow C\quad,\quad\quad\psi_{u}^{A}\triangleq a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\quad.
\]
\end_inset
@@ -45240,201 +48581,210 @@ where the universal runner (
\end_layout
+\begin_layout Subparagraph
+Proof
+\end_layout
+
\begin_layout Standard
-It remains to retrace step
-\series bold
-(1)
-\series default
- and define a function
-\begin_inset Formula $h$
+We know from Statement
+\begin_inset space ~
\end_inset
- of type:
-\begin_inset Formula
-\[
-h:\forall(F\in P\text{-typeclass}).\,(A\rightarrow F^{B})\rightarrow F^{C}\quad.
-\]
-\end_inset
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-coalgebra-morphism-unfold"
+plural "false"
+caps "false"
+noprefix "false"
-We implement
-\begin_inset Formula $h$
\end_inset
- via this code:
-\begin_inset Formula
-\[
-h^{F}(k^{:A\rightarrow F^{B}})\triangleq g^{F}\big(\forall X.\,a^{:A}\times t^{:B\rightarrow X}\rightarrow k(a)\triangleright t^{\uparrow F}\big)\quad.
-\]
-
+ that
+\begin_inset Formula $\psi_{u}^{A}$
\end_inset
-This completes the code that transforms
-\begin_inset Formula $q$
+ satisfies the law of
+\begin_inset Formula $F$
\end_inset
- into
-\begin_inset Formula $h$
+-coalgebra morphisms.
+ Let
+\begin_inset Formula $f:A\rightarrow C$
\end_inset
-.
-
-\begin_inset Formula $\square$
+ be any other
+\begin_inset Formula $F$
\end_inset
+-coalgebra morphism; we need to prove that
+\begin_inset Formula $f=\psi_{u}^{A}$
+\end_inset
+.
\end_layout
\begin_layout Standard
-We will now apply the Jaskelioff-O'Connor theorem to prove some useful type
- equivalences.
-\end_layout
+We know that
+\begin_inset Formula $f$
+\end_inset
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-identity-monad-morphism"
+ satisfies the
+\begin_inset Formula $F$
+\end_inset
+
+-coalgebra morphism law:
+\begin_inset Formula
+\[
+u\bef f^{\uparrow F}=f\bef\text{unfix}\quad.
+\]
\end_inset
+This is the precondition of the relational naturality law
+\begin_inset space ~
+\end_inset
+(
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-identity-monad-morphism"
+reference "eq:relational-naturality-law-of-unfold"
plural "false"
caps "false"
noprefix "false"
\end_inset
+) of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+unfold
\end_layout
-\begin_layout Standard
-Denote by
-\begin_inset Formula $F\xrightarrow{\text{Monad}}G$
-\end_inset
-
- (more verbosely,
-\begin_inset Formula $\forall X.\,F^{X}\xrightarrow{\text{Monad}}G^{X}$
\end_inset
-) the type of monad morphisms between monads
-\begin_inset Formula $F$
+ if we set
+\begin_inset Formula $B=C$
\end_inset
and
-\begin_inset Formula $G$
+\begin_inset Formula $v=\text{unfix}$
\end_inset
.
- Those are natural transformations of type
-\begin_inset Formula $\forall X.\,F^{X}\rightarrow G^{X}$
+ So, the conclusion of that law holds.
+ We use that equation as well as Statement
+\begin_inset space ~
\end_inset
- that additionally satisfy the laws of monad morphisms.
- Denote by
-\begin_inset Formula $\text{Id}$
-\end_inset
- the identity monad (
-\begin_inset Formula $\text{Id}^{A}\triangleq A$
-\end_inset
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-identity-law-of-unfold"
+plural "false"
+caps "false"
+noprefix "false"
-).
-
-\end_layout
+\end_inset
-\begin_layout Standard
+ and get:
+\begin_inset Formula
+\begin{align*}
+\text{for any }a^{:A}:\quad & \psi_{u}^{A}(a)=\text{unfold}^{A}(u^{:A\rightarrow F^{A}}\times a^{:A})\\
+\text{naturality law of }\text{unfold}:\quad & =\text{unfold}^{C}(\text{unfix}\times f(a))\\
+\text{identity law of }\text{unfold}:\quad & =f(a)\quad.
+\end{align*}
-\series bold
-(a)
-\series default
- The standard monad method
-\begin_inset Formula $\text{pu}_{M}:\forall A.\,A\rightarrow M^{A}$
\end_inset
- is the only monad morphism of type
-\begin_inset Formula $\text{Id}\xrightarrow{\text{Monad}}M$
+It follows that
+\begin_inset Formula $\psi_{u}^{A}=f$
\end_inset
- that works in the same way for all monads
-\begin_inset Formula $M$
+.
+
+\begin_inset Formula $\square$
\end_inset
-.
-\begin_inset Foot
+
+\end_layout
+
+\begin_layout Standard
+We conclude this Appendix with the proof of a type identity dual to the
+ Church-Yoneda identity
+\begin_inset Index idx
status open
\begin_layout Plain Layout
-See
-\family typewriter
+Church-co-Yoneda identity
+\end_layout
-\begin_inset CommandInset href
-LatexCommand href
-target "https://cstheory.stackexchange.com/questions/53389/"
-literal "false"
+\end_inset
+ shown in Statement
+\begin_inset space ~
\end_inset
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-Church-Yoneda-identity"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
- We can express this as a type equivalence:
-\begin_inset Formula
-\[
-\forall M^{:\text{Monad}}.\,\text{Id}\xrightarrow{\text{Monad}}M\cong\bbnum 1\quad.
-\]
-
+.
+ That identity has no accepted name, and this book calls it the
+\begin_inset Quotes eld
\end_inset
+Church-co-Yoneda
+\begin_inset Quotes erd
+\end_inset
+ identity.
\end_layout
-\begin_layout Standard
-
-\series bold
-(b)
-\series default
- The identity function of type
-\begin_inset Formula $\forall X.\,M^{X}\rightarrow M^{X}$
-\end_inset
-
- is the only monad morphism of type
-\begin_inset Formula $M\xrightarrow{\text{Monad}}M$
-\end_inset
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-Church-co-Yoneda"
- that works in the same way for all monads
-\begin_inset Formula $M$
\end_inset
-.
-\begin_inset Foot
-status open
-
-\begin_layout Plain Layout
-See
-\family typewriter
-\begin_inset CommandInset href
-LatexCommand href
-target "https://stackoverflow.com/questions/61444425/"
-literal "false"
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-Church-co-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
\end_layout
+\begin_layout Standard
+For any covariant functors
+\begin_inset Formula $F$
\end_inset
- We can express this as a type equivalence:
+ and
+\begin_inset Formula $G$
+\end_inset
+
+:
\begin_inset Formula
\[
-\forall M^{:\text{Monad}}.\,M\xrightarrow{\text{Monad}}M\cong\bbnum 1\quad.
+G^{\nu X.\,F^{X}}\cong\exists A.\,(A\rightarrow F^{A})\times G^{A}\quad.
\]
\end_inset
@@ -45447,127 +48797,103 @@ Proof
\end_layout
\begin_layout Standard
-The
+Denote for brevity
+\begin_inset Formula $C\triangleq\nu X.\,F^{X}$
+\end_inset
+
+.
+ The existential type is rewritten as:
+\begin_inset Formula
+\[
+\exists A.\,(A\rightarrow F^{A})\times G^{A}=\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R\quad.
+\]
+
+\end_inset
+
+We will demonstrate the isomorphism if we define functions
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-Monad
+toG
\end_layout
\end_inset
- typeclass has methods in the form of a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass for functors
-\begin_inset Formula $K$
-\end_inset
-
- if we define
-\begin_inset Formula $P$
-\end_inset
-
- by
-\begin_inset Formula $(P^{K})^{A}\triangleq A+K^{K^{A}}$
-\end_inset
-
-.
- Then the methods of the
+ and
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-Monad
+fromG
\end_layout
\end_inset
- typeclass are represented by a single value of type:
+ that are mutual inverses, with type signatures:
\begin_inset Formula
\[
-\forall A.\,(P^{K})^{A}\rightarrow K^{A}=\forall A.\,A+K^{K^{A}}\rightarrow K^{A}\cong(\forall A.\,A\rightarrow K^{A})\times(\forall A.\,K^{K^{A}}\rightarrow K^{A})\quad.
+\text{toG}:(\exists A.\,(A\rightarrow F^{A})\times G^{A})\rightarrow G^{C}\quad,\quad\quad\text{fromG}:G^{C}\rightarrow\exists A.\,(A\rightarrow F^{A})\times G^{A}\quad.
\]
\end_inset
-This is a tuple type describing the type signatures of
-\begin_inset Formula $K$
-\end_inset
-
-'s
-\begin_inset listings
-inline true
-status open
+The first type signature can be implemented as:
+\begin_inset Formula
+\begin{align*}
+ & \text{toG}:\big(\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R\big)\rightarrow G^{C}\quad,\\
+ & \text{toG}\triangleq k^{:\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R}\rightarrow k^{G^{C}}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)\quad,
+\end{align*}
-\begin_layout Plain Layout
+\end_inset
-pure
-\end_layout
+where
+\begin_inset Formula $\psi_{u}^{A}$
+\end_inset
+ is the anamorphism of type
+\begin_inset Formula $A\rightarrow C$
\end_inset
- and
-\begin_inset listings
-inline true
-status open
+ defined in Statement
+\begin_inset space ~
+\end_inset
-\begin_layout Plain Layout
-flatten
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-coalgebra-morphism-unfold"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
- methods when
-\begin_inset Formula $K$
-\end_inset
+.
+\end_layout
- is a monad.
- So, the Jaskelioff-O'Connor theorem applies to the
+\begin_layout Standard
+The function
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-Monad
+fromG
\end_layout
\end_inset
- typeclass.
- The free monad constructor (
-\begin_inset Formula $E$
-\end_inset
-
-) is defined recursively as
-\begin_inset Formula $(E^{F})^{A}\triangleq A+F^{(E^{F})^{A}}$
-\end_inset
-
-, making
-\begin_inset Formula $E^{F}$
-\end_inset
-
- a monad when
-\begin_inset Formula $F$
-\end_inset
-
- is any functor.
- The free monad's universal runner is defined by:
+ is implemented as:
\begin_inset Formula
\begin{align*}
- & \text{run}_{E}^{F,A}:(\forall X.\,F^{X}\rightarrow M^{X})\rightarrow(E^{F})^{A}\rightarrow M^{A}\quad,\\
- & \text{run}_{E}^{F,A}\big(k^{:\forall X.\,F^{X}\rightarrow M^{X}}\big)\triangleq\,\begin{array}{|c||c|}
- & M^{A}\\
-\hline A & \text{pu}_{M}\\
-F^{(E^{F})^{A}} & k^{(E^{F})^{A}}\bef\text{flm}_{M}\big(\overline{\text{run}}_{E}^{F,A}(k)\big)
-\end{array}\quad.
+ & \text{fromG}:G^{C}\rightarrow\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R\quad,\\
+ & \text{fromG}\triangleq g^{:G^{C}}\rightarrow\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R}\rightarrow p^{C}(\text{unfix}\times g)\quad.
\end{align*}
\end_inset
@@ -45575,650 +48901,563 @@ F^{(E^{F})^{A}} & k^{(E^{F})^{A}}\bef\text{flm}_{M}\big(\overline{\text{run}}_{E
\end_layout
+\begin_layout Standard
+It remains to prove the two directions of the isomorphism roundtrip:
+\end_layout
+
\begin_layout Standard
\series bold
-(a)
+(1)
\series default
- Monad morphisms are natural transformations that satisfy additional laws.
- We first consider the given type without restricting the functions of type
-
-\begin_inset Formula $A\rightarrow M^{A}$
+ For any
+\begin_inset Formula $g:G^{C}$
\end_inset
- to monad morphisms but still assuming that they are natural transformations:
-\begin_inset Formula
-\[
-\forall M^{:\text{Monad}}.\,\forall A.\,A\rightarrow M^{A}\quad.
-\]
-
+ we have:
+\begin_inset Formula $\text{toG}\,(\text{fromG}\,(g))=g$
\end_inset
-By the Yoneda identity, we get the type equivalence:
-\begin_inset Formula
-\[
-\forall A.\,A\rightarrow M^{A}\cong M^{\bbnum 1}\quad.
-\]
+.
+\end_layout
-\end_inset
+\begin_layout Standard
-So, we have reduced the type to
-\begin_inset Formula $\forall M^{:\text{Monad}}.\,M^{\bbnum 1}$
+\series bold
+(2)
+\series default
+ For any
+\begin_inset Formula $k:\exists A.\,(A\rightarrow F^{A})\times G^{A}$
\end_inset
-.
- This type will be in the form suitable for the Jaskelioff-O'Connor theorem
-\begin_inset space ~
+ we have:
+\begin_inset Formula $\text{fromG}\,(\text{toG}\,(k))=k$
\end_inset
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:jaskelioff-o-connor-theorem"
-plural "false"
-caps "false"
-noprefix "false"
+.
+\end_layout
-\end_inset
+\begin_layout Standard
+To prove item
+\series bold
+(1)
+\series default
+:
+\begin_inset Formula
+\begin{align*}
+ & \text{toG}\,(\gunderline{\text{fromG}}\,(g))=\gunderline{\text{toG}}\,\big(\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R}\rightarrow p^{C}(\text{unfix}\times g)\big)\\
+ & =\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)^{C}(\text{unfix}\times g)\\
+ & =g\triangleright(\psi_{\text{unfix}}^{C})^{\uparrow F}\quad.
+\end{align*}
-) if we set
-\begin_inset Formula $F=M$
\end_inset
-,
-\begin_inset Formula $A=\bbnum 0$
+We note that
+\begin_inset Formula $\psi_{\text{unfix}}^{C}$
\end_inset
-,
-\begin_inset Formula $C=\bbnum 1$
+ is the identity function (
+\begin_inset Formula $\text{id}^{:C\rightarrow C}$
\end_inset
-; the parameter
-\begin_inset Formula $B$
+) because it is the unique
+\begin_inset Formula $F$
\end_inset
- remains unused since
-\begin_inset Formula $A\rightarrow M^{B}=\bbnum 0\rightarrow M^{B}\cong\bbnum 1$
+-coalgebra morphism of type
+\begin_inset Formula $C\rightarrow C$
\end_inset
-.
- Then Eq.
+ by Statement
\begin_inset space ~
\end_inset
-(
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:jaskelioff-o-connor-theorem"
+reference "subsec:Statement-greatest-fixpoint-Church-encoding-morphism"
plural "false"
caps "false"
noprefix "false"
\end_inset
-) gives:
+.
+ It follows that:
\begin_inset Formula
\[
-\forall M^{:\text{Monad}}.\,M^{\bbnum 1}\cong\forall M^{:\text{Monad}}.\,(\bbnum 0\rightarrow M^{B})\rightarrow M^{\bbnum 1}\cong(E^{R})^{\bbnum 1}\quad,
+\text{toG}\,(\text{fromG}\,(g))=g\triangleright(\psi_{\text{unfix}}^{C})^{\uparrow F}=g\triangleright\text{id}^{\uparrow F}=g\quad.
\]
\end_inset
-where we must define
-\begin_inset Formula $R^{X}=A\times(B\rightarrow X)$
-\end_inset
-.
- However, setting
-\begin_inset Formula $A=\bbnum 0$
-\end_inset
+\end_layout
- gives also
-\begin_inset Formula $R=\bbnum 0$
+\begin_layout Standard
+To prove item
+\series bold
+(2)
+\series default
+, apply both sides to a type
+\begin_inset Formula $R$
\end_inset
-.
- Then the free monad
-\begin_inset Formula $E^{R}$
+ and a value
+\begin_inset Formula $p^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R}$
\end_inset
- is the identity functor:
+:
\begin_inset Formula
-\[
-(E^{R})^{C}=C+R^{(E^{R})^{C}}=C+\bbnum 0\cong C\quad.
-\]
+\begin{align*}
+\text{expect to equal }k^{R}(p):\quad & \big(\text{fromG}\,(\text{toG}\,(k))\big)^{R}(p)=p^{C}(\text{unfix}\times\text{toG}\,(k))\\
+ & =p^{C}\big(\text{unfix}\times k^{G^{C}}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)\big)\quad.
+\end{align*}
\end_inset
-Finally, we obtain
-\begin_inset Formula $(E^{R})^{\bbnum 1}=\bbnum 1$
+To proceed, we need to use the naturality law of
+\begin_inset Formula $k$
\end_inset
-, and so:
+:
\begin_inset Formula
\[
-\forall M^{:\text{Monad}}.\,\forall A.\,A\rightarrow M^{A}\cong\bbnum 1\quad.
+\text{for all }Q,R,f^{:Q\rightarrow R},q^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow Q}:\quad k^{R}(\forall A.\:q^{A}\bef f)=f(k^{Q}(q))\quad.
\]
\end_inset
+Setting the following parameters in this law:
+\begin_inset Formula
+\[
+Q=G^{C}\quad,\quad\quad f=t^{:G^{C}}\rightarrow p^{C}(\text{unfix}\times t)\quad,\quad q=\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\quad,
+\]
-\end_layout
-
-\begin_layout Standard
-We conclude that
-\emph on
-without
-\emph default
- restricting to monad morphisms there is only a single function of the given
- type.
- It remains to derive the code for that function and to verify that it is
- indeed a monad morphism.
-\end_layout
-
-\begin_layout Standard
-We begin with a unit value (that we denote by
-\begin_inset Formula $1$
\end_inset
-) viewed as a value of type
-\begin_inset Formula $(E^{R})^{C}$
+we obtain:
+\begin_inset Formula
+\begin{align*}
+ & k^{R}(\forall A.\:u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F}))\\
+ & =p^{C}\big(\text{unfix}\times k^{G^{C}}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)\big)\quad.
+\end{align*}
+
\end_inset
- in the right-hand side of Eq.
-\begin_inset space ~
+We expect the left-hand side to equal
+\begin_inset Formula $k^{R}(p)$
\end_inset
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:jaskelioff-o-connor-theorem"
-plural "false"
-caps "false"
-noprefix "false"
+, so the remaining difference is:
+\begin_inset Formula
+\begin{align*}
+ & p\overset{?}{=}\forall A.\:u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F})\quad,\\
+\text{or equivalently}:\quad & p^{A}(u^{:A\rightarrow F^{A}}\times g^{:G^{A}})\overset{?}{=}p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F})\quad.
+\end{align*}
\end_inset
-).
- We follow the proof of Statement
-\begin_inset space ~
+This should hold for all types
+\begin_inset Formula $A$
\end_inset
+ and for all
+\begin_inset Formula $g^{:G^{A}}$
+\end_inset
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-Jaskelioff-OConnor"
-plural "false"
-caps "false"
-noprefix "false"
-
+,
+\begin_inset Formula $u^{:A\rightarrow F^{A}}$
\end_inset
-.
- The first step is to convert the value of type
-\begin_inset Formula $(E^{R})^{C}$
+,
+\begin_inset Formula $p:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R$
\end_inset
- into a function
-\begin_inset Formula $f$
+.
+ We may assume that all such
+\begin_inset Formula $p$
\end_inset
- of type:
+ obey their relational naturality law:
\begin_inset Formula
\[
-f:\forall M^{:\text{Monad}}.\,\big(\forall X.\,(E^{R})^{X}\xrightarrow{\text{Monad}}M^{X}\big)\rightarrow M^{C}\quad.
+\forall A,B,f^{:A\rightarrow B}:\quad\text{if}\quad u^{:A\rightarrow F^{A}}\bef f^{\uparrow F}=f\bef v^{:B\rightarrow F^{B}}\quad\text{then}\quad p^{A}(u\times a)=p^{B}(v\times a\triangleright f^{\uparrow F})\quad.
\]
\end_inset
-In our case, this function is simplified to:
+We set the following parameters in this law,
\begin_inset Formula
-\begin{align*}
- & f:\forall M^{:\text{Monad}}.\,\big(\forall X.\,\text{Id}^{X}\xrightarrow{\text{Monad}}M^{X}\big)\rightarrow M^{\bbnum 1}\quad,\\
- & f^{M}\big(k^{:\forall X.\,\text{Id}^{X}\xrightarrow{\text{Monad}}M^{X}}\big)\triangleq k^{\bbnum 1}(1)\quad.
-\end{align*}
-
-\end_inset
-
-The next step is to convert
-\begin_inset Formula $f$
-\end_inset
+\[
+B=C\quad,\quad a=g\quad,\quad f=\psi_{u}^{A}\quad,\quad v=\text{unfix}\quad,
+\]
- to a function
-\begin_inset Formula $g$
\end_inset
- of type:
+and obtain:
\begin_inset Formula
\[
-g:\forall M^{:\text{Monad}}.\,(\forall X.\,R^{X}\rightarrow M^{X})\rightarrow M^{C}\quad.
+p^{A}(u\times g)=p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F})\quad.
\]
\end_inset
-In our case,
-\begin_inset Formula $R^{X}=\bbnum 0$
-\end_inset
-
- and
-\begin_inset Formula $R^{X}\rightarrow M^{X}\cong\bbnum 1$
-\end_inset
-
-, so this function is simplified to:
+This will complete the proof of item
+\series bold
+(2)
+\series default
+ as long as the precondition holds:
\begin_inset Formula
\begin{align*}
- & g:\forall M^{:\text{Monad}}.\,\bbnum 1\rightarrow M^{\bbnum 1}\quad,\\
- & g^{M}(k^{:\bbnum 1})\triangleq f^{M}\big(\forall Y.\,r^{:(E^{R})^{Y}}\rightarrow\text{run}_{E}^{R,Y}(k)(r)\big)\\
- & \quad=f^{M}(\forall Y.\,r^{:Y}\rightarrow\text{pu}_{M}^{Y}(r))=\text{pu}_{M}^{\bbnum 1}(1)\quad.
+ & u^{:A\rightarrow F^{A}}\bef f^{\uparrow F}\overset{?}{=}f\bef v^{:B\rightarrow F^{B}}\quad,\\
+\text{or equivalently}:\quad & u\bef(\psi_{u}^{A})^{\uparrow F}\overset{?}{=}\psi_{u}^{A}\bef\text{unfix}\quad.
\end{align*}
\end_inset
-Finally, we convert
-\begin_inset Formula $g$
+This holds by Statement
+\begin_inset space ~
\end_inset
- to a function
-\begin_inset Formula $h$
-\end_inset
- of type:
-\begin_inset Formula
-\begin{align*}
- & h:\forall M^{:\text{Monad}}.\,(A\rightarrow M^{B})\rightarrow M^{C}\\
- & =\forall M^{:\text{Monad}}.\,(\bbnum 0\rightarrow M^{B})\rightarrow M^{\bbnum 1}\quad.\\
- & \cong\forall M^{:\text{Monad}}.\,\bbnum 1\rightarrow M^{\bbnum 1}\cong\forall M^{:\text{Monad}}.\,M^{\bbnum 1}\quad.
-\end{align*}
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-coalgebra-morphism-unfold"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
- There exists only one value of type
-\begin_inset Formula $\forall M^{:\text{Monad}}.\,M^{\bbnum 1}$
+: it is the
+\begin_inset Formula $F$
\end_inset
-, and that value is
-\begin_inset Formula $\text{pu}_{M}(1)$
+-coalgebra morphism law of
+\begin_inset Formula $\psi_{u}^{A}$
\end_inset
.
- Converting that to the type signature
-\begin_inset Formula $\forall A.\:A\rightarrow M^{A}$
-\end_inset
-
-, we recover just the standard monad method
-\begin_inset Formula $\text{pu}_{M}$
+
+\begin_inset Formula $\square$
\end_inset
-.
- We know that
-\begin_inset Formula $\text{pu}_{M}$
-\end_inset
- gives a monad morphism between the identity monad and
-\begin_inset Formula $M$
-\end_inset
+\end_layout
- (see Statement
+\begin_layout Standard
+The Church-co-Yoneda identity can be used to prove the Church encoding formula
+ for simultaneous greatest fixpoints of several functors, similarly to what
+ we did in Section
\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-pure-M-is-monad-morphism"
+reference "subsec:Least-fixpoints-of-mutually-recursive-types"
plural "false"
caps "false"
noprefix "false"
\end_inset
-).
- So, we have proved that there exists a unique monad morphism of type
-\begin_inset Formula $\forall M^{:\text{Monad}}.\,\text{Id}\xrightarrow{\text{Monad}}M$
-\end_inset
-
.
+ For simplicity, we will now show a proof for just two mutually recursive
+ types; the proof can be extended to any number of types.
\end_layout
\begin_layout Standard
+We will first prove a property of nested fixpoints.
+\end_layout
-\series bold
-(b)
-\series default
- Again, we first consider the given type without restricting the functions
- of type
-\begin_inset Formula $M^{X}\rightarrow M^{X}$
-\end_inset
-
- to monad morphisms (but still assuming that they are natural transformations):
-\begin_inset Formula
-\[
-\forall M^{:\text{Monad}}.\,\forall X.\,M^{X}\rightarrow M^{X}\quad.
-\]
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-nested-greatest-fixpoints"
\end_inset
-This type will be in the form suitable for the Jaskelioff-O'Connor theorem
-\begin_inset space ~
-\end_inset
-(
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:jaskelioff-o-connor-theorem"
+reference "subsec:Statement-nested-greatest-fixpoints"
plural "false"
caps "false"
noprefix "false"
\end_inset
-) if we set
-\begin_inset Formula $F=M$
-\end_inset
-
-,
-\begin_inset Formula $A=\bbnum 1$
-\end_inset
-, and
-\begin_inset Formula $B=C=X$
-\end_inset
+\end_layout
-.
- The functor
-\begin_inset Formula $R$
+\begin_layout Standard
+For any bifunctor
+\begin_inset Formula $F$
\end_inset
- is then defined by:
+, the following equivalence holds:
\begin_inset Formula
\[
-R^{T}\triangleq A\times(B\rightarrow T)\cong X\rightarrow T\quad,
+\nu A.\,(\nu B.\,F^{A,B})\cong\nu B.\,F^{B,B}\quad.
\]
\end_inset
-and the functor
-\begin_inset Formula $E^{R}$
-\end_inset
-
- (the free monad on
-\begin_inset Formula $R$
-\end_inset
-
-) is defined recursively by:
-\begin_inset Formula
-\[
-(E^{R})^{T}\triangleq T+\big(X\rightarrow(E^{R})^{T}\big)\quad.
-\]
-
-\end_inset
- With these definitions, Eq.
-\begin_inset space ~
-\end_inset
+\end_layout
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:jaskelioff-o-connor-theorem"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Subparagraph
+Proof
+\end_layout
+\begin_layout Standard
+Denote
+\begin_inset Formula $G^{A,C}\triangleq(A\rightarrow C)\times A$
\end_inset
-) gives:
+ and write the Church encoding for the fixpoints:
\begin_inset Formula
\[
-\forall M^{:\text{Monad}}.\,\forall X.\,M^{X}\rightarrow M^{X}\cong\forall X.\,(E^{R})^{X}\quad.
+\nu A.\,(\nu B.\,F^{A,B})=\exists A.\,(A\rightarrow\nu B.\,F^{A,B})\times A=\exists A.\,G^{A,\,\nu B.\,F^{A,B}}\quad.
\]
\end_inset
-We are using the functor
-\begin_inset Formula $(E^{R})^{T}$
+View
+\begin_inset Formula $A$
\end_inset
- with the type parameter
-\begin_inset Formula $T=X$
+ as fixed and use the Church-co-Yoneda identity (Statement
+\begin_inset space ~
\end_inset
-; however,
-\begin_inset Formula $E^{R}$
-\end_inset
- also contains
-\begin_inset Formula $X$
-\end_inset
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-Church-co-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
- through the definition of
-\begin_inset Formula $R$
\end_inset
-.
- To avoid confusion and to simplify notation, let us write
-\begin_inset Formula $G^{X}$
-\end_inset
+):
+\begin_inset Formula
+\begin{align*}
+ & G^{A,\,\nu B.\,F^{A,B}}\cong\exists B.\,(B\rightarrow F^{A,B})\times\gunderline{G^{A,B}}\\
+ & =\exists B.\,(B\rightarrow F^{A,B})\times(A\rightarrow B)\times A\\
+ & =\exists B.\,(A\rightarrow B)\times H^{A,B}\quad,
+\end{align*}
- instead of
-\begin_inset Formula $(E^{R})^{X}$
\end_inset
-, where the type constructor
-\begin_inset Formula $G$
+where we defined
+\begin_inset Formula $H$
\end_inset
- is defined recursively by:
+ by:
\begin_inset Formula
\[
-G^{X}\triangleq X+(X\rightarrow G^{X})\quad.
+H^{A,B}\triangleq(B\rightarrow F^{A,B})\times A\quad.
\]
\end_inset
-(Note that
-\begin_inset Formula $G$
-\end_inset
-
- is neither covariant nor contravariant.) With this definition, we obtain:
+Now we can simplify the nested fixpoints:
\begin_inset Formula
-\[
-\forall M^{:\text{Monad}}.\,\forall X.\,M^{X}\rightarrow M^{X}\cong\forall X.\,G^{X}\quad.
-\]
+\begin{align*}
+\text{expect }\nu B.\,F^{B,B}:\quad & \nu A.\,(\nu B.\,F^{A,B})=\gunderline{\exists A.\,\exists B.}\,(A\rightarrow B)\times H^{A,B}\\
+\text{co-Fubini theorem (Statement~\ref{subsec:Statement-commute-existential})}:\quad & \cong\exists B.\,\exists A.\,(A\rightarrow B)\times H^{A,B}\\
+\text{co-Yoneda identity}:\quad & \cong\exists B.\,\gunderline{H^{B,B}}=\exists B.\,(B\rightarrow F^{B,B})\times B\\
+\text{Church encoding}:\quad & \cong\nu B.\,F^{B,B}\quad.
+\end{align*}
\end_inset
\end_layout
-\begin_layout Standard
-To simpify the type
-\begin_inset Formula $\forall X.\,G^{X}$
-\end_inset
-
-, begin by expanding the recursive type
-\begin_inset Formula $G^{X}$
-\end_inset
-
-:
-\begin_inset Formula
-\begin{align*}
- & \forall X.\,G^{X}\cong\forall X.\,X+(X\rightarrow G^{X})\\
-\text{non-disjunctivity}:\quad & \cong(\forall X.\,X)+(\forall X.\,X\rightarrow G^{X})\\
-\text{use }\forall X.\,X\cong\bbnum 0:\quad & \cong\forall X.\,X\rightarrow G^{X}\quad.
-\end{align*}
-
-\end_inset
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-mutually-recursive-greatest-fixpoints"
-Here we used the non-disjunctivity property from Example
-\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Example-undisjunctive-type-constructors"
+reference "subsec:Statement-mutually-recursive-greatest-fixpoints"
plural "false"
caps "false"
noprefix "false"
\end_inset
-(e).
+
\end_layout
\begin_layout Standard
-Continue expanding the recursive type:
-\begin_inset Formula
-\begin{align*}
- & \forall X.\,X\rightarrow G^{X}\cong\forall X.\,X\rightarrow(X+(X\rightarrow G^{X}))\\
-\text{non-disjunctivity}:\quad & \cong(\gunderline{\forall X.\,X\rightarrow X})+\big(\forall X.\,X\rightarrow X\rightarrow G^{X}\big)\\
- & \cong\bbnum 1+\forall X.\,X\times X\rightarrow G^{X}\quad.
-\end{align*}
+Given any bifunctors
+\begin_inset Formula $F$
+\end_inset
+,
+\begin_inset Formula $G$
\end_inset
-The relevant non-disjunctivity property was shown in Example
-\begin_inset space ~
+, define
+\begin_inset Formula $T$
\end_inset
+ and
+\begin_inset Formula $U$
+\end_inset
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Example-undisjunctive-type-constructors"
-plural "false"
-caps "false"
-noprefix "false"
+ as the simultaneous greatest fixpoints of two type equations:
+\begin_inset Formula
+\[
+T=F^{T,U}\quad,\quad\quad U=G^{T,U}\quad.
+\]
\end_inset
-(f).
- Expand further, using the same non-disjunctivity property:
+Then the types
+\begin_inset Formula $T$
+\end_inset
+
+ and
+\begin_inset Formula $U$
+\end_inset
+
+ can be expressed as:
\begin_inset Formula
\begin{align*}
- & \forall X.\,G^{X}\cong\bbnum 1+\forall X.\,X\times X\rightarrow G^{X}\\
- & \cong\bbnum 1+\forall X.\,X\times X\rightarrow(X+(X\rightarrow G^{X}))\\
-\text{non-disjunctivity}:\quad & \cong\bbnum 1+(\gunderline{\forall X.\,X\times X\rightarrow X})+\big(\forall X.\,X\times X\rightarrow X\rightarrow G^{X}\big)\\
- & \cong\bbnum 1+\bbnum 2+\forall X.\,X\times X\times X\rightarrow G^{X}\quad.
+ & T\cong\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times A\quad,\\
+ & U\cong\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times B\quad.
\end{align*}
\end_inset
-Proceeding similarly, we obtain:
-\begin_inset Formula
-\[
-\forall X.\,\underbrace{X\times...\times X}_{n\text{ times}}\rightarrow G^{X}\cong\underbrace{\bbnum 1+...+\bbnum 1}_{n\text{ times}}+\forall X.\,\underbrace{X\times...\times X}_{n+1\text{ times}}\rightarrow G^{X}\quad.
-\]
-\end_inset
+\end_layout
-It follows by induction that
-\begin_inset Formula $\forall X.\,G^{X}$
-\end_inset
+\begin_layout Subparagraph
+Proof
+\end_layout
- is equivalent to an
-\begin_inset Quotes eld
+\begin_layout Standard
+If
+\begin_inset Formula $T$
\end_inset
-infinite
-\begin_inset Quotes erd
+ and
+\begin_inset Formula $U$
\end_inset
- sum type:
+ are fixed (and equal to the correct greatest fixpoints) then we can write:
\begin_inset Formula
\[
-\forall X.\,G^{X}\cong\bbnum 1+\bbnum 2+\bbnum 3+...
+T=\nu A.\,F^{A,U}\quad,\quad\quad U=\nu B.\,G^{T,B}\quad.
\]
\end_inset
-Values of that type may be described by pairs
-\begin_inset Formula $\left(n,k\right)$
+Now we can substitute
+\begin_inset Formula $U$
\end_inset
- of natural numbers such that
-\begin_inset Formula $1\le k\le n$
+ into the equation for
+\begin_inset Formula $T$
\end_inset
-.
- The number
-\begin_inset Formula $n$
-\end_inset
+:
+\begin_inset Formula
+\[
+T=\nu A.\,F^{A,\,\nu B.\,G^{T,B}}\quad.
+\]
- chooses the part
-\begin_inset Quotes eld
\end_inset
+The last line is a fixpoint equation involving only
+\begin_inset Formula $T$
+\end_inset
-\begin_inset Formula $\bbnum n$
+, so we may express
+\begin_inset Formula $T$
\end_inset
+ as the greatest fixpoint of that equation.
+ Then we get:
+\begin_inset Formula
+\begin{align*}
+ & T=\nu C.\,\nu A.\,F^{A,\,\nu B.\,G^{C,B}}\\
+\text{use Statement~\ref{subsec:Statement-nested-greatest-fixpoints} and set }A=C:\quad & \cong\gunderline{\nu A.}\,F^{A,\,\nu B.\,G^{A,B}}\\
+\text{use Church encoding}:\quad & \cong\exists A.\:(A\rightarrow F^{A,\,\nu B.\,G^{A,B}})\times A\\
+\text{define }N^{A,C}\triangleq(A\rightarrow F^{A,C})\times A:\quad & =\exists A.\:N^{A,\,\nu B.\,G^{A,B}}\\
+\text{Church-co-Yoneda identity (Statement~\ref{subsec:Statement-Church-co-Yoneda})}:\quad & \cong\gunderline{\exists A.\,\exists B.}\,(B\rightarrow G^{A,B})\times N^{A,B}\quad.
+\end{align*}
-\begin_inset Quotes erd
\end_inset
- within the disjunctive type
-\begin_inset Formula $\bbnum 1+\bbnum 2+\bbnum 3+...$
+Writing out the definition of
+\begin_inset Formula $N^{A,B}$
\end_inset
-, where we denoted by
-\begin_inset Quotes eld
+, we obtain the claimed Church encoding for
+\begin_inset Formula $T$
\end_inset
+:
+\begin_inset Formula
+\[
+T\cong\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times A\quad.
+\]
-\begin_inset Formula $\bbnum n$
\end_inset
-
-\begin_inset Quotes erd
+ The formula for
+\begin_inset Formula $U$
\end_inset
- the type
-\begin_inset Formula $\underbrace{\bbnum 1+...+\bbnum 1}_{n\text{ times}}$
+ is derived similarly.
+
+\begin_inset Formula $\square$
\end_inset
-.
- The number
-\begin_inset Formula $k$
-\end_inset
- chooses a specific unit value within
-\begin_inset Formula $\underbrace{\bbnum 1+...+\bbnum 1}_{n\text{ times}}$
-\end_inset
+\end_layout
-.
+\begin_layout Subsection
+Summary of type isomorphisms
\end_layout
\begin_layout Standard
-The next step is to convert values
-\begin_inset Formula $\left(n,k\right)$
-\end_inset
-
- of that type into functions of type
-\begin_inset Formula $M^{X}\rightarrow M^{X}$
+This Appendix has developed various parametricity techniques to prove a
+ number of type isomorphisms.
+ The results are summarized in Tables
+\begin_inset space ~
\end_inset
- that work in the same way for all monads
-\begin_inset Formula $M$
-\end_inset
- and all types
-\begin_inset Formula $X$
-\end_inset
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:Type-identities-proved-by-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
-.
- We have to find out whether any of those functions obey the laws of monad
- morphisms.
- For that, we need to derive the specific code of those functions.
- We follow the steps outlined in the proof of Statement
-\begin_inset space ~
\end_inset
-
+–
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-Jaskelioff-OConnor"
+reference "tab:Type-identities-for-existential-types"
plural "false"
caps "false"
noprefix "false"
@@ -46229,1626 +49468,1665 @@ noprefix "false"
\end_layout
\begin_layout Standard
-First, we translate pairs
-\begin_inset Formula $\left(n,k\right)$
-\end_inset
+\begin_inset Float table
+placement h
+wide false
+sideways false
+status open
- into values of type
-\begin_inset Formula $\forall X.\,G^{X}$
-\end_inset
+\begin_layout Plain Layout
+\align center
+\begin_inset Tabular
+
+
+
+
+
+|
+\begin_inset Text
- that we will denote by
-\begin_inset Formula $q_{n,k}$
-\end_inset
+\begin_layout Plain Layout
-.
- To achieve that, we need to retrace the way we expanded the recursive type
-
-\begin_inset Formula $G^{X}$
-\end_inset
+\series bold
+\size footnotesize
+Identity
+\end_layout
-.
- As an example, consider the pair
-\begin_inset Formula $\left(n=2,k=1\right)$
\end_inset
+ |
+
+\begin_inset Text
-.
- The value
-\begin_inset Formula $n=2$
-\end_inset
+\begin_layout Plain Layout
- corresponds to the type
-\begin_inset Formula $\bbnum 2$
-\end_inset
+\series bold
+\size footnotesize
+Assumptions
+\end_layout
-, which was obtained from
-\begin_inset Formula $\forall X.\,X\rightarrow X\rightarrow X$
\end_inset
+ |
+
+
+|
+\begin_inset Text
- during expansion of
-\begin_inset Formula $\forall X.\,G^{X}$
-\end_inset
+\begin_layout Plain Layout
-.
- The type
-\begin_inset Formula $\forall X.\,X\rightarrow X\rightarrow X$
+\size footnotesize
+\begin_inset Formula $\forall A.\,A\rightarrow A\cong\bbnum 1$
\end_inset
- has only two distinct values, which are functions that return the first
- or the second argument of type
-\begin_inset Formula $X$
+
+\end_layout
+
\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
-.
- The index
-\begin_inset Formula $k=1$
\end_inset
+ |
+
+
+|
+\begin_inset Text
- selects the first of those values, which is a function whose code is written
- as
-\begin_inset Formula $x_{1}^{:X}\rightarrow x_{2}^{:X}\rightarrow x_{1}$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $\forall A.\,A\rightarrow F^{A}\cong F^{\bbnum 1}$
\end_inset
-.
-
+
\end_layout
-\begin_layout Standard
-To simplify notation, let us temporarily fix the type parameter
-\begin_inset Formula $X$
\end_inset
+ |
+
+\begin_inset Text
-; we will restore the quantifier
-\begin_inset Formula $\forall X$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F$
\end_inset
- at the end of the derivation.
+ is any functor
\end_layout
-\begin_layout Standard
-The type
-\begin_inset Formula $X\rightarrow X\rightarrow X$
\end_inset
+ |
+
+
+|
+\begin_inset Text
- was found during expansion of the recursive type
-\begin_inset Formula $G^{X}$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $\forall A.\,A\times A\rightarrow F^{A}\cong F^{\bbnum 2}$
\end_inset
- as:
-\begin_inset Formula
-\[
-G^{X}=X+(X\rightarrow(X+(X\rightarrow(X+...))))\quad.
-\]
+
+\end_layout
\end_inset
+ |
+
+\begin_inset Text
-So, the pair
-\begin_inset Formula $\left(n=2,k=1\right)$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F$
\end_inset
- corresponds to the function
-\begin_inset Formula $q_{2,1}^{X}:G^{X}$
+ is any functor
+\end_layout
+
\end_inset
+ |
+
+
+|
+\begin_inset Text
- written as:
-\begin_inset Formula
-\begin{align*}
- & q_{2,1}^{X}:X+(X\rightarrow(X+(X\rightarrow(X+(X\rightarrow G^{X})))))\quad,\\
- & q_{2,1}^{X}\triangleq\bbnum 0^{:X}+(x_{1}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{2}^{:X}\rightarrow(x_{1}+\bbnum 0^{:X\rightarrow G^{X}}))))\quad.
-\end{align*}
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $\forall A.\,A\cong\bbnum 0$
\end_inset
-In a similar way, we define the functions
-\begin_inset Formula $q_{n,k}$
+
+\end_layout
+
\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\end_layout
- for any
-\begin_inset Formula $1\le k\le n$
\end_inset
+ |
+
+
+|
+\begin_inset Text
-:
-\begin_inset Formula
-\[
-q_{n,k}^{X}\triangleq\bbnum 0^{:X}+(x_{1}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{2}^{:X}\rightarrow...\rightarrow(\bbnum 0^{:X}+(x_{n}^{:X}\rightarrow(x_{k}+\bbnum 0^{:X\rightarrow G^{X}})))...)))\quad.
-\]
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $\forall A.\,F^{A}\cong F^{\bbnum 0}$
\end_inset
-To make this code description rigorous, let us define
-\begin_inset Formula $u_{i,n,k}$
+
+\end_layout
+
\end_inset
+ |
+
+\begin_inset Text
- and
-\begin_inset Formula $v_{i,n}$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F$
\end_inset
- like this:
-\begin_inset Formula
-\begin{align*}
- & u_{i,n,k}\triangleq\bbnum 0^{:X}+(x_{i}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{i+1}^{:X}\rightarrow...\rightarrow(x_{n}^{:X}\rightarrow(x_{k}+\bbnum 0^{:X\rightarrow G^{X}}))...))),\\
- & v_{i,n}(x_{0})\triangleq\bbnum 0^{:X}+(x_{i}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{i+1}^{:X}\rightarrow...\rightarrow(x_{n}^{:X}\rightarrow(x_{0}+\bbnum 0^{:X\rightarrow G^{X}}))...))).
-\end{align*}
+ is any functor
+\end_layout
\end_inset
+ |
+
+
+|
+\begin_inset Text
-These formulas hold for
-\begin_inset Formula $1\le i\le k\le n$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $\forall A.\,H^{A}\cong H^{\bbnum 1}$
\end_inset
-.
- An inductive definition of
-\begin_inset Formula $q_{n,k}^{X}$
+
+\end_layout
+
\end_inset
+ |
+
+\begin_inset Text
-,
-\begin_inset Formula $u_{i,n,k}$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $H$
\end_inset
-, and
-\begin_inset Formula $v_{i,n}$
+ is any contrafunctor
+\end_layout
+
\end_inset
+ |
+
+
+
+\begin_inset Text
- is:
-\begin_inset Formula
-\begin{align*}
- & q_{n,k}^{X}=u_{1,n,k}\quad,\quad\quad u_{i,n,k}:G^{X}\quad,\quad\quad v_{i,n}:X\rightarrow G^{X}\quad,\\
-\text{for }1\le i
+|
+\begin_inset Text
- of type
-\begin_inset Formula $G^{X}=(E^{R})^{X}$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $P$
\end_inset
- into a function
-\begin_inset Formula $f_{n,k}$
+,
+\begin_inset Formula $Q$
\end_inset
- of type:
-\begin_inset Formula
-\[
-f_{n,k}:\forall M^{:\text{Monad}}.\,\big(\forall T.\,(E^{R})^{T}\xrightarrow{\text{Monad}}M^{T}\big)\rightarrow M^{X}\quad.
-\]
+ are fixed types
+\end_layout
\end_inset
+ |
+ |
+
+|
+\begin_inset Text
-The code of
-\begin_inset Formula $f_{n,k}$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $\forall A.\,(P\rightarrow A)\rightarrow Q\rightarrow A\cong Q\rightarrow P$
\end_inset
- is:
-\begin_inset Formula
-\[
-f_{n,k}^{M}\big(p^{:\forall T.\,(E^{R})^{T}\xrightarrow{\text{Monad}}M^{T}}\big)\triangleq p^{X}(q_{n,k}^{X})\quad.
-\]
-\end_inset
+\end_layout
-At this point,
-\begin_inset Formula $p$
\end_inset
+ |
+
+\begin_inset Text
- is an arbitrary function, so we cannot simplify this code any further.
- We proceed to converting
-\begin_inset Formula $f_{n,k}$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $P$
\end_inset
- into a function
-\begin_inset Formula $g_{n,k}$
+,
+\begin_inset Formula $Q$
\end_inset
-:
-\begin_inset Formula
-\begin{align*}
- & g_{n,k}:\forall M^{:\text{Monad}}.\,(\forall T.\,R^{T}\rightarrow M^{T})\rightarrow M^{X}\quad,\\
- & g_{n,k}^{M}\big(p^{:\forall T.\,R^{T}\rightarrow M^{T}}\big)\triangleq f_{n,k}^{M}\big(\forall T.\,r^{:(E^{R})^{T}}\rightarrow\text{run}_{E}^{R,T}(p)(r)\big)\\
- & \quad=\text{run}_{E}^{R,X}(p)(q_{n,k}^{X})\quad.
-\end{align*}
+ are fixed types
+\end_layout
\end_inset
+ |
+
+
+|
+\begin_inset Text
-In our case,
-\begin_inset Formula $R^{T}=X\rightarrow T$
-\end_inset
+\begin_layout Plain Layout
-, so the type of
-\begin_inset Formula $p$
+\size footnotesize
+\begin_inset Formula $\forall A.\,((A\rightarrow P)\rightarrow Q)\rightarrow(A\rightarrow S)\rightarrow R\cong((S\rightarrow P)\rightarrow Q)\rightarrow R$
\end_inset
- is equivalent to just
-\begin_inset Formula $M^{X}$
-\end_inset
-:
-\begin_inset Formula
-\begin{align*}
- & \forall T.\,R^{T}\rightarrow M^{T}=\forall T.\,(X\rightarrow T)\rightarrow M^{T}\\
-\text{covariant Yoneda identity}:\quad & \cong M^{X}\quad.
-\end{align*}
+\end_layout
\end_inset
+ |
+
+\begin_inset Text
-Given a value
-\begin_inset Formula $m:M^{X}$
-\end_inset
+\begin_layout Plain Layout
-, the corresponding value
-\begin_inset Formula $p:\forall T.\,R^{T}\rightarrow M^{T}$
+\size footnotesize
+\begin_inset Formula $P$
\end_inset
- is computed as:
-\begin_inset Formula
-\[
-p:\forall T.\,(X\rightarrow T)\rightarrow M^{T}\quad,\quad\quad p^{T}(r^{:X\rightarrow T})\triangleq m\triangleright r^{\uparrow M}\quad.
-\]
+,
+\begin_inset Formula $Q$
+\end_inset
+,
+\begin_inset Formula $R$
\end_inset
-So, the last step is to convert
-\begin_inset Formula $g_{n,k}^{M}$
+,
+\begin_inset Formula $S$
\end_inset
- into
-\begin_inset Formula $h_{n,k}^{M}$
+ are fixed types
+\end_layout
+
\end_inset
+ |
+
+
+|
+\begin_inset Text
- of type
-\begin_inset Formula $M^{X}\rightarrow M^{X}$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $\forall A.\,(P\rightarrow A\times Q)\rightarrow(A+R)\times S\cong$
\end_inset
-:
-\begin_inset Formula
-\begin{align*}
- & h_{n,k}:\forall M^{:\text{Monad}}.\,M^{X}\rightarrow M^{X}\quad,\\
- & h_{n,k}^{M}(m^{:M^{X}})\triangleq g_{n,k}^{M}(p)=\text{run}_{E}^{R,X}(p)(q_{n,k}^{X})\quad,\\
-\text{where we defined}:\quad & p\triangleq\forall T.\,r^{:X\rightarrow T}\rightarrow m\triangleright r^{\uparrow M}\quad.
-\end{align*}
+\begin_inset Formula $(P\rightarrow Q)\rightarrow(P+R)\times S$
\end_inset
\end_layout
-\begin_layout Standard
-At this point, we must use the definition of
-\begin_inset Formula $\text{run}_{E}$
\end_inset
+ |
+
+\begin_inset Text
- to derive specific code for
-\begin_inset Formula $h_{n,k}^{M}$
-\end_inset
+\begin_layout Plain Layout
-.
- A first simplification is to apply
-\begin_inset Formula $\text{run}_{E}^{R,X}(p)$
+\size footnotesize
+\begin_inset Formula $P$
\end_inset
- substituting the required value of
-\begin_inset Formula $p$
+,
+\begin_inset Formula $Q$
\end_inset
-:
-\begin_inset Formula
-\begin{align*}
- & \text{run}_{E}^{R,X}(p)=\,\begin{array}{|c||c|}
- & M^{X}\\
-\hline X & \text{pu}_{M}\\
-X\rightarrow G^{X} & p^{G^{X}}\bef\text{flm}_{M}\big(\overline{\text{run}}_{E}^{R,X}(p)\big)
-\end{array}\\
- & =\,\begin{array}{|c||c|}
- & M^{X}\\
-\hline X & \text{pu}_{M}\\
-X\rightarrow G^{X} & r^{:X\rightarrow G^{X}}\rightarrow m\triangleright\gunderline{r^{\uparrow M}\bef\text{flm}_{M}}\big(\overline{\text{run}}_{E}^{R,X}(p)\big)
-\end{array}\\
-\text{naturality law of }\text{flm}_{M}:\quad & =\,\,\begin{array}{|c||c|}
- & M^{X}\\
-\hline X & \text{pu}_{M}\\
-X\rightarrow G^{X} & r^{:X\rightarrow G^{X}}\rightarrow m\triangleright\text{flm}_{M}\big(r\bef\overline{\text{run}}_{E}^{R,X}(p)\big)
-\end{array}\quad.
-\end{align*}
-
+,
+\begin_inset Formula $R$
\end_inset
+,
+\begin_inset Formula $S$
+\end_inset
+ are fixed types
\end_layout
-\begin_layout Standard
-To get more intuition, let us compute
-\begin_inset Formula $\text{run}_{E}^{R,X}(p)(q_{2,1})$
\end_inset
+ |
+
+
- using the expression for
-\begin_inset Formula $q_{2,1}$
\end_inset
- derived earlier:
-\begin_inset Formula
-\begin{align*}
- & \text{run}_{E}^{R,X}(p)(q_{2,1}^{X})=q_{2,1}^{X}\triangleright\text{run}_{E}^{R,X}(p)\\
- & =\,\begin{array}{|cc|}
-\bbnum 0 & x_{1}^{:X}\rightarrow\bbnum 0+(x_{2}^{:X}\rightarrow(x_{1}+\bbnum 0))\end{array}\,\triangleright\,\begin{array}{|c||c|}
- & M^{X}\\
-\hline X & \text{pu}_{M}\\
-X\rightarrow G^{X} & r^{:X\rightarrow G^{X}}\rightarrow m\triangleright\text{flm}_{M}\big(r\bef\overline{\text{run}}_{E}^{R,X}(p)\big)
-\end{array}\\
- & =m\triangleright\text{flm}_{M}\big(x_{1}^{:X}\rightarrow\overline{\text{run}}_{E}^{R,X}(p)(\bbnum 0+(x_{2}^{:X}\rightarrow(x_{1}+\bbnum 0)))\big)\quad.
-\end{align*}
-
-\end_inset
-Now we go through a similar calculation with a smaller sub-expression:
-\begin_inset Formula
-\begin{align*}
- & \overline{\text{run}}_{E}^{R,X}(p)(\bbnum 0+(x_{2}^{:X}\rightarrow(x_{1}+\bbnum 0)))\\
- & =\,\begin{array}{|cc|}
-\bbnum 0 & x_{2}^{:X}\rightarrow(x_{1}+\bbnum 0)\end{array}\,\triangleright\,\begin{array}{|c||c|}
- & M^{X}\\
-\hline X & \text{pu}_{M}\\
-X\rightarrow G^{X} & r^{:X\rightarrow G^{X}}\rightarrow m\triangleright\text{flm}_{M}\big(r\bef\overline{\text{run}}_{E}^{R,X}(p)\big)
-\end{array}\\
- & =m\triangleright\text{flm}_{M}(x_{2}^{:X}\rightarrow\overline{\text{run}}_{E}^{R,X}(p)(x_{1}+\bbnum 0))\quad.
-\end{align*}
+\end_layout
-\end_inset
+\begin_layout Plain Layout
+\begin_inset Caption Standard
-Finally, we calculate the last sub-expression:
-\begin_inset Formula
-\begin{align*}
- & \overline{\text{run}}_{E}^{R,X}(p)(x_{1}+\bbnum 0)\\
- & =\,\begin{array}{|cc|}
-x_{1} & \bbnum 0\end{array}\,\triangleright\,\begin{array}{|c||c|}
- & M^{X}\\
-\hline X & \text{pu}_{M}\\
-X\rightarrow G^{X} & r^{:X\rightarrow G^{X}}\rightarrow m\triangleright\text{flm}_{M}\big(r\bef\overline{\text{run}}_{E}^{R,X}(p)\big)
-\end{array}=\text{pu}_{M}(x_{1})\quad.
-\end{align*}
+\begin_layout Plain Layout
+Type isomorphisms proved via Yoneda identities.
+\begin_inset CommandInset label
+LatexCommand label
+name "tab:Type-identities-proved-by-Yoneda"
\end_inset
-Putting the sub-expressions together, we get:
-\begin_inset Formula
-\[
-h_{2,1}^{M}(m)=\text{run}_{E}^{R,X}(p)(q_{2,1}^{X})=m\triangleright\text{flm}_{M}\big(x_{1}^{:X}\rightarrow m\triangleright\text{flm}_{M}(x_{2}^{:X}\rightarrow\text{pu}_{M}(x_{1}))\big)\quad.
-\]
-\end_inset
+\end_layout
-Written in the Scala syntax, the last expression looks like this:
-\begin_inset listings
-inline false
-status open
+\end_inset
-\begin_layout Plain Layout
-def h_2_1(m: M[X]): M[X] = m.flatMap { x_1 => m.flatMap { x_2 => pure(x_1)
- } }
\end_layout
\end_inset
-This code can be rewritten as a functor block, making its logic more visually
- clear:
-\begin_inset listings
-inline false
-status open
-
-\begin_layout Plain Layout
-def h_2_1(m: M[X]): M[X] = for {
\end_layout
-\begin_layout Plain Layout
+\begin_layout Standard
+\begin_inset Float table
+wide false
+sideways false
+status open
- x_1 <- m
-\end_layout
+\begin_layout Plain Layout
+\align center
+\begin_inset Tabular
+
+
+
+
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
- x_2 <- m
+\series bold
+\size footnotesize
+Identity
\end_layout
+\end_inset
+ |
+
+\begin_inset Text
+
\begin_layout Plain Layout
-} yield x_1
+\series bold
+\size footnotesize
+Assumptions
\end_layout
\end_inset
-
-The code runs two effects of
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-m
+\series bold
+\size footnotesize
+Source
\end_layout
\end_inset
-
- but returns the first value (
-\begin_inset listings
-inline true
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-x_1
+\size footnotesize
+\begin_inset Formula $\forall A.\,(F^{A}\rightarrow A)\rightarrow A\cong\mu A.\,F^{A}$
+\end_inset
+
+
\end_layout
\end_inset
-
-), ignoring
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-x_2
-\end_layout
-
+\size footnotesize
+\begin_inset Formula $F$
\end_inset
-.
+ is any functor
\end_layout
-\begin_layout Standard
-Now we can generalize the code pattern from
-\begin_inset Formula $h_{2,1}$
\end_inset
+ |
+
+\begin_inset Text
- to
-\begin_inset Formula $h_{n,k}$
+\begin_layout Plain Layout
+
+\size footnotesize
+Section
+\begin_inset space ~
\end_inset
- and write symbolically:
-\begin_inset listings
-inline false
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:The-Church-encoding-of-recursive-types"
+plural "false"
+caps "false"
+noprefix "false"
-def h_n_k(m: M[X]): M[X] = for {
-\end_layout
+\end_inset
-\begin_layout Plain Layout
- x_1 <- m
\end_layout
-\begin_layout Plain Layout
-
- x_2 <- m
-\end_layout
+\end_inset
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
- ...
-\end_layout
+\size footnotesize
+\begin_inset Formula $\forall A.\,(H^{A}\rightarrow A)\rightarrow A\cong H^{\bbnum 1}$
+\end_inset
-\begin_layout Plain Layout
- x_n <- m
\end_layout
-\begin_layout Plain Layout
+\end_inset
+ |
+
+\begin_inset Text
-} yield x_k
-\end_layout
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $H$
\end_inset
-
+ is any contrafunctor
\end_layout
-\begin_layout Standard
-To prove that this is indeed the correct code for
-\begin_inset Formula $h_{n,k}^{M}(m)$
-\end_inset
-
-, we need to use induction in
-\begin_inset Formula $n$
\end_inset
+ |
+
+\begin_inset Text
-.
- We rewrite
-\begin_inset Formula $q_{n,k}^{X}=u_{1,n,k}$
-\end_inset
+\begin_layout Plain Layout
- and compute
-\begin_inset Formula $\text{run}_{E}^{R,X}(p)(q_{n,k})=\text{run}_{E}^{R,X}(p)(u_{1,n,k})$
+\size footnotesize
+Statement
+\begin_inset space ~
\end_inset
-.
- Using the code of
-\begin_inset Formula $\text{run}_{E}$
-\end_inset
-, we obtain the following inductive code definitions:
-\begin_inset Formula
-\begin{align*}
-\text{for }1\le i
+ |
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-h_n_k
-\end_layout
-
+\size footnotesize
+\begin_inset Formula $\forall A.\,(A\rightarrow A)\rightarrow H^{A}\cong H^{\bbnum 1}$
\end_inset
- we just showed.
+
\end_layout
-\begin_layout Standard
-It remains to check whether the functions
-\begin_inset Formula $h_{n,k}$
\end_inset
+ |
+
+\begin_inset Text
- are monad morphisms.
- We note that
-\begin_inset Formula $h_{1,1}$
-\end_inset
+\begin_layout Plain Layout
- is an identity function, due to the monad
-\begin_inset Formula $M$
+\size footnotesize
+\begin_inset Formula $H$
\end_inset
-'s identity law:
-\begin_inset Formula
-\[
-h_{1,1}^{M}(m)=m\triangleright\text{flm}_{M}(\gunderline{x_{1}^{:X}\rightarrow\text{pu}_{M}(x_{1})})=m\triangleright\gunderline{\text{flm}_{M}(\text{pu}_{M})}=m\quad.
-\]
+ is any contrafunctor
+\end_layout
\end_inset
+ |
+
+\begin_inset Text
-So,
-\begin_inset Formula $h_{1,1}$
-\end_inset
+\begin_layout Plain Layout
- is (trivially) a monad morphism.
- We will now show that
-\begin_inset Formula $h_{n,k}$
+\size footnotesize
+Example
+\begin_inset space ~
\end_inset
- for
-\begin_inset Formula $n\ge2$
-\end_inset
- are
-\emph on
-not
-\emph default
- monad morphisms.
- It is sufficient to choose a specific monad
-\begin_inset Formula $M$
-\end_inset
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-strong-dinaturality-show-void"
+plural "false"
+caps "false"
+noprefix "false"
- and to show that a specific monad morphism law fails.
- We will check the monad morphism composition law: for any value
-\begin_inset Formula $q:M^{M^{X}}$
\end_inset
-,
-\begin_inset Formula
-\[
-h_{n,k}(\text{ftn}_{M}(q))\overset{?}{=}\text{ftn}_{M}(h_{n,k}(q\triangleright h_{n,k}^{\uparrow M}))\quad.
-\]
+(b)
+\end_layout
\end_inset
+ |
+
+
+|
+\begin_inset Text
-We choose
-\begin_inset Formula $M$
-\end_inset
+\begin_layout Plain Layout
- as the standard
-\begin_inset listings
-inline true
-status open
+\size footnotesize
+\begin_inset Formula $\forall A.\,(F^{A}\rightarrow A)\rightarrow G^{A}\cong G^{\mu A.\,F^{A}}$
+\end_inset
-\begin_layout Plain Layout
-State
\end_layout
\end_inset
-
- monad with the internal state of type
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-Int
-\end_layout
-
+\size footnotesize
+\begin_inset Formula $F$
\end_inset
-.
- To show a counterexample that disproves the composition law, we will use
- a specially chosen value
-\begin_inset Formula $q$
+,
+\begin_inset Formula $G$
\end_inset
- of type
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-
-State[Int, State[Int, Unit]]
+ are any functors
\end_layout
\end_inset
-
-:
-\begin_inset listings
-inline false
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-type M[A] = Int => (A, Int)
-\end_layout
+\size footnotesize
+Statement
+\begin_inset space ~
+\end_inset
-\begin_layout Plain Layout
-val q: M[M[Unit]] = { s => ( { t => ((), s + 1) }, s) }
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-Church-Yoneda-identity"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
-\begin_inset Formula
-\[
-M^{A}\triangleq\text{Int}\rightarrow A\times\text{Int}\quad,\quad\quad q:M^{M^{\bbnum 1}}\quad,\quad q\triangleq s^{:\text{Int}}\rightarrow(\_^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}})\times s\quad.
-\]
+\end_layout
\end_inset
-
-For more intuition, let us express
-\begin_inset listings
-inline true
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-q
-\end_layout
-
+\size footnotesize
+\begin_inset Formula $\mu A.\,\mu B.\,F^{A,B}\cong\mu B.\,F^{B,B}$
\end_inset
- via the
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-State
\end_layout
\end_inset
-
- monad operations
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-get
+\size footnotesize
+\begin_inset Formula $F$
+\end_inset
+
+ is any bifunctor
\end_layout
\end_inset
-
- and
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-set
-\end_layout
-
+\size footnotesize
+Statement
+\begin_inset space ~
\end_inset
-:
-\begin_inset listings
-inline false
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-nested-fixpoints"
+plural "false"
+caps "false"
+noprefix "false"
-val get: M[Int] = s => (s, s)
-\end_layout
+\end_inset
-\begin_layout Plain Layout
-val set: Int => M[Unit] = x => s => ((), x)
\end_layout
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
\begin_layout Plain Layout
-// Assuming that map and flatMap are defined for M:
-\end_layout
+\size footnotesize
+\begin_inset Note Note
+status collapsed
\begin_layout Plain Layout
-val q: M[M[Unit]] = for {
-\end_layout
+\size footnotesize
+See
+\family typewriter
+\size default
-\begin_layout Plain Layout
+\begin_inset CommandInset href
+LatexCommand href
+target "https://tex.stackexchange.com/questions/50332/vertical-spacing-of-a-table-cell"
+literal "false"
- s <- get
-\end_layout
+\end_inset
-\begin_layout Plain Layout
-} yield set(s + 1)
\end_layout
\end_inset
-Now we compute the two sides of the composition law, step by step.
- First, we will use Scala's functor block syntax.
- The
-\begin_inset listings
-inline true
-status open
+
+\begin_inset Box Frameless
+position "c"
+hor_pos "c"
+has_inner_box 1
+inner_pos "t"
+use_parbox 0
+use_makebox 0
+width "0.1mm"
+special "none"
+height "12mm"
+height_special "none"
+thickness "0.4pt"
+separation "3pt"
+shadowsize "4pt"
+framecolor "black"
+backgroundcolor "none"
+status collapsed
\begin_layout Plain Layout
-flatten
\end_layout
\end_inset
- method can be written as:
-\begin_inset listings
-inline false
+
+\begin_inset Box Frameless
+position "c"
+hor_pos "c"
+has_inner_box 1
+inner_pos "c"
+use_parbox 0
+use_makebox 0
+width "43col%"
+special "none"
+height "1in"
+height_special "totalheight"
+thickness "0.4pt"
+separation "3pt"
+shadowsize "4pt"
+framecolor "black"
+backgroundcolor "none"
status open
\begin_layout Plain Layout
+\align center
-def flatten[A](mm: M[M[A]]): M[A] = for {
-\end_layout
+\size footnotesize
+\begin_inset Formula $\mu A.\,P^{A,\,\mu B.\,Q^{A,B}}\cong$
+\end_inset
-\begin_layout Plain Layout
- m <- mm
-\end_layout
+\begin_inset Newline newline
+\end_inset
-\begin_layout Plain Layout
- x <- m
-\end_layout
+\begin_inset Formula $\forall A.\,\forall B.\,(P^{A,B}\rightarrow A)\times(Q^{A,B}\rightarrow B)\rightarrow A$
+\end_inset
-\begin_layout Plain Layout
-} yield x
\end_layout
\end_inset
-Substituting the value
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-q
\end_layout
\end_inset
-
- defined above, we get:
-\begin_inset listings
-inline false
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-val flatten_q: M[Unit] = for { // This is flatten(q).
-\end_layout
+\size footnotesize
+\begin_inset Formula $P$
+\end_inset
-\begin_layout Plain Layout
+,
+\begin_inset Formula $Q$
+\end_inset
- m <- for {
+ are any bifunctors
\end_layout
-\begin_layout Plain Layout
-
- s <- get
-\end_layout
+\end_inset
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
- } yield set(s + 1)
-\end_layout
+\size footnotesize
+Statement
+\begin_inset space ~
+\end_inset
-\begin_layout Plain Layout
- x <- m
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-nested-fixpoint-under-functor"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
-\begin_layout Plain Layout
-} yield x
\end_layout
\end_inset
-
-Eliminate the nested
-\begin_inset listings
-inline true
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-for
+\size footnotesize
+\begin_inset Formula $\forall A.\,F^{A}\rightarrow P\cong P$
+\end_inset
+
+
\end_layout
\end_inset
-
- and obtain:
-\begin_inset listings
-inline false
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-val flatten_q: M[Unit] = for {
-\end_layout
+\size footnotesize
+If
+\begin_inset Formula $F^{A}\neq\bbnum 0$
+\end_inset
+
+ for some
+\begin_inset Formula $A$
+\end_inset
-\begin_layout Plain Layout
- s <- get
\end_layout
+\end_inset
+ |
+
+\begin_inset Text
+
\begin_layout Plain Layout
- m = set(s + 1)
-\end_layout
+\size footnotesize
+Statement
+\begin_inset space ~
+\end_inset
-\begin_layout Plain Layout
- x <- m
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-application-full-relation"
+plural "false"
+caps "false"
+noprefix "false"
-\begin_layout Plain Layout
+\end_inset
-} yield x
+(a)
\end_layout
\end_inset
-
-Or equivalently (as the returned value is always a unit value):
-\begin_inset listings
-inline false
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-val flatten_q: M[Unit] = for {
-\end_layout
+\size footnotesize
+\begin_inset Formula $\forall A.\,((A\rightarrow A)\rightarrow A)\rightarrow A\cong\bbnum 1+\bbnum 2+\bbnum 3+...$
+\end_inset
-\begin_layout Plain Layout
- s <- get
\end_layout
+\end_inset
+ |
+
+\begin_inset Text
+
\begin_layout Plain Layout
- _ <- set(s + 1)
-\end_layout
+\size footnotesize
+\begin_inset space ~
+\end_inset
-\begin_layout Plain Layout
-} yield ()
\end_layout
\end_inset
-
-Applying
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-h_n_k
-\end_layout
-
+\size footnotesize
+Statement
+\begin_inset space ~
\end_inset
- to this value means writing code of the form:
-\begin_inset listings
-inline false
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-advanced-type-equivalence"
+plural "false"
+caps "false"
+noprefix "false"
-val h_flatten_q: M[Unit] = for {
-\end_layout
+\end_inset
-\begin_layout Plain Layout
- x_1 <- flatten_q
\end_layout
-\begin_layout Plain Layout
-
- ...
-\end_layout
+\end_inset
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
- x_n <- flatten_q
-\end_layout
+\size footnotesize
+\begin_inset Box Frameless
+position "c"
+hor_pos "c"
+has_inner_box 1
+inner_pos "t"
+use_parbox 0
+use_makebox 0
+width "0.1mm"
+special "none"
+height "17mm"
+height_special "none"
+thickness "0.4pt"
+separation "3pt"
+shadowsize "4pt"
+framecolor "black"
+backgroundcolor "none"
+status open
\begin_layout Plain Layout
-} yield x_k
\end_layout
\end_inset
-The returned value in
-\begin_inset listings
-inline true
+
+\begin_inset Box Frameless
+position "c"
+hor_pos "c"
+has_inner_box 1
+inner_pos "c"
+use_parbox 0
+use_makebox 0
+width "43col%"
+special "none"
+height "1in"
+height_special "totalheight"
+thickness "0.4pt"
+separation "3pt"
+shadowsize "4pt"
+framecolor "black"
+backgroundcolor "none"
status open
\begin_layout Plain Layout
+\align center
+
+\size footnotesize
+\begin_inset Formula $\forall A.\,(H^{A}\rightarrow A)\rightarrow F^{A}+G^{A}\cong$
+\end_inset
-x_k
-\end_layout
+\begin_inset Newline newline
\end_inset
- is in any case the unit value, so let us focus on the state updates.
- Each
-\begin_inset listings
-inline true
-status open
-\begin_layout Plain Layout
+\begin_inset Formula $(\forall A.\:(H^{A}\rightarrow A)\rightarrow F^{A})\,+$
+\end_inset
-flatten_q
-\end_layout
+\begin_inset Newline newline
\end_inset
- has the effect of reading the state value
-\begin_inset listings
-inline true
-status open
-\begin_layout Plain Layout
+\begin_inset Formula $(\forall A.\:(H^{A}\rightarrow A)\rightarrow G^{A})$
+\end_inset
+
-s
\end_layout
\end_inset
- and storing the incremented value
-\begin_inset listings
-inline true
-status open
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-s + 1
-\end_layout
+\size footnotesize
+For any
+\begin_inset Formula $F$
+\end_inset
+,
+\begin_inset Formula $G$
\end_inset
-.
- The function
-\begin_inset listings
-inline true
-status open
+,
+\begin_inset Formula $H$
+\end_inset
-\begin_layout Plain Layout
-h_n_k
\end_layout
\end_inset
+ |
+
+\begin_inset Text
- repeats
-\begin_inset Formula $n$
+\begin_layout Plain Layout
+
+\size footnotesize
+Example
+\begin_inset space ~
\end_inset
- times the effect of
-\begin_inset listings
-inline true
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-undisjunctive-type-constructors"
+plural "false"
+caps "false"
+noprefix "false"
-flatten_q
+\end_inset
+
+(c)
\end_layout
\end_inset
+ |
+
+
+|
+\begin_inset Text
-.
- This increments the internal state
-\begin_inset Formula $n$
-\end_inset
+\begin_layout Plain Layout
- times.
- So, the left-hand side of the law is equivalent to:
-\begin_inset listings
-inline false
-status open
+\size footnotesize
+\begin_inset Formula $\forall A.\,\forall B.\,F^{A,B}\cong\forall B.\,\forall A.\,F^{A,B}$
+\end_inset
-\begin_layout Plain Layout
-val lhs: M[Unit] = for { // This is h_flatten_q === h_n_k(flatten(q)).
\end_layout
+\end_inset
+ |
+
+\begin_inset Text
+
\begin_layout Plain Layout
- s <- get
-\end_layout
+\size footnotesize
+For any
+\begin_inset Formula $F$
+\end_inset
-\begin_layout Plain Layout
- _ <- set(s + n)
\end_layout
-\begin_layout Plain Layout
+\end_inset
+ |
+
+\begin_inset Text
-} yield ()
-\end_layout
+\begin_layout Plain Layout
+\size footnotesize
+Statement
+\begin_inset space ~
\end_inset
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-Fubini-theorem-1"
+plural "false"
+caps "false"
+noprefix "false"
-\begin_layout Standard
-Turning now to the right-hand side of the law, we write the first sub-expression
- (
-\begin_inset Formula $q\triangleright h_{n,k}^{\uparrow M}$
\end_inset
-, or in Scala,
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-q.map(h_n_k)
\end_layout
\end_inset
-
-) as the following Scala code:
-\begin_inset listings
-inline false
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-val q_map_h: M[M[Unit]] = for {
-\end_layout
+\size footnotesize
+\begin_inset Formula $\forall A.\,(F^{A}+G^{A})\cong(\forall A.\,F^{A})+(\forall A.\,G^{A})$
+\end_inset
-\begin_layout Plain Layout
- m <- q
\end_layout
-\begin_layout Plain Layout
+\end_inset
+ |
+
+\begin_inset Text
-} yield h_n_k(m)
-\end_layout
+\begin_layout Plain Layout
+\size footnotesize
+For any
+\begin_inset Formula $F$
\end_inset
-Substituting the code of
-\begin_inset listings
-inline true
-status open
+,
+\begin_inset Formula $G$
+\end_inset
-\begin_layout Plain Layout
-q
\end_layout
\end_inset
-
- (but not yet expanding
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-h_n_k
-\end_layout
-
+\size footnotesize
+Statement
+\begin_inset space ~
\end_inset
-), we find:
-\begin_inset listings
-inline false
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-general-identities-forall"
+plural "false"
+caps "false"
+noprefix "false"
-val q_map_h: M[M[Unit]] = for {
+\end_inset
+
+(a)
\end_layout
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
\begin_layout Plain Layout
- s <- get
-\end_layout
+\size footnotesize
+\begin_inset Formula $\forall A.\,(F^{A}\times G^{A})\cong(\forall A.\,F^{A})\times(\forall A.\,G^{A})$
+\end_inset
-\begin_layout Plain Layout
-} yield h_n_k(set(s + 1))
\end_layout
\end_inset
-
-The function call
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-h_n_k(set(s + 1))
-\end_layout
-
+\size footnotesize
+For any
+\begin_inset Formula $F$
\end_inset
- repeats
-\begin_inset Formula $n$
+,
+\begin_inset Formula $G$
\end_inset
- times the effect of
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-set(s + 1)
\end_layout
\end_inset
-
-, but
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-s
-\end_layout
-
+\size footnotesize
+Statement
+\begin_inset space ~
\end_inset
- is a fixed value in that scope, so the result is equal to just a single
- effect:
-\begin_inset listings
-inline false
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-general-identities-forall"
+plural "false"
+caps "false"
+noprefix "false"
-val q_map_h: M[M[Unit]] = for {
+\end_inset
+
+(b)
\end_layout
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
\begin_layout Plain Layout
- s <- get
-\end_layout
+\size footnotesize
+\begin_inset Formula $\forall A.\,R\rightarrow F^{A}\cong R\rightarrow(\forall A.\,F^{A})$
+\end_inset
-\begin_layout Plain Layout
-} yield set(s + 1)
\end_layout
\end_inset
-
-This is the same value as
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-q
-\end_layout
+\size footnotesize
+Any
+\begin_inset Formula $F$
+\end_inset
+, a fixed type
+\begin_inset Formula $R$
\end_inset
- itself.
+
\end_layout
-\begin_layout Standard
-The next sub-expression is
-\begin_inset listings
-inline true
-status open
+\end_inset
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-h_n_k(q_map_h)
-\end_layout
-
+\size footnotesize
+Statement
+\begin_inset space ~
\end_inset
-, which equals
-\begin_inset listings
-inline true
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-general-identities-forall"
+plural "false"
+caps "false"
+noprefix "false"
-h_n_k(q)
+\end_inset
+
+(c)
\end_layout
\end_inset
-
-:
-\begin_inset listings
-inline false
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-val h_q_map_h: M[M[Unit]] = for {
-\end_layout
+\size footnotesize
+\begin_inset Formula $\forall A.\,F^{P^{A}}\cong F^{\forall A.\,P^{A}}$
+\end_inset
-\begin_layout Plain Layout
- x_1 <- q
\end_layout
-\begin_layout Plain Layout
-
- ...
-\end_layout
+\end_inset
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
- x_n <- q
-\end_layout
-
-\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $F$
+\end_inset
-} yield x_k
+ is strictly positive
\end_layout
\end_inset
-
-Substituting the code for
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-q
-\end_layout
-
+\size footnotesize
+Statement
+\begin_inset space ~
\end_inset
-, we get:
-\begin_inset listings
-inline false
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-quantifier-across-functor"
+plural "false"
+caps "false"
+noprefix "false"
-val h_q_map_h: M[M[Unit]] = for {
-\end_layout
+\end_inset
-\begin_layout Plain Layout
- x_1 <- for {
\end_layout
-\begin_layout Plain Layout
-
- s <- get
-\end_layout
+\end_inset
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
- } yield set(s + 1)
-\end_layout
-
-\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $\forall A.\,F^{A}\cong\bbnum 0$
+\end_inset
- ...
-\end_layout
+ when
+\begin_inset Formula $F^{\bbnum 0}\cong\bbnum 0$
+\end_inset
-\begin_layout Plain Layout
- x_n <- for {
\end_layout
-\begin_layout Plain Layout
-
- s <- get
-\end_layout
+\end_inset
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
- } yield set(s + 1)
-\end_layout
+\size footnotesize
+\begin_inset Formula $F$
+\end_inset
+
+ is such that
+\begin_inset Formula $F^{\bbnum 0}\cong\bbnum 0$
+\end_inset
-\begin_layout Plain Layout
-} yield x_k
\end_layout
\end_inset
-
-Eliminate the nested
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-for
-\end_layout
-
+\size footnotesize
+Statement
+\begin_inset space ~
\end_inset
- and obtain:
-\begin_inset listings
-inline false
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-Fubini-theorem-1"
+plural "false"
+caps "false"
+noprefix "false"
-val h_q_map_h: M[M[Unit]] = for {
-\end_layout
+\end_inset
-\begin_layout Plain Layout
- s <- get
\end_layout
-\begin_layout Plain Layout
-
- x_1 = set(s + 1)
-\end_layout
+\end_inset
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
- ...
-\end_layout
+\size footnotesize
+\begin_inset Formula $\forall A.\,F^{A\rightarrow A}\cong F^{\bbnum 1}$
+\end_inset
-\begin_layout Plain Layout
- s <- get
\end_layout
-\begin_layout Plain Layout
-
- x_n = set(s + 1)
-\end_layout
+\end_inset
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-} yield x_k
+\size footnotesize
+\begin_inset Formula $F$
+\end_inset
+
+ is strictly positive
\end_layout
\end_inset
+ |
+
+\begin_inset Text
-The code runs
-\begin_inset Formula $n$
+\begin_layout Plain Layout
+
+\size footnotesize
+Example
+\begin_inset space ~
\end_inset
- times the effect of
-\begin_inset listings
-inline true
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-simplify-quantifier-A-A"
+plural "false"
+caps "false"
+noprefix "false"
-get
+\end_inset
+
+(a)
\end_layout
\end_inset
-
- but actually never runs the effect of
-\begin_inset listings
-inline true
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-set
-\end_layout
-
+\size footnotesize
+\begin_inset Formula $\forall A.\,H^{A\rightarrow A}\cong H^{\bbnum 1}$
\end_inset
-; the unevaluated effectful value
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-set(s + 1)
\end_layout
\end_inset
-
- is merely assigned to each
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-x_i
+\size footnotesize
+\begin_inset Formula $H$
+\end_inset
+
+ is a contrafunctor
\end_layout
\end_inset
-
- and then returned.
- So, the code is equivalent to:
-\begin_inset listings
-inline false
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-val h_q_map_h: M[M[Unit]] = for {
-\end_layout
+\size footnotesize
+Example
+\begin_inset space ~
+\end_inset
-\begin_layout Plain Layout
- s <- get
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-simplify-quantifier-A-A"
+plural "false"
+caps "false"
+noprefix "false"
-\begin_layout Plain Layout
+\end_inset
-} yield set(s + 1)
+(b)
\end_layout
\end_inset
-
-This is again just equal to
-\begin_inset listings
-inline true
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-q
-\end_layout
-
+\size footnotesize
+\begin_inset Formula $\forall A.\,((A\rightarrow P)\rightarrow A\rightarrow A\cong P$
\end_inset
-.
+
\end_layout
-\begin_layout Standard
-It remains to apply
-\begin_inset listings
-inline true
-status open
+\end_inset
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-flatten
+\size footnotesize
+\begin_inset Formula $P$
+\end_inset
+
+ is a fixed type
\end_layout
\end_inset
-
- to
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-h_q_map_h
-\end_layout
-
+\size footnotesize
+Exercise
+\begin_inset space ~
\end_inset
-, which is the same as
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-flatten(q)
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "par:Problem-Peirce-law"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
- and was already computed as
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-flatten_q
\end_layout
\end_inset
+ |
+
+
- above:
-\begin_inset listings
-inline false
-status open
+\end_inset
-\begin_layout Plain Layout
-val rhs: M[Unit] = for { // This is flatten(h_q_map_h) === flatten(q).
\end_layout
\begin_layout Plain Layout
-
- s <- get
-\end_layout
+\begin_inset Caption Standard
\begin_layout Plain Layout
+Type identities proved by other parametricity techniques.
+\begin_inset CommandInset label
+LatexCommand label
+name "tab:Type-identities-proved-by-parametricity"
+
+\end_inset
+
- _ <- set(s + 1)
\end_layout
-\begin_layout Plain Layout
+\end_inset
+
-} yield ()
\end_layout
\end_inset
@@ -47857,340 +51135,300 @@ val rhs: M[Unit] = for { // This is flatten(h_q_map_h) === flatten(q).
\end_layout
\begin_layout Standard
-The left-hand side and the right-hand side of the law differ only in the
-
-\begin_inset listings
-inline true
+\begin_inset Float table
+placement h
+wide false
+sideways false
status open
+\begin_layout Plain Layout
+\align center
+\begin_inset Tabular
+
+
+
+
+
+
+|
+\begin_inset Text
+
\begin_layout Plain Layout
-set
+\series bold
+\size footnotesize
+Identity
\end_layout
\end_inset
-
- operation (
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-set(s + n)
+\series bold
+\size footnotesize
+Assumptions
\end_layout
\end_inset
-
- vs.
-\begin_inset space ~
-\end_inset
-
-
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-set(s + 1)
+\series bold
+\size footnotesize
+Source
\end_layout
\end_inset
-
-).
- So, they are equal only when
-\begin_inset Formula $n=1$
-\end_inset
-
- (that is, for
-\begin_inset listings
-inline true
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-h_1_1
-\end_layout
-
+\size footnotesize
+\begin_inset Formula $\exists C.\,F^{C}\cong\forall D.\,\big(\forall C.\,(F^{C}\rightarrow D)\big)\rightarrow D$
\end_inset
-).
- It follows that, for all
-\begin_inset Formula $n\ge2$
-\end_inset
- and for all
-\begin_inset Formula $1\le k\le n$
-\end_inset
+\end_layout
-, the function
-\begin_inset Formula $h_{n,k}$
\end_inset
+ |
+
+\begin_inset Text
- of type
-\begin_inset Formula $M^{X}\rightarrow M^{X}$
-\end_inset
+\begin_layout Plain Layout
- violates the composition law of monad morphisms when applied to the chosen
- value
-\begin_inset Formula $q:M^{M^{X}}$
+\size footnotesize
+For any
+\begin_inset Formula $F$
\end_inset
-.
-\end_layout
-\begin_layout Standard
-Let us now summarize this derivation in code notation.
- The left-hand side of the composition law is:
-\begin_inset Formula
-\begin{align*}
- & \text{ftn}_{M}(q)=s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}}\quad,\\
- & h_{n,k}(\text{ftn}_{M}(q))=s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+n)^{:\text{Int}}\quad.
-\end{align*}
+\end_layout
\end_inset
+ |
+
+\begin_inset Text
-Here we used the fact that
-\begin_inset Formula $h_{n,k}(m)$
-\end_inset
+\begin_layout Plain Layout
- repeats
-\begin_inset Formula $n$
+\size footnotesize
+Equation
+\begin_inset space ~
\end_inset
- times the effect of
-\begin_inset Formula $m$
-\end_inset
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:existential-via-universal-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
- (and that effect increments the value
-\begin_inset Formula $s$
\end_inset
-).
-
+)
\end_layout
-\begin_layout Standard
-Turn to the right-hand side of the law and calculate:
-\begin_inset Formula
-\begin{align*}
- & q\triangleright h_{n,k}^{\uparrow M}=s^{:\text{Int}}\rightarrow(\_^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}})\times s=q\quad,\\
- & h_{n,k}(q\triangleright h_{n,k}^{\uparrow M})=s^{:\text{Int}}\rightarrow(\_^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}})\times s=q\quad,\\
- & \text{ftn}_{M}(q)=s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}}\quad.
-\end{align*}
-
\end_inset
+ |
+
+
+|
+\begin_inset Text
-The condition for the two sides of the law to be equal is:
-\begin_inset Formula
-\[
-s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+n)^{:\text{Int}}\overset{?}{=}s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}}\quad.
-\]
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $(\exists C.\,F^{C})\rightarrow R\cong\forall C.\,(F^{C}\rightarrow R)$
\end_inset
-This holds only if
-\begin_inset Formula $n=1$
-\end_inset
-.
\end_layout
-\begin_layout Standard
-It follows that
-\begin_inset Formula $h_{1,1}$
\end_inset
+ |
+
+\begin_inset Text
- (which is an identity function of type
-\begin_inset Formula $M^{X}\rightarrow M^{X}$
+\begin_layout Plain Layout
+
+\size footnotesize
+For any
+\begin_inset Formula $F$
\end_inset
-) is the only monad morphism that fits the required type.
-
-\begin_inset Formula $\square$
+,
+\begin_inset Formula $R$
\end_inset
\end_layout
-\begin_layout Subsection
-Existential type quantifiers.
- Co-Yoneda identities
-\end_layout
+\end_inset
+ |
+
+\begin_inset Text
-\begin_layout Standard
-The Yoneda identities allow us in many cases to simplify type expressions
- with universal quantifiers.
- Similar identities hold for existentially quantified types.
-\end_layout
+\begin_layout Plain Layout
-\begin_layout Standard
-For the purposes of this and the following sections, we define the existential
- quantifier via Eq.
+\size footnotesize
+Statement
\begin_inset space ~
\end_inset
-(
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:existential-via-universal-Yoneda"
+reference "subsec:Statement-function-extension-rule"
plural "false"
caps "false"
noprefix "false"
\end_inset
-):
-\begin_inset Formula
-\[
-\exists C.\,F^{C}\cong\forall D.\,\big(\forall C.\,(F^{C}\rightarrow D)\big)\rightarrow D\quad.
-\]
+
+\end_layout
\end_inset
+ |
+
+
+|
+\begin_inset Text
-Here
-\begin_inset Formula $F$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $\exists A.\,A\cong\bbnum 1$
\end_inset
- is any type constructor (not necessarily covariant or contravariant).
-\end_layout
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-co-Yoneda-two-identities"
+\end_layout
\end_inset
+ |
+
+\begin_inset Text
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-co-Yoneda-two-identities"
-plural "false"
-caps "false"
-noprefix "false"
+\end_layout
\end_inset
+ |
+
+\begin_inset Text
+\begin_layout Plain Layout
\end_layout
-\begin_layout Standard
-For any functor
-\begin_inset Formula $F$
\end_inset
+ |
+
+
+|
+\begin_inset Text
- and any contrafunctor
-\begin_inset Formula $H$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $\exists A.\,F^{A}\cong F^{\bbnum 1}$
\end_inset
-, the following identities hold:
-\begin_inset Formula
-\begin{align*}
-\text{\textbf{(a)} }\text{covariant co-Yoneda identity}:\quad & \exists A.\,(A\rightarrow R)\times F^{A}\cong F^{R}\quad,\\
-\text{\textbf{(b)} }\text{contravariant co-Yoneda identity}:\quad & \exists A.\,(R\rightarrow A)\times H^{A}\cong H^{R}\quad.
-\end{align*}
+
+\end_layout
\end_inset
+ |
+
+\begin_inset Text
+\begin_layout Plain Layout
-\end_layout
+\size footnotesize
+\begin_inset Formula $F$
+\end_inset
-\begin_layout Subparagraph
-Proof
+ is any functor
\end_layout
-\begin_layout Standard
-We use Eq.
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+Statement
\begin_inset space ~
\end_inset
-(
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:existential-via-universal-Yoneda"
+reference "subsec:Statement-co-Yoneda-two-identities-1"
plural "false"
caps "false"
noprefix "false"
\end_inset
-) to express
-\begin_inset Formula $\exists A$
-\end_inset
-
- via
-\begin_inset Formula $\forall A$
-\end_inset
-
-.
-
+(a)
\end_layout
-\begin_layout Standard
+\end_inset
+ |
+
+
+|
+\begin_inset Text
-\series bold
-(a)
-\series default
- We write:
-\begin_inset Formula
-\begin{align*}
-\text{expect to equal }F^{R}:\quad & \exists A.\,(A\rightarrow R)\times F^{A}\\
-\text{definition of }\exists\text{ in Eq.~}(\ref{eq:existential-via-universal-Yoneda}):\quad & \cong\forall B.\,\big(\forall A.\,\gunderline{(A\rightarrow R)\times F^{A}}\rightarrow B\big)\rightarrow B\\
-\text{uncurry arguments}:\quad & \cong\forall B.\,\big(\gunderline{\forall A.\,(A\rightarrow R)\rightarrow F^{A}\rightarrow B}\big)\rightarrow B\\
-\text{contravariant Yoneda identity}:\quad & \cong\gunderline{\forall B.\,\big(F^{R}\rightarrow B\big)\rightarrow B}\\
-\text{covariant Yoneda identity}:\quad & \cong F^{R}\quad.
-\end{align*}
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $\exists A.\,H^{A}\cong H^{\bbnum 0}$
\end_inset
\end_layout
-\begin_layout Standard
-
-\series bold
-(b)
-\series default
- We write:
-\begin_inset Formula
-\begin{align*}
-\text{expect to equal }H^{R}:\quad & \exists A.\,(R\rightarrow A)\times H^{A}\\
-\text{definition of }\exists\text{ in Eq.~}(\ref{eq:existential-via-universal-Yoneda}):\quad & \cong\forall B.\,\big(\forall A.\,\gunderline{(R\rightarrow A)\times H^{A}}\rightarrow B\big)\rightarrow B\\
-\text{uncurry arguments}:\quad & \cong\forall B.\,\big(\gunderline{\forall A.\,(R\rightarrow A)\rightarrow H^{A}\rightarrow B}\big)\rightarrow B\\
-\text{covariant Yoneda identity}:\quad & \cong\gunderline{\forall B.\,\big(H^{R}\rightarrow B\big)\rightarrow B}\\
-\text{covariant Yoneda identity}:\quad & \cong H^{R}\quad.
-\end{align*}
-
\end_inset
+ |
+
+\begin_inset Text
+\begin_layout Plain Layout
-\begin_inset Formula $\square$
+\size footnotesize
+\begin_inset Formula $H$
\end_inset
-
+ is any contrafunctor
\end_layout
-\begin_layout Standard
-To build up intuition, let us substitute
-\begin_inset Formula $R=\bbnum 0$
-\end_inset
-
- and
-\begin_inset Formula $R=\bbnum 1$
\end_inset
+ |
+
+\begin_inset Text
- into the co-Yoneda identities:
-\end_layout
-
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-co-Yoneda-two-identities-1"
+\begin_layout Plain Layout
+\size footnotesize
+Statement
+\begin_inset space ~
\end_inset
@@ -48203,486 +51441,442 @@ noprefix "false"
\end_inset
-
-\end_layout
-
-\begin_layout Standard
-The following type equivalences hold:
-\begin_inset Formula
-\begin{align*}
-\text{\textbf{(a)} for any functor }F:\quad & \exists A.\,F^{A}\cong F^{\bbnum 1}\quad,\\
-\text{\textbf{(b)} for any contrafunctor }F:\quad & \exists A.\,H^{A}\cong H^{\bbnum 0}\quad.
-\end{align*}
-
-\end_inset
-
-
-\end_layout
-
-\begin_layout Subparagraph
-Proof
+(b)
\end_layout
-\begin_layout Standard
-For
-\series bold
-(a)
-\series default
-, set
-\begin_inset Formula $R=\bbnum 1$
\end_inset
+ |
+
+
+|
+\begin_inset Text
- in the covariant co-Yoneda identity:
-\begin_inset Formula
-\begin{align*}
-\text{left-hand side}:\quad & \exists A.\,(\gunderline{A\rightarrow\bbnum 1})\times F^{A}\cong\exists A.\,\bbnum 1\times F^{A}\cong\exists A.\,F^{A}\quad,\\
-\text{right-hand side}:\quad & F^{\bbnum 1}\quad.
-\end{align*}
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $\exists A.\,F^{A}\rightarrow A\cong\bbnum 1$
\end_inset
\end_layout
-\begin_layout Standard
-For
-\series bold
-(b)
-\series default
-, set
-\begin_inset Formula $R=\bbnum 0$
\end_inset
+ |
+
+\begin_inset Text
- in the contravariant co-Yoneda identity:
-\begin_inset Formula
-\begin{align*}
-\text{left-hand side}:\quad & \exists A.\,(\gunderline{\bbnum 0\rightarrow A})\times H^{A}\cong\exists A.\,\bbnum 1\times H^{A}\cong\exists A.\,H^{A}\quad,\\
-\text{right-hand side}:\quad & H^{\bbnum 0}\quad.
-\end{align*}
-
-\end_inset
+\begin_layout Plain Layout
-
-\begin_inset Formula $\square$
+\size footnotesize
+For any
+\begin_inset Formula $F$
\end_inset
\end_layout
-\begin_layout Standard
-With these properties, we get the following examples of type equivalences:
-\begin_inset Formula
-\begin{align*}
- & \exists A.\,A\cong\bbnum 1\quad,\quad\quad\exists A.\,A\rightarrow R\cong\bbnum 1\quad,\quad\quad\exists A.\,A+R\cong\bbnum 1+R\quad,\\
- & \exists A.\,(R\rightarrow A)\times(A\rightarrow S)\cong R\rightarrow S\quad,\quad\quad\exists A.\,(A\rightarrow R)\times A\times A\cong R\times R\quad.
-\end{align*}
-
\end_inset
+ |
+
+\begin_inset Text
+\begin_layout Plain Layout
-\end_layout
-
-\begin_layout Paragraph
-Remarks
-\end_layout
+\size footnotesize
+Example
+\begin_inset space ~
+\end_inset
-\begin_layout Standard
-\series bold
-(1)
-\series default
- The Scala type
-\begin_inset listings
-inline true
-status open
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-simple-existential-derivation"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
-\begin_layout Plain Layout
-Any
\end_layout
\end_inset
+ |
+
+
+|
+\begin_inset Text
- closely corresponds to the type
-\begin_inset Formula $\exists X.\,X$
-\end_inset
+\begin_layout Plain Layout
-, which is equivalent to
-\begin_inset listings
-inline true
-status open
+\size footnotesize
+\begin_inset Formula $\exists A.\,(F^{A}+G^{A})\cong(\exists A.\,F^{A})+(\exists A.\,G^{A})$
+\end_inset
-\begin_layout Plain Layout
-Unit
\end_layout
\end_inset
-
-.
- The advantage of using
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-Any
-\end_layout
-
+\size footnotesize
+For any
+\begin_inset Formula $F$
\end_inset
- instead of
-\begin_inset listings
-inline true
-status open
+,
+\begin_inset Formula $G$
+\end_inset
-\begin_layout Plain Layout
-Unit
\end_layout
\end_inset
-
- is that
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-Any
-\end_layout
-
+\size footnotesize
+Example
+\begin_inset space ~
\end_inset
- is understood by the Scala compiler as a supertype of
-\emph on
-all
-\emph default
- Scala types (while
-\begin_inset listings
-inline true
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-simple-existential-derivation-1-1"
+plural "false"
+caps "false"
+noprefix "false"
-Unit
+\end_inset
+
+(b)
\end_layout
\end_inset
+ |
+
+
+|
+\begin_inset Text
- is not).
- Indeed, for any type
-\begin_inset Formula $T$
-\end_inset
+\begin_layout Plain Layout
- there is an injective function
-\begin_inset Formula $T\rightarrow\exists X.\,X$
+\size footnotesize
+\begin_inset Formula $\exists A.\,\exists B.\,F^{A,B}\cong\exists B.\,\exists A.\,F^{A,B}$
\end_inset
-, which corresponds to a function of type
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-T => Any
\end_layout
\end_inset
-
- in Scala:
-\begin_inset listings
-inline false
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-def toAny[T](t: T): Any = t
+\size footnotesize
+For any
+\begin_inset Formula $F$
+\end_inset
+
+
\end_layout
\end_inset
-
- This is just an identity function that relabels the types.
- So, this function establishes the subtyping relation
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-T <: Any
-\end_layout
-
+\size footnotesize
+Statement
+\begin_inset space ~
\end_inset
-.
-
-\end_layout
-\begin_layout Standard
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-commute-existential"
+plural "false"
+caps "false"
+noprefix "false"
-\series bold
-(2)
-\series default
- The type equivalence
-\begin_inset Formula $\exists X.\,X\cong\bbnum 1$
\end_inset
- may appear counterintuitive.
- The unit type has only one distinct value; but there are infinitely many
- ways of creating a value of type
-\begin_inset Formula $\exists X.\,X$
-\end_inset
-.
- We may take any value
-\begin_inset Formula $t:T$
-\end_inset
+\end_layout
- of any type
-\begin_inset Formula $T$
\end_inset
+ |
+
+
+|
+\begin_inset Text
- and
-\begin_inset Quotes eld
-\end_inset
+\begin_layout Plain Layout
-pack
-\begin_inset Quotes erd
+\size footnotesize
+\begin_inset Formula $\nu A.\,F^{A}\cong\exists A.\,(A\rightarrow F^{A})\times A$
\end_inset
- that value into a value of type
-\begin_inset Formula $\exists X.\,X$
-\end_inset
- by hiding the type
-\begin_inset Formula $T$
-\end_inset
+\end_layout
-, similarly to the function
-\begin_inset listings
-inline true
-status open
+\end_inset
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-toAny
+\size footnotesize
+\begin_inset Formula $F$
+\end_inset
+
+ is any functor
\end_layout
\end_inset
-
-.
-\begin_inset listings
-lstparams "mathescape=true"
-inline false
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-sealed trait ExistsX // Implements the type $
-\backslash
-color{dkgreen}
-\backslash
-exists X.
-\backslash
-,X$.
-\end_layout
+\size footnotesize
+Section
+\begin_inset space ~
+\end_inset
-\begin_layout Plain Layout
-final case class ExistsX0[X](x: X)
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:The-greatest-fixpoints-and-Church-co-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
-\begin_layout Plain Layout
-def hide[T](t: T): ExistsX = ExistsX0[T](t)
\end_layout
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
\begin_layout Plain Layout
-val x1: ExistsX = hide(123)
-\end_layout
+\size footnotesize
+\begin_inset Formula $G^{\nu A.\,F^{A}}\cong\exists A.\,(A\rightarrow F^{A})\times G^{A}$
+\end_inset
-\begin_layout Plain Layout
-val x2: ExistsX = hide(124)
\end_layout
+\end_inset
+ |
+
+\begin_inset Text
+
\begin_layout Plain Layout
-val x3: ExistsX = hide(
-\begin_inset Quotes eld
+\size footnotesize
+\begin_inset Formula $F$
\end_inset
-abc
-\begin_inset Quotes erd
+,
+\begin_inset Formula $G$
\end_inset
-)
+ are any functors
\end_layout
\end_inset
-
-This code may suggest that we are able to create many different values of
- type
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-ExistsX
-\end_layout
-
+\size footnotesize
+Statement
+\begin_inset space ~
\end_inset
-.
- How can it be that
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-ExistsX
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-Church-co-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
- is equivalent to a unit type with a single distinct value? The reason is
- that no fully parametric functions will be able to detect any difference
- between all those values.
- A fully parametric function may pattern-match on
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-ExistsX0(x)
\end_layout
\end_inset
-
- but must treat the type of
-\begin_inset listings
-inline true
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-x
+\size footnotesize
+\begin_inset Formula $\nu A.\,\nu B.\,F^{A,B}\cong\nu B.\,F^{B,B}$
+\end_inset
+
+
\end_layout
\end_inset
-
- as arbitrary and unknown, with no operations available for computing anything
- out of
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-x
+\size footnotesize
+\begin_inset Formula $F$
+\end_inset
+
+ is any bifunctor
\end_layout
\end_inset
-
-.
- So, there will be no way to determine the actual type and value of
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-x
-\end_layout
-
+\size footnotesize
+Statement
+\begin_inset space ~
\end_inset
- and to make any decisions based on them.
- A computer's memory will probably store different bit patterns when representin
-g
-\begin_inset listings
-inline true
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-nested-greatest-fixpoints"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
-hide(123)
\end_layout
\end_inset
+ |
+
+
+|
+\begin_inset Text
- and
-\begin_inset listings
-inline true
-status open
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Note Note
+status collapsed
\begin_layout Plain Layout
-hide(124)
-\end_layout
+\size footnotesize
+See
+\family typewriter
+\size default
-\end_inset
+\begin_inset CommandInset href
+LatexCommand href
+target "https://tex.stackexchange.com/questions/50332/vertical-spacing-of-a-table-cell"
+literal "false"
-.
- But that difference remains unobservable in fully parametric code.
-
-\begin_inset Formula $\square$
\end_inset
\end_layout
-\begin_layout Standard
-We may use Eq.
-\begin_inset space ~
\end_inset
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:existential-via-universal-Yoneda"
-plural "false"
-caps "false"
-noprefix "false"
-\end_inset
+\begin_inset Box Frameless
+position "c"
+hor_pos "c"
+has_inner_box 1
+inner_pos "t"
+use_parbox 0
+use_makebox 0
+width "0.1mm"
+special "none"
+height "12mm"
+height_special "none"
+thickness "0.4pt"
+separation "3pt"
+shadowsize "4pt"
+framecolor "black"
+backgroundcolor "none"
+status collapsed
-) to replace the existential quantifier by the universal one when proving
- properties of existentially quantified types.
-\end_layout
+\begin_layout Plain Layout
-\begin_layout Subsubsection
-Example
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Example-simple-existential-derivation"
+\end_layout
\end_inset
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Example-simple-existential-derivation"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_inset Box Frameless
+position "c"
+hor_pos "c"
+has_inner_box 1
+inner_pos "c"
+use_parbox 0
+use_makebox 0
+width "43col%"
+special "none"
+height "1in"
+height_special "totalheight"
+thickness "0.4pt"
+separation "3pt"
+shadowsize "4pt"
+framecolor "black"
+backgroundcolor "none"
+status collapsed
+
+\begin_layout Plain Layout
+\align center
+\size footnotesize
+\begin_inset Formula $\nu A.\,F^{A,\,\nu B.\,G^{A,B}}\cong$
\end_inset
-\begin_inset Index idx
-status open
+\begin_inset Newline newline
+\end_inset
+
+
+\begin_inset Formula $\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times A$
+\end_inset
+
-\begin_layout Plain Layout
-examples
\end_layout
\end_inset
@@ -48690,320 +51884,288 @@ examples
\end_layout
-\begin_layout Standard
-Show that
-\begin_inset Formula $\exists A.\,F^{A}\rightarrow A\cong\bbnum 1$
\end_inset
+ |
+
+\begin_inset Text
- for any type constructor
+\begin_layout Plain Layout
+
+\size footnotesize
\begin_inset Formula $F$
\end_inset
-.
-\end_layout
+,
+\begin_inset Formula $G$
+\end_inset
-\begin_layout Subparagraph
-Solution
+ are any bifunctors
\end_layout
-\begin_layout Standard
-Use Eq.
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+Statement
\begin_inset space ~
\end_inset
-(
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:existential-via-universal-Yoneda"
+reference "subsec:Statement-mutually-recursive-greatest-fixpoints"
plural "false"
caps "false"
noprefix "false"
\end_inset
-) and write:
-\begin_inset Formula
-\[
-\exists A.\,F^{A}\rightarrow A=\forall B.\,(\forall A.\,(F^{A}\rightarrow A)\rightarrow B)\rightarrow B\quad.
-\]
+
+\end_layout
\end_inset
+ |
+
+
+|
+\begin_inset Text
-Statement
-\begin_inset space ~
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $G^{\exists C.\,F^{C}}\cong\forall D.\,(\forall C.\,F^{C}\rightarrow D)\rightarrow G^{D}$
\end_inset
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-application-full-relation"
-plural "false"
-caps "false"
-noprefix "false"
+\end_layout
\end_inset
+ |
+
+\begin_inset Text
- with
-\begin_inset Formula $P^{A}\triangleq F^{A}\rightarrow A$
+\begin_layout Plain Layout
+
+\size footnotesize
+Any
+\begin_inset Formula $F$
\end_inset
- and
-\begin_inset Formula $K\triangleq B$
+, any functor
+\begin_inset Formula $G$
\end_inset
- shows that
-\begin_inset Formula $\forall A.\,(F^{A}\rightarrow A)\rightarrow B\cong B$
-\end_inset
- as the type constructor
-\begin_inset Formula $F^{A}\rightarrow A$
-\end_inset
+\end_layout
- is
-\begin_inset Quotes eld
\end_inset
+ |
+
+\begin_inset Text
-lifting-to-full
-\begin_inset Quotes erd
-\end_inset
+\begin_layout Plain Layout
- by Statement
+\size footnotesize
+Exercise
\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-undisjunctive-type-constructors-structural"
+reference "par:Exercise-additional-16-3"
plural "false"
caps "false"
noprefix "false"
\end_inset
-(c, d).
- So, we get:
-\begin_inset Formula
-\[
-\exists A.\,F^{A}\rightarrow A=\forall B.\,B\rightarrow B\cong\bbnum 1\quad.
-\]
+
+\end_layout
+
+\end_inset
+ |
+
+
\end_inset
\end_layout
-\begin_layout Subsubsection
-Example
+\begin_layout Plain Layout
+\begin_inset Caption Standard
+
+\begin_layout Plain Layout
+Type isomorphisms for existential types.
\begin_inset CommandInset label
LatexCommand label
-name "subsec:Example-simple-existential-derivation-1-1"
+name "tab:Type-identities-for-existential-types"
\end_inset
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Example-simple-existential-derivation-1-1"
-plural "false"
-caps "false"
-noprefix "false"
+\end_layout
\end_inset
\end_layout
-\begin_layout Standard
-Let
-\begin_inset Formula $P$
\end_inset
- and
-\begin_inset Formula $Q$
-\end_inset
- be any type constructors.
+\end_layout
+
+\begin_layout Subsection
+The Jaskelioff-O'Connor theorem for simple types
\end_layout
\begin_layout Standard
+The Jaskelioff-O'Connor theorem
+\begin_inset Foot
+status open
-\series bold
-(a)
-\series default
- If
-\begin_inset Formula $P^{A}\cong Q^{A}$
-\end_inset
+\begin_layout Plain Layout
+See
+\family typewriter
- for all
-\begin_inset Formula $A$
-\end_inset
+\begin_inset CommandInset href
+LatexCommand href
+target "https://arxiv.org/abs/1402.1699"
+literal "false"
- then
-\begin_inset Formula $\exists A.\,P^{A}\cong\exists A.\,Q^{A}$
\end_inset
-.
-\end_layout
-\begin_layout Standard
+\end_layout
-\series bold
-(b)
-\series default
- For arbitrary
-\begin_inset Formula $P$
\end_inset
- and
-\begin_inset Formula $Q$
+ is a type equivalence between certain type constructors quantified over
+ a typeclass.
+ This section proves a version of that theorem that holds for simple types
+ belonging to an
+\begin_inset Formula $FM$
\end_inset
-:
-\begin_inset Formula
-\[
-\exists A.\,P^{A}+Q^{A}\cong(\exists A.\,P^{A})+(\exists A.\,Q^{A})\quad.
-\]
-
+-typeclass.
+ Then the theorem gives a general type formula for the free construction
+ of any
+\begin_inset Formula $FM$
\end_inset
-
+-typeclass.
\end_layout
-\begin_layout Standard
-
-\series bold
-(c)
-\series default
- Show that following type identities do
-\emph on
-not
-\emph default
- hold in general:
-\begin_inset Formula
-\begin{align*}
- & \exists A.\,P^{A}\times Q^{A}\not\cong(\exists A.\,P^{A})\times(\exists A.\,Q^{A})\quad,\\
- & R\rightarrow(\exists A.\,P^{A})\not\cong\exists A.\,R\rightarrow P^{A}\quad.
-\end{align*}
-
-\end_inset
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-JOC-theorem-simple-types"
-(Similar identities do hold for the universal quantifiers; see Statement
-\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-general-identities-forall"
+reference "subsec:Statement-JOC-theorem-simple-types"
plural "false"
caps "false"
noprefix "false"
\end_inset
-.)
-\end_layout
-\begin_layout Subparagraph
-Solution
\end_layout
\begin_layout Standard
-
-\series bold
-(a)
-\series default
- Suppose we have an isomorphism:
-\begin_inset Formula
-\[
-f^{A}:P^{A}\rightarrow Q^{A}\quad,\quad\quad g^{A}:Q^{A}\rightarrow P^{A}\quad.
-\]
-
+The free
+\begin_inset Formula $FM$
\end_inset
-The types
-\begin_inset Formula $\exists A.\,P^{A}$
+-typeclass instance
+\begin_inset Formula $E^{T}$
\end_inset
- and
-\begin_inset Formula $\exists A.\,Q^{A}$
+ generated by a type
+\begin_inset Formula $T$
\end_inset
- are equivalent to some type expressions involving only universal quantifiers
- and the type constructors
-\begin_inset Formula $P$
-\end_inset
+ is equivalent to the type defined by:
+\begin_inset Formula
+\begin{equation}
+E^{T}\cong\forall(A\in P\text{-typeclass}).\,(T\rightarrow A)\rightarrow A\quad.\label{eq:free-typeclass-via-church-encoding}
+\end{equation}
-,
-\begin_inset Formula $Q$
\end_inset
-.
-\begin_inset Formula
-\begin{align*}
- & \exists A.\,P^{A}\cong\exists A.\,Q^{A}\\
-\text{is the same as}:\quad & \forall D.\,(\forall A.\,P^{A}\rightarrow D)\rightarrow D\cong\forall D.\,(\forall A.\,Q^{A}\rightarrow D)\rightarrow D\quad.
-\end{align*}
+Here the quantifier goes only over the types
+\begin_inset Formula $A$
+\end_inset
+ that belong to the
+\begin_inset Formula $FM$
\end_inset
-Then we can apply Statement
+-typeclass.
+ It is also assumed that the type in the right-hand side of Eq.
\begin_inset space ~
\end_inset
-
+(
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-isomorphism-under-type-constructor"
+reference "eq:free-typeclass-via-church-encoding"
plural "false"
caps "false"
noprefix "false"
\end_inset
- repeatedly to show that those type expressions are isomorphic as types:
-\begin_inset Formula
-\begin{align*}
- & \forall A.\,P^{A}\rightarrow D\cong\forall A.\,Q^{A}\rightarrow D\quad,\\
- & (\forall A.\,P^{A}\rightarrow D)\rightarrow D\cong(\forall A.\,Q^{A}\rightarrow D)\rightarrow D\quad,\\
- & \forall D.\,(\forall A.\,P^{A}\rightarrow D)\rightarrow D\cong\forall D.\,(\forall A.\,Q^{A}\rightarrow D)\rightarrow D\quad.
-\end{align*}
-
+) admits only functions that satisfy the naturality law with respect to
+
+\begin_inset Formula $A$
\end_inset
+.
+\end_layout
+\begin_layout Subparagraph
+Proof
\end_layout
\begin_layout Standard
+One of the defining properties of the free typeclass constructor
+\begin_inset Formula $E$
+\end_inset
-\series bold
-(b)
-\series default
- Use Eq.
-\begin_inset space ~
+ is the one-to-one correspondence between functions of type
+\begin_inset Formula $T\rightarrow A$
\end_inset
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:existential-via-universal-Yoneda"
-plural "false"
-caps "false"
-noprefix "false"
+ and
+\begin_inset Formula $FM$
+\end_inset
+-typeclass morphisms of type
+\begin_inset Formula $E^{T}\rightarrow A$
\end_inset
-) and write:
+.
+ Denoting by
+\begin_inset Formula $E^{T}\overset{P}{\rightarrow}A$
+\end_inset
+
+ the type of those morphisms, we have:
\begin_inset Formula
-\begin{align*}
- & \exists A.\,P^{A}+Q^{A}=\forall B.\,(\forall A.\,\gunderline{P^{A}+Q^{A}\rightarrow B})\rightarrow B\\
- & =\forall B.\,(\forall A.\,(P^{A}\rightarrow B)\times(Q^{A}\rightarrow B))\rightarrow B\\
- & =\forall B.\,(\gunderline{\forall A.\,P^{A}\rightarrow B})\times(\gunderline{\forall A.\,Q^{A}\rightarrow B})\rightarrow B\\
-\text{use Eq.\,(\ref{eq:existential-via-universal})}:\quad & =\forall B.\,(\gunderline{(\exists A.\,P^{A})\rightarrow B)\times((\exists A.\,Q^{A})\rightarrow B})\rightarrow B\\
- & =\forall B.\,\big((\exists A.\,P^{A})+(\exists A.\,Q^{A})\,\gunderline{\rightarrow B\big)\rightarrow B}\\
-\text{Yoneda identity}:\quad & =(\exists A.\,P^{A})+(\exists A.\,Q^{A})\quad.
-\end{align*}
+\[
+\forall(A\in P\text{-typeclass}).\,(T\rightarrow A)\rightarrow A\cong\forall(A\in P\text{-typeclass}).\,(E^{T}\overset{P}{\rightarrow}A)\rightarrow A\quad.
+\]
\end_inset
@@ -49011,336 +52173,352 @@ noprefix "false"
\end_layout
\begin_layout Standard
+All types
+\begin_inset Formula $A$
+\end_inset
-\series bold
-(c)
-\series default
- The first counter-example is found via the co-Yoneda identity itself:
+ belonging to the
+\begin_inset Formula $FM$
+\end_inset
+
+-typeclass are
+\begin_inset Formula $E$
+\end_inset
+
+-monad algebras, and those algebras form a category.
+ Now we use the Yoneda identity in that category:
\begin_inset Formula
\[
-\exists A.\,(A\rightarrow R)\times F^{A}\cong F^{R}\quad.
+\forall(A\in P\text{-typeclass}).\,(X\overset{P}{\rightarrow}A)\rightarrow A\cong X\quad,
\]
\end_inset
-Splitting the left-hand side into a product of two existential types, we
- get:
+where
+\begin_inset Formula $X$
+\end_inset
+
+ is any fixed type that also belongs to the
+\begin_inset Formula $FM$
+\end_inset
+
+-typeclass.
+ We use this identity with
+\begin_inset Formula $X=E^{T}$
+\end_inset
+
+ and obtain:
\begin_inset Formula
\[
-(\exists A.\,(A\rightarrow R))\times(\exists A.\,F^{A})\cong\bbnum 1\times F^{\bbnum 1}\cong F^{\bbnum 1}\quad.
+\forall(A\in P\text{-typeclass}).\,(E^{T}\overset{P}{\rightarrow}A)\rightarrow A\cong E^{T}\quad,
\]
\end_inset
-But the last type is not equivalent to
-\begin_inset Formula $F^{R}$
+as required.
+
+\begin_inset Formula $\square$
\end_inset
-.
+
+\end_layout
+
+\begin_layout Subsection
+The Jaskelioff-O'Connor theorem for type constructors
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:The-Jaskelioff-OConnor-theorem"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
-The second counter-example is with the following type:
-\begin_inset Formula
-\[
-P^{A}\triangleq(A\rightarrow Q)\times A\quad.
-\]
+The full formulation of the theorem involves functor typeclasses instead
+ of typeclasses for simple types.
+ The theorem applies to all
+\begin_inset Formula $FM$
+\end_inset
+-typeclasses for functors.
+ Those typeclasses have method signatures of the form
+\begin_inset Formula $\forall A.\,(P^{F})^{A}\rightarrow F^{A}$
\end_inset
-Here
-\begin_inset Formula $Q$
+, where
+\begin_inset Formula $P$
\end_inset
- is a fixed type.
- By the co-Yoneda identity, we have
-\begin_inset Formula $\exists A.\,P^{A}\cong Q$
+ is a functor on functors (the kind of
+\begin_inset Formula $P$
\end_inset
- and so
-\begin_inset Formula $R\rightarrow(\exists A.\,P^{A})\cong R\rightarrow Q$
+ is
+\begin_inset Formula $(*\rightarrow*)\rightarrow*\rightarrow*$
\end_inset
-.
- Now let us simplify the other side:
-\begin_inset Formula
-\begin{align*}
- & \exists A.\,R\rightarrow P^{A}=\exists A.\,R\rightarrow(A\rightarrow Q)\times A\\
- & \quad\cong\exists A.\,(R\rightarrow A\rightarrow Q)\times(R\rightarrow A)\\
-\text{co-Yoneda identity}:\quad & \quad\cong R\rightarrow R\rightarrow Q\quad.
-\end{align*}
+) and functions of type
+\begin_inset Formula $(P^{F})^{A}\rightarrow F^{A}$
+\end_inset
+ are restricted to natural transformations between functors
+\begin_inset Formula $P^{F}$
\end_inset
-The last type is not equivalent to
-\begin_inset Formula $R\rightarrow Q$
+ and
+\begin_inset Formula $F$
\end_inset
.
-
-\begin_inset Formula $\square$
+ Examples of well-known
+\begin_inset Formula $FM$
\end_inset
-
+-typeclasses of that form are pointed functors, filterable functors, applicative
+ functors, and monads.
\end_layout
\begin_layout Subsubsection
Statement
\begin_inset CommandInset label
LatexCommand label
-name "subsec:Statement-commute-existential"
+name "subsec:Statement-Jaskelioff-OConnor"
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-commute-existential"
+reference "subsec:Statement-Jaskelioff-OConnor"
plural "false"
caps "false"
noprefix "false"
\end_inset
-(co-Fubini theorem)
+ (Jaskelioff-O'Connor)
\end_layout
\begin_layout Standard
-For any type constructor
-\begin_inset Formula $P$
+Given any fixed
+\begin_inset Formula $FM$
\end_inset
- with two parameters (not necessarily covariant or contravariant):
-\begin_inset Formula
-\[
-\exists A.\,\exists B.\,P^{A,B}\cong\exists B.\,\exists A.\,P^{A,B}\quad.
-\]
-
+-typeclass for functors, denote by
+\begin_inset Formula $E$
\end_inset
-
-\end_layout
-
-\begin_layout Subparagraph
-Proof
-\end_layout
-
-\begin_layout Standard
-We rewrite
-\begin_inset Formula $\exists A.\,\exists B.\,P^{A,B}$
+ the constructor of free instances of that typeclass: if
+\begin_inset Formula $T$
\end_inset
- via universal quantifiers:
-\begin_inset Formula
-\begin{align*}
- & \gunderline{\exists A.}\,\exists B.\,P^{A,B}\\
-\text{use Eq.\,(\ref{eq:existential-via-universal-Yoneda})}:\quad & \cong\forall D.\,\big(\forall A.\,\gunderline{(\exists B.\,P^{A,B})\rightarrow D})\rightarrow D\\
-\text{use Eq.\,(\ref{eq:existential-via-universal})}:\quad & \cong\forall D.\,\big(\forall A.\,\forall B.\,P^{A,B}\rightarrow D)\rightarrow D\quad.
-\end{align*}
-
+ is any functor then the functor
+\begin_inset Formula $E^{T}$
\end_inset
-If we rewrite
-\begin_inset Formula $\exists B.\,\exists A.\,P^{A,B}$
+ is an instance of the
+\begin_inset Formula $FM$
\end_inset
- similarly, we will get:
-\begin_inset Formula
-\[
-\exists B.\,\exists A.\,P^{A,B}\cong\forall D.\,\big(\forall B.\,\forall A.\,P^{A,B}\rightarrow D)\rightarrow D\quad.
-\]
-
+-typeclass satisfying the properties of free typeclass constructors.
+ Suppose
+\begin_inset Formula $A$
\end_inset
-Statement
-\begin_inset space ~
+,
+\begin_inset Formula $B$
\end_inset
+,
+\begin_inset Formula $C$
+\end_inset
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-Fubini-theorem"
-plural "false"
-caps "false"
-noprefix "false"
+ are some fixed types.
+ Then the following type equivalence holds:
+\begin_inset Formula
+\begin{align}
+ & \forall(F\in P\text{-typeclass}).\,(A\rightarrow F^{B})\rightarrow F^{C}\cong(E^{R})^{C}\quad,\label{eq:jaskelioff-o-connor-theorem}\\
+\text{where }R\text{ is defined by}:\quad & R^{T}\triangleq A\times(B\rightarrow T)\quad.\nonumber
+\end{align}
\end_inset
- gives
-\begin_inset Formula $\forall A.\,\forall B.\,P^{A,B}\cong\forall B.\,\forall A.\,P^{A,B}$
+Here, it is assumed that the type
+\begin_inset Formula $(A\rightarrow F^{B})\rightarrow F^{C}$
\end_inset
-, completing the proof.
-
-\begin_inset Formula $\square$
+ is restricted to functions satisfying the
+\begin_inset Formula $FM$
\end_inset
+-typeclass naturality law with respect to
+\begin_inset Formula $F$
+\end_inset
+.
\end_layout
-\begin_layout Standard
-Now we will prove some more technical properties of existential types.
+\begin_layout Subparagraph
+Proof
\end_layout
\begin_layout Standard
-In the next two statements, we work with a fixed type constructor
-\begin_inset Formula $P$
+Denote by
+\begin_inset Formula $K\overset{P}{\rightarrow}L$
\end_inset
-, which is not assumed to be covariant or contravariant.
- For brevity, we denote:
-\begin_inset Formula
-\[
-E\triangleq\forall B.\,(\forall A.\,P^{A}\rightarrow B)\rightarrow B\quad.
-\]
-
+ the type of
+\begin_inset Formula $FM$
\end_inset
+-typeclass morphisms between functors
+\begin_inset Formula $K$
+\end_inset
-\end_layout
+ and
+\begin_inset Formula $L$
+\end_inset
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-identity-law-of-pack"
+ that belong to the typeclass.
+ (The full type signature of an
+\begin_inset Formula $FM$
+\end_inset
+-typeclass morphism is
+\begin_inset Formula $\forall A.\,K^{A}\overset{P}{\rightarrow}L^{A}$
\end_inset
+.)
+\end_layout
+
+\begin_layout Standard
+We will prove the type equivalence
+\begin_inset space ~
+\end_inset
+(
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-identity-law-of-pack"
+reference "eq:jaskelioff-o-connor-theorem"
plural "false"
caps "false"
noprefix "false"
\end_inset
-
+) in three steps.
\end_layout
\begin_layout Standard
-Values of type
-\begin_inset Formula $E$
-\end_inset
-
- are constructed via the standard function
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-pack
-\end_layout
+\series bold
+(1)
+\series default
+ Use the Yoneda identity to obtain this type equivalence:
+\begin_inset Formula
+\[
+A\rightarrow F^{B}\cong\forall X.\,R^{X}\rightarrow F^{X}\quad.
+\]
\end_inset
- that has the following type signature:
+To derive this formula, write:
\begin_inset Formula
\begin{align*}
- & \text{pack}:\forall T.\,P^{T}\rightarrow E\quad,\\
-\text{or equivalently}:\quad & \text{pack}:\forall T.\,P^{T}\rightarrow\forall B.\,(\forall A.\,P^{A}\rightarrow B)\rightarrow B\quad,\\
- & \text{pack}^{T}(p^{:P^{T}})\triangleq\forall B.\,\big(k^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow k^{T}(p)\quad.
+ & A\rightarrow F^{B}\\
+\text{covariant Yoneda identity}:\quad & \cong A\rightarrow\forall X.\,(B\rightarrow X)\rightarrow F^{X}\\
+\text{move }\forall X\text{ to front}:\quad & \cong\forall X.\,A\rightarrow(B\rightarrow X)\rightarrow F^{X}\\
+\text{uncurry the function}:\quad & \cong\forall X.\,A\times(B\rightarrow X)\rightarrow F^{X}=\forall X.\,R^{X}\rightarrow F^{X}\quad.
\end{align*}
\end_inset
-Then the
-\series bold
-identity law
-\series default
- of
-\begin_inset Index idx
-status open
-
-\begin_layout Plain Layout
-identity laws!of
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
+In the first line of this derivation, we have used the assumption that
+\begin_inset Formula $F$
+\end_inset
-pack
+ is a (covariant) functor.
\end_layout
+\begin_layout Standard
+
+\series bold
+(2)
+\series default
+ By the universal property of the free
+\begin_inset Formula $FM$
\end_inset
+-typeclass runner, for any functor
+\begin_inset Formula $F$
+\end_inset
-\end_layout
-
+ that belongs to the
+\begin_inset Formula $FM$
\end_inset
-
-\begin_inset listings
-inline true
-status open
+-typeclass and for any functor
+\begin_inset Formula $R$
+\end_inset
-\begin_layout Plain Layout
+ (not necessarily a member of the
+\begin_inset Formula $FM$
+\end_inset
-pack
-\end_layout
+-typeclass) there is a one-to-one correspondence between
+\begin_inset Formula $FM$
+\end_inset
+-typeclass morphisms
+\begin_inset Formula $E^{R}\overset{P}{\rightarrow}F$
\end_inset
- holds: for any value
-\begin_inset Formula $e:E$
+ and natural transformations
+\begin_inset Formula $R\leadsto F$
\end_inset
-,
+.
+ In other words, there is a type equivalence between the following types
+ (where we wrote out the full type signatures):
\begin_inset Formula
-\begin{equation}
-e^{E}(\text{pack})=e\quad.\label{eq:identity-law-of-pack}
-\end{equation}
+\[
+\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X}\cong\forall X.\,R^{X}\rightarrow F^{X}\quad.
+\]
\end_inset
-It is assumed that all values
-\begin_inset Formula $e^{:E}$
+Now we set
+\begin_inset Formula $R^{T}\triangleq A\times(B\rightarrow T)$
\end_inset
- obey their naturality law:
+ and obtain:
\begin_inset Formula
-\begin{equation}
-\text{for all }f^{:B\rightarrow C},k^{:\forall A.\,P^{A}\rightarrow B}:\quad f(e^{B}(k))=e^{C}(\forall A.\,k^{A}\bef f)\quad.\label{eq:naturality-law-of-e-derivation1}
-\end{equation}
+\[
+(A\rightarrow F^{B})\rightarrow F^{C}\cong(\forall X.\,R^{X}\rightarrow F^{X})\rightarrow F^{C}\cong(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\quad.
+\]
\end_inset
-
-\end_layout
-
-\begin_layout Subparagraph
-Proof
-\begin_inset Foot
-status open
-
-\begin_layout Plain Layout
-The author thanks
-\begin_inset Index idx
-status open
-
-\begin_layout Plain Layout
-Dan Doel
-\end_layout
-
+So, the left-hand side of Eq.
+\begin_inset space ~
\end_inset
-Dan Doel for assistance with the proof of this statement.
- See the discussion at
-\family typewriter
-
-\begin_inset CommandInset href
-LatexCommand href
-target "https://cstheory.stackexchange.com/questions/54124"
-literal "false"
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:jaskelioff-o-connor-theorem"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
-
-\end_layout
+) is equivalent to:
+\begin_inset Formula
+\[
+\forall(F\in P\text{-typeclass}).\,(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\quad.
+\]
\end_inset
@@ -49348,293 +52526,298 @@ literal "false"
\end_layout
\begin_layout Standard
-Both sides of Eq.
+
+\series bold
+(3)
+\series default
+ We use the covariant Yoneda identity in the category of functors that belong
+ to the
+\begin_inset Formula $FM$
+\end_inset
+
+-typeclass.
+ As we have found in Section
\begin_inset space ~
\end_inset
-(
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:identity-law-of-pack"
+reference "subsec:Imposing-laws-of-P-typeclasses-via-monad-algebras"
plural "false"
caps "false"
noprefix "false"
\end_inset
-) have type
-\begin_inset Formula $E$
-\end_inset
-
-.
- Since
+, all those functors are
\begin_inset Formula $E$
\end_inset
- is a type of functions with a type parameter, the two sides can be applied
- to an arbitrary type
-\begin_inset Formula $U$
-\end_inset
-
- and an arbitrary value
-\begin_inset Formula $u:\forall A.\,P^{A}\rightarrow U$
+-monad algebras, which form a category.
+ The
+\begin_inset Formula $FM$
\end_inset
- to get two values of type
-\begin_inset Formula $U$
+-typeclass morphisms are in one-to-one correspondence with the
+\begin_inset Formula $E$
\end_inset
-:
+-monad algebra morphisms.
+ Therefore, we may write the covariant Yoneda identity for that category
+ as:
\begin_inset Formula
-\begin{align*}
-\text{both sides of}:\quad & e^{E}(\text{pack})\overset{?}{=}e\\
-\text{can be applied to }U\text{ and }u\text{ and yield}:\quad & \big(e^{E}(\text{pack})\big)^{U}(u)\overset{?}{=}e^{U}(u)\quad.
-\end{align*}
+\[
+\forall(F\in P\text{-typeclass}).\,(\forall X.\,Q^{X}\overset{P}{\rightarrow}F^{X})\rightarrow S^{F}\cong S^{Q}\quad,
+\]
\end_inset
+where
+\begin_inset Formula $Q$
+\end_inset
-\end_layout
-
-\begin_layout Standard
-So, let us prove that for all types
-\begin_inset Formula $U$
+ is any fixed functor from the
+\begin_inset Formula $FM$
\end_inset
- and all values
-\begin_inset Formula $u:\forall A.\,P^{A}\rightarrow U$
+-typeclass,
+\begin_inset Formula $S^{F}$
\end_inset
-,
-\begin_inset Formula
-\begin{equation}
-\big(e^{E}(\text{pack})\big)^{U}(u)\overset{?}{=}e^{U}(u)\quad.\label{eq:identity-law-of-pack-derivation1}
-\end{equation}
+ is any type expression that is covariant in
+\begin_inset Formula $F$
+\end_inset
+, and the naturality law with respect to
+\begin_inset Formula $F$
\end_inset
-To prove the last equation, we will rewrite it in the form of the naturality
- law
-\begin_inset space ~
+ is assumed to hold.
+ We will use this Yoneda identity with
+\begin_inset Formula $Q=E^{R}$
\end_inset
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:naturality-law-of-e-derivation1"
-plural "false"
-caps "false"
-noprefix "false"
+, and set
+\begin_inset Formula $S^{F}$
+\end_inset
+ to just
+\begin_inset Formula $F^{C}$
\end_inset
-) by finding suitable parameters
-\begin_inset Formula $B$
+ (the application of
+\begin_inset Formula $F$
\end_inset
-,
+ to the fixed type
\begin_inset Formula $C$
\end_inset
-,
-\begin_inset Formula $f$
-\end_inset
+).
+ Then we get:
+\begin_inset Formula
+\[
+\forall(F\in P\text{-typeclass}).\,(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\cong(E^{R})^{C}\quad.
+\]
-, and
-\begin_inset Formula $k$
\end_inset
-.
- Once we manage to do that, the proof of Eq.
+The last type is the right-hand side of Eq.
\begin_inset space ~
\end_inset
(
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:identity-law-of-pack"
+reference "eq:jaskelioff-o-connor-theorem"
plural "false"
caps "false"
noprefix "false"
\end_inset
-) will be completed.
-
-\end_layout
-
-\begin_layout Standard
-The left-hand side of Eq.
+).
+ So, Eq.
\begin_inset space ~
\end_inset
(
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:identity-law-of-pack-derivation1"
+reference "eq:jaskelioff-o-connor-theorem"
plural "false"
caps "false"
noprefix "false"
\end_inset
-) will match the left-hand side of Eq.
+) holds.
+\end_layout
+
+\begin_layout Standard
+Let us now derive the code that implements the type equivalence
\begin_inset space ~
\end_inset
(
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:naturality-law-of-e-derivation1"
+reference "eq:jaskelioff-o-connor-theorem"
plural "false"
caps "false"
noprefix "false"
\end_inset
-) if we assign
-\begin_inset Formula $B=E$
-\end_inset
-
-,
-\begin_inset Formula $k=\text{pack}$
-\end_inset
-
-, and
-\begin_inset Formula $f(e)\triangleq e^{U}(u)$
-\end_inset
-
-.
- The type of
-\begin_inset Formula $f$
-\end_inset
-
- must be
-\begin_inset Formula $B\rightarrow C$
-\end_inset
-
-; since
-\begin_inset Formula $f(e)$
-\end_inset
-
- has type
-\begin_inset Formula $U$
-\end_inset
-
-, we need to set
-\begin_inset Formula $C=U$
+) in the direction of right-to-left.
+ Suppose we are given a value
+\begin_inset Formula $q$
\end_inset
-.
- With these assignments, the right-hand side of Eq.
+ of the type in the right-hand side of Eq.
\begin_inset space ~
\end_inset
(
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:naturality-law-of-e-derivation1"
+reference "eq:jaskelioff-o-connor-theorem"
plural "false"
caps "false"
noprefix "false"
\end_inset
-) becomes:
+):
\begin_inset Formula
\[
-e^{C}(k\bef f)=e^{U}(\forall A.\,\text{pack}^{A}\bef f)\quad.
+q:(E^{R})^{C}\quad.
\]
\end_inset
-This will be equal to the right-hand side
-\begin_inset Formula $e^{U}(u)$
+We need to retrace step
+\series bold
+(3)
+\series default
+ above and convert this
+\begin_inset Formula $q$
\end_inset
- of Eq.
-\begin_inset space ~
+ to a function
+\begin_inset Formula $f$
\end_inset
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:identity-law-of-pack-derivation1"
-plural "false"
-caps "false"
-noprefix "false"
+ of type:
+\begin_inset Formula
+\[
+f:\forall(F\in P\text{-typeclass}).\,(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\quad.
+\]
\end_inset
-) if we show that:
+The required function
+\begin_inset Formula $f$
+\end_inset
+
+ is defined by:
\begin_inset Formula
\[
-\forall A.\,\text{pack}^{A}\bef f\overset{?}{=}u\quad.
+f^{F}\big(k^{:\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X}}\big)\triangleq k^{C}(q)\quad.
\]
\end_inset
-Substitute the definitions of
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-pack
\end_layout
+\begin_layout Standard
+Continue by retracing step
+\series bold
+(2)
+\series default
+, converting
+\begin_inset Formula $f$
\end_inset
- and
-\begin_inset Formula $f$
+ to a function
+\begin_inset Formula $g$
\end_inset
-, renaming
-\begin_inset Formula $A$
+ of type:
+\begin_inset Formula
+\[
+g:\forall(F\in P\text{-typeclass}).\,(\forall X.\,R^{X}\rightarrow F^{X})\rightarrow F^{C}\quad.
+\]
+
\end_inset
- to
-\begin_inset Formula $T$
+The function
+\begin_inset Formula $g$
\end_inset
-:
+ is defined by:
\begin_inset Formula
\[
-\forall T.\,\text{pack}^{T}\bef f=\forall T.\,p^{:P^{T}}\rightarrow f\big(\forall B.\,\big(q^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow q^{T}(p)\big)\quad.
+g^{F}\big(k^{:\forall X.\,R^{X}\rightarrow F^{X}}\big)\triangleq f^{F}\big(\forall Y.\,r^{:(E^{R})^{Y}}\rightarrow\text{run}_{E}^{R,Y}(k)(r)\big)\quad,
\]
\end_inset
-The function
-\begin_inset Formula $f$
+where the universal runner (
+\begin_inset Formula $\text{run}_{E}^{T,Y}$
\end_inset
- substitutes
-\begin_inset Formula $B=U$
+) has type:
+\begin_inset Formula
+\[
+\text{run}_{E}^{T,Y}:(\forall X.\,T^{X}\rightarrow F^{X})\rightarrow(E^{T})^{Y}\rightarrow F^{Y}\quad.
+\]
+
\end_inset
- and
-\begin_inset Formula $q=u$
+
+\end_layout
+
+\begin_layout Standard
+It remains to retrace step
+\series bold
+(1)
+\series default
+ and define a function
+\begin_inset Formula $h$
\end_inset
- into its function parameter:
+ of type:
\begin_inset Formula
\[
-f\big(\forall B.\,\big(q^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow q^{T}(p)\big)=\big(\forall B.\,\big(q^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow q^{T}(p)\big)^{U}(u)=u^{T}(p)\quad.
+h:\forall(F\in P\text{-typeclass}).\,(A\rightarrow F^{B})\rightarrow F^{C}\quad.
\]
\end_inset
-So, we find:
+We implement
+\begin_inset Formula $h$
+\end_inset
+
+ via this code:
\begin_inset Formula
\[
-\forall T.\,\text{pack}^{T}\bef f=\forall T.\,p^{:P^{T}}\rightarrow u^{T}(p)=\forall T.\,u^{T}=u\quad.
+h^{F}(k^{:A\rightarrow F^{B}})\triangleq g^{F}\big(\forall X.\,a^{:A}\times t^{:B\rightarrow X}\rightarrow k(a)\triangleright t^{\uparrow F}\big)\quad.
\]
\end_inset
-This completes the proof.
+This completes the code that transforms
+\begin_inset Formula $q$
+\end_inset
+
+ into
+\begin_inset Formula $h$
+\end_inset
+
+.
\begin_inset Formula $\square$
\end_inset
@@ -49643,176 +52826,228 @@ This completes the proof.
\end_layout
\begin_layout Standard
-Finally, here is the key property required for proving the equivalence of
- two formulations of existential types, Eq.
-\begin_inset space ~
+We will now apply the Jaskelioff-O'Connor theorem to prove some useful type
+ equivalences.
+\end_layout
+
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-identity-monad-morphism"
+
\end_inset
-(
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:existential-via-universal"
+reference "subsec:Statement-identity-monad-morphism"
plural "false"
caps "false"
noprefix "false"
\end_inset
-) and Eq.
-\begin_inset space ~
+
+\end_layout
+
+\begin_layout Standard
+Denote by
+\begin_inset Formula $F\xrightarrow{\text{Monad}}G$
\end_inset
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:existential-via-universal-Yoneda"
-plural "false"
-caps "false"
-noprefix "false"
+ (more verbosely,
+\begin_inset Formula $\forall X.\,F^{X}\xrightarrow{\text{Monad}}G^{X}$
+\end_inset
+
+) the type of monad morphisms between monads
+\begin_inset Formula $F$
+\end_inset
+
+ and
+\begin_inset Formula $G$
+\end_inset
+.
+ Those are natural transformations of type
+\begin_inset Formula $\forall X.\,F^{X}\rightarrow G^{X}$
+\end_inset
+
+ that additionally satisfy the laws of monad morphisms.
+ Denote by
+\begin_inset Formula $\text{Id}$
+\end_inset
+
+ the identity monad (
+\begin_inset Formula $\text{Id}^{A}\triangleq A$
\end_inset
).
+
\end_layout
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-function-extension-rule"
+\begin_layout Standard
+\series bold
+(a)
+\series default
+ The standard monad method
+\begin_inset Formula $\text{pu}_{M}:\forall A.\,A\rightarrow M^{A}$
\end_inset
+ is the only monad morphism of type
+\begin_inset Formula $\text{Id}\xrightarrow{\text{Monad}}M$
+\end_inset
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-function-extension-rule"
-plural "false"
-caps "false"
-noprefix "false"
+ that works in the same way for all monads
+\begin_inset Formula $M$
+\end_inset
+
+.
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+See
+\family typewriter
+
+\begin_inset CommandInset href
+LatexCommand href
+target "https://cstheory.stackexchange.com/questions/53389/"
+literal "false"
+
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+ We can express this as a type equivalence:
+\begin_inset Formula
+\[
+\forall M^{:\text{Monad}}.\,\text{Id}\xrightarrow{\text{Monad}}M\cong\bbnum 1\quad.
+\]
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(b)
+\series default
+ The identity function of type
+\begin_inset Formula $\forall X.\,M^{X}\rightarrow M^{X}$
+\end_inset
+
+ is the only monad morphism of type
+\begin_inset Formula $M\xrightarrow{\text{Monad}}M$
+\end_inset
+
+ that works in the same way for all monads
+\begin_inset Formula $M$
+\end_inset
+
+.
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+See
+\family typewriter
+
+\begin_inset CommandInset href
+LatexCommand href
+target "https://stackoverflow.com/questions/61444425/"
+literal "false"
\end_inset
\end_layout
-\begin_layout Standard
-The following type isomorphism holds:
-\begin_inset Formula
-\begin{align*}
- & E\rightarrow R=(\exists A.\,P^{A})\rightarrow R\cong\forall C.\,P^{C}\rightarrow R\quad,\\
-\text{or equivalently}:\quad & \big(\forall B.\,(\forall A.\,P^{A}\rightarrow B)\rightarrow B\big)\rightarrow R\cong\forall C.\,P^{C}\rightarrow R\quad,
-\end{align*}
-
-\end_inset
-
-where
-\begin_inset Formula $R$
-\end_inset
-
- is a fixed type.
- In this isomorphism, it is assumed that the type
-\begin_inset Formula $E$
\end_inset
- contains only functions
-\begin_inset Formula $e^{:E}$
-\end_inset
+ We can express this as a type equivalence:
+\begin_inset Formula
+\[
+\forall M^{:\text{Monad}}.\,M\xrightarrow{\text{Monad}}M\cong\bbnum 1\quad.
+\]
- that obey the naturality law
-\begin_inset space ~
\end_inset
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:naturality-law-of-e-derivation1"
-plural "false"
-caps "false"
-noprefix "false"
-\end_inset
+\end_layout
-).
-
+\begin_layout Subparagraph
+Proof
\end_layout
\begin_layout Standard
-This isomorphism can be also formulated via code like this:
-\begin_inset Formula
-\begin{equation}
-\text{for all }e^{:E}\text{ and }r^{:E\rightarrow R}:\quad r(e)=e^{R}(\forall C.\,\text{pack}^{C}\bef r)\quad,\label{eq:surjectivity-of-pack}
-\end{equation}
-
-\end_inset
-
-where the standard function
+The
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-pack
+Monad
\end_layout
\end_inset
- was defined in the proof of Statement
-\begin_inset space ~
-\end_inset
-
-
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-identity-law-of-pack"
-plural "false"
-caps "false"
-noprefix "false"
-
+ typeclass has methods in the form of an
+\begin_inset Formula $FM$
\end_inset
-.
- Any function
-\begin_inset Formula $r$
+-typeclass for functors
+\begin_inset Formula $K$
\end_inset
- that consumes values of type
-\begin_inset Formula $e$
+ if we define
+\begin_inset Formula $P$
\end_inset
- can be expressed via application of
-\begin_inset Formula $r$
+ by
+\begin_inset Formula $(P^{K})^{A}\triangleq A+K^{K^{A}}$
\end_inset
- to values constructed via
+.
+ Then the methods of the
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-pack
+Monad
\end_layout
\end_inset
-.
-\end_layout
+ typeclass are represented by a single value of type:
+\begin_inset Formula
+\[
+\forall A.\,(P^{K})^{A}\rightarrow K^{A}=\forall A.\,A+K^{K^{A}}\rightarrow K^{A}\cong(\forall A.\,A\rightarrow K^{A})\times(\forall A.\,K^{K^{A}}\rightarrow K^{A})\quad.
+\]
-\begin_layout Subparagraph
-Proof
-\end_layout
+\end_inset
-\begin_layout Standard
-The isomorphism is shown by defining two functions (
+This is a tuple type describing the type signatures of
+\begin_inset Formula $K$
+\end_inset
+
+'s
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-inF
+pure
\end_layout
\end_inset
@@ -49824,782 +53059,1003 @@ status open
\begin_layout Plain Layout
-outF
+flatten
\end_layout
\end_inset
-):
-\begin_inset Formula
-\begin{align*}
- & \text{inF}:(\forall C.\,P^{C}\rightarrow R)\rightarrow E\rightarrow R\quad,\\
- & \text{inF}\triangleq k^{:\forall C.\,P^{C}\rightarrow R}\rightarrow e^{:E}\rightarrow e^{R}(k)\quad,\\
- & \text{outF}:(E\rightarrow R)\rightarrow\forall C.\,P^{C}\rightarrow R\quad,\\
- & \text{outF}\triangleq r^{:E\rightarrow R}\rightarrow\forall C.\,p^{:P^{C}}\rightarrow r(\text{pack}^{C}(p))=r^{:E\rightarrow R}\rightarrow\forall C.\,\text{pack}^{C}\bef r\quad,
-\end{align*}
-
+ methods when
+\begin_inset Formula $K$
\end_inset
-and by proving that those functions are inverses of each other.
-\end_layout
-
-\begin_layout Standard
-Without the type annotations, the code of
+ is a monad.
+ So, the Jaskelioff-O'Connor theorem applies to the
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-inF
+Monad
\end_layout
\end_inset
- and
-\begin_inset listings
-inline true
-status open
+ typeclass.
+ The free monad constructor (
+\begin_inset Formula $E$
+\end_inset
+
+) is defined recursively as
+\begin_inset Formula $(E^{F})^{A}\triangleq A+F^{(E^{F})^{A}}$
+\end_inset
+
+, making
+\begin_inset Formula $E^{F}$
+\end_inset
+
+ a monad when
+\begin_inset Formula $F$
+\end_inset
+
+ is any functor.
+ The free monad's universal runner is defined by:
+\begin_inset Formula
+\begin{align*}
+ & \text{run}_{E}^{F,A}:(\forall X.\,F^{X}\rightarrow M^{X})\rightarrow(E^{F})^{A}\rightarrow M^{A}\quad,\\
+ & \text{run}_{E}^{F,A}\big(k^{:\forall X.\,F^{X}\rightarrow M^{X}}\big)\triangleq\,\begin{array}{|c||c|}
+ & M^{A}\\
+\hline A & \text{pu}_{M}\\
+F^{(E^{F})^{A}} & k^{(E^{F})^{A}}\bef\text{flm}_{M}\big(\overline{\text{run}}_{E}^{F,A}(k)\big)
+\end{array}\quad.
+\end{align*}
+
+\end_inset
-\begin_layout Plain Layout
-outF
\end_layout
+\begin_layout Standard
+
+\series bold
+(a)
+\series default
+ Monad morphisms are natural transformations that satisfy additional laws.
+ We first consider the given type without restricting the functions of type
+
+\begin_inset Formula $A\rightarrow M^{A}$
\end_inset
- is:
+ to monad morphisms but still assuming that they are natural transformations:
\begin_inset Formula
\[
-\text{inF}=k\rightarrow q\rightarrow q(k)\quad,\quad\quad\text{outF}=r\rightarrow p\rightarrow r(k\rightarrow k(p))\quad.
+\forall M^{:\text{Monad}}.\,\forall A.\,A\rightarrow M^{A}\quad.
\]
\end_inset
-Now it is quick to prove one direction of isomorphism (
-\begin_inset Formula $\text{inF}\bef\text{outF}\overset{?}{=}\text{id}$
+By the Yoneda identity, we get the type equivalence:
+\begin_inset Formula
+\[
+\forall A.\,A\rightarrow M^{A}\cong M^{\bbnum 1}\quad.
+\]
+
\end_inset
-):
-\begin_inset Formula
-\begin{align*}
-\text{expect to equal }\text{id}:\quad & \text{inF}\bef\text{outF}=k\rightarrow\text{outF}\,(q\rightarrow q(k))\\
- & =k\rightarrow p\rightarrow(q\rightarrow q(k))(k\rightarrow k(p))\\
- & =k\rightarrow\gunderline{p\rightarrow k(p)}=k\rightarrow k=\text{id}\quad.
-\end{align*}
+So, we have reduced the type to
+\begin_inset Formula $\forall M^{:\text{Monad}}.\,M^{\bbnum 1}$
+\end_inset
+.
+ This type will be in the form suitable for the Jaskelioff-O'Connor theorem
+\begin_inset space ~
\end_inset
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:jaskelioff-o-connor-theorem"
+plural "false"
+caps "false"
+noprefix "false"
-\end_layout
+\end_inset
-\begin_layout Standard
-The other direction (
-\begin_inset Formula $\text{outF}\bef\text{inF}\overset{?}{=}\text{id}$
+) if we set
+\begin_inset Formula $F=M$
\end_inset
-) requires more work.
- The argument of the function
-\begin_inset Formula $\text{outF}\bef\text{inF}$
+,
+\begin_inset Formula $A=\bbnum 0$
\end_inset
- has type
-\begin_inset Formula $E\rightarrow R$
+,
+\begin_inset Formula $C=\bbnum 1$
\end_inset
-, and we need to show that for any function
-\begin_inset Formula $r^{:E\rightarrow R}$
+; the parameter
+\begin_inset Formula $B$
\end_inset
- the following equation holds:
+ remains unused since
+\begin_inset Formula $A\rightarrow M^{B}=\bbnum 0\rightarrow M^{B}\cong\bbnum 1$
+\end_inset
+
+.
+ Then Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:jaskelioff-o-connor-theorem"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) gives:
\begin_inset Formula
\[
-\text{inF}\,(\text{outF}\,(r))\overset{?}{=}r\quad,\quad\text{or equivalently}:\quad r\triangleright\text{outF}\triangleright\text{inF}\overset{?}{=}r\quad.
+\forall M^{:\text{Monad}}.\,M^{\bbnum 1}\cong\forall M^{:\text{Monad}}.\,(\bbnum 0\rightarrow M^{B})\rightarrow M^{\bbnum 1}\cong(E^{R})^{\bbnum 1}\quad,
\]
\end_inset
-The last equation is between functions of type
-\begin_inset Formula $E\rightarrow R$
+where we must define
+\begin_inset Formula $R^{X}=A\times(B\rightarrow X)$
\end_inset
-; we may apply both sides to an arbitrary value
-\begin_inset Formula $e^{:E}$
+.
+ However, setting
+\begin_inset Formula $A=\bbnum 0$
\end_inset
- and require that the results (of type
-\begin_inset Formula $R$
+ gives also
+\begin_inset Formula $R=\bbnum 0$
\end_inset
-) should be equal:
+.
+ Then the free monad
+\begin_inset Formula $E^{R}$
+\end_inset
+
+ is the identity functor:
\begin_inset Formula
\[
-\big(r\triangleright\text{outF}\triangleright\text{inF}\big)(e)\overset{?}{=}r(e)\quad.
+(E^{R})^{C}=C+R^{(E^{R})^{C}}=C+\bbnum 0\cong C\quad.
\]
\end_inset
-We begin by subtituting the definitions of
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
+Finally, we obtain
+\begin_inset Formula $(E^{R})^{\bbnum 1}=\bbnum 1$
+\end_inset
-inF
-\end_layout
+, and so:
+\begin_inset Formula
+\[
+\forall M^{:\text{Monad}}.\,\forall A.\,A\rightarrow M^{A}\cong\bbnum 1\quad.
+\]
\end_inset
- and
-\begin_inset listings
-inline true
-status open
-\begin_layout Plain Layout
+\end_layout
-outF
+\begin_layout Standard
+We conclude that
+\emph on
+without
+\emph default
+ restricting to monad morphisms there is only a single function of the given
+ type.
+ It remains to derive the code for that function and to verify that it is
+ indeed a monad morphism.
\end_layout
+\begin_layout Standard
+We begin with a unit value (that we denote by
+\begin_inset Formula $1$
\end_inset
-:
-\begin_inset Formula
-\begin{align*}
-\text{expect to equal }r(e):\quad & e\triangleright\big(r\triangleright\text{outF}\triangleright\text{inF}\big)=e\triangleright\big((\forall A.\,p^{:P^{A}}\rightarrow r(\text{pack}^{A}(p)))\triangleright\text{inF}\big)\\
- & =e^{R}\big(\forall A.\,p^{:P^{A}}\rightarrow r(\text{pack}^{A}(p))\big)=e^{R}(\forall A.\,\text{pack}^{A}\bef r)\quad.
-\end{align*}
-
+) viewed as a value of type
+\begin_inset Formula $(E^{R})^{C}$
\end_inset
-Since
-\begin_inset Formula $e$
+ in the right-hand side of Eq.
+\begin_inset space ~
\end_inset
- is unknown and arbitrary, we can make progress in the proof only if we
- use the naturality law of
-\begin_inset Formula $e$
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:jaskelioff-o-connor-theorem"
+plural "false"
+caps "false"
+noprefix "false"
+
\end_inset
- as given by Eq.
+).
+ We follow the proof of Statement
\begin_inset space ~
\end_inset
-(
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:naturality-law-of-e-derivation1"
+reference "subsec:Statement-Jaskelioff-OConnor"
plural "false"
caps "false"
noprefix "false"
\end_inset
-).
- We assign
-\begin_inset Formula $B=E$
+.
+ The first step is to convert the value of type
+\begin_inset Formula $(E^{R})^{C}$
\end_inset
-,
-\begin_inset Formula $C=R$
+ into a function
+\begin_inset Formula $f$
\end_inset
-,
-\begin_inset Formula $f=r$
+ of type:
+\begin_inset Formula
+\[
+f:\forall M^{:\text{Monad}}.\,\big(\forall X.\,(E^{R})^{X}\xrightarrow{\text{Monad}}M^{X}\big)\rightarrow M^{C}\quad.
+\]
+
\end_inset
-,
-\begin_inset Formula $k=\text{pack}$
+In our case, this function is simplified to:
+\begin_inset Formula
+\begin{align*}
+ & f:\forall M^{:\text{Monad}}.\,\big(\forall X.\,\text{Id}^{X}\xrightarrow{\text{Monad}}M^{X}\big)\rightarrow M^{\bbnum 1}\quad,\\
+ & f^{M}\big(k^{:\forall X.\,\text{Id}^{X}\xrightarrow{\text{Monad}}M^{X}}\big)\triangleq k^{\bbnum 1}(1)\quad.
+\end{align*}
+
\end_inset
- in that law and obtain:
+The next step is to convert
+\begin_inset Formula $f$
+\end_inset
+
+ to a function
+\begin_inset Formula $g$
+\end_inset
+
+ of type:
\begin_inset Formula
\[
-r(e^{E}(\text{pack}))=e^{R}(\forall A.\,\text{pack}^{A}\bef r)\quad.
+g:\forall M^{:\text{Monad}}.\,(\forall X.\,R^{X}\rightarrow M^{X})\rightarrow M^{C}\quad.
\]
\end_inset
-By the identity law of pack (Statement
+In our case,
+\begin_inset Formula $R^{X}=\bbnum 0$
+\end_inset
+
+ and
+\begin_inset Formula $R^{X}\rightarrow M^{X}\cong\bbnum 1$
+\end_inset
+
+, so this function is simplified to:
+\begin_inset Formula
+\begin{align*}
+ & g:\forall M^{:\text{Monad}}.\,\bbnum 1\rightarrow M^{\bbnum 1}\quad,\\
+ & g^{M}(k^{:\bbnum 1})\triangleq f^{M}\big(\forall Y.\,r^{:(E^{R})^{Y}}\rightarrow\text{run}_{E}^{R,Y}(k)(r)\big)\\
+ & \quad=f^{M}(\forall Y.\,r^{:Y}\rightarrow\text{pu}_{M}^{Y}(r))=\text{pu}_{M}^{\bbnum 1}(1)\quad.
+\end{align*}
+
+\end_inset
+
+Finally, we convert
+\begin_inset Formula $g$
+\end_inset
+
+ to a function
+\begin_inset Formula $h$
+\end_inset
+
+ of type:
+\begin_inset Formula
+\begin{align*}
+ & h:\forall M^{:\text{Monad}}.\,(A\rightarrow M^{B})\rightarrow M^{C}\\
+ & =\forall M^{:\text{Monad}}.\,(\bbnum 0\rightarrow M^{B})\rightarrow M^{\bbnum 1}\quad.\\
+ & \cong\forall M^{:\text{Monad}}.\,\bbnum 1\rightarrow M^{\bbnum 1}\cong\forall M^{:\text{Monad}}.\,M^{\bbnum 1}\quad.
+\end{align*}
+
+\end_inset
+
+ There exists only one value of type
+\begin_inset Formula $\forall M^{:\text{Monad}}.\,M^{\bbnum 1}$
+\end_inset
+
+, and that value is
+\begin_inset Formula $\text{pu}_{M}(1)$
+\end_inset
+
+.
+ Converting that to the type signature
+\begin_inset Formula $\forall A.\:A\rightarrow M^{A}$
+\end_inset
+
+, we recover just the standard monad method
+\begin_inset Formula $\text{pu}_{M}$
+\end_inset
+
+.
+ We know that
+\begin_inset Formula $\text{pu}_{M}$
+\end_inset
+
+ gives a monad morphism between the identity monad and
+\begin_inset Formula $M$
+\end_inset
+
+ (see Statement
\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-identity-law-of-pack"
+reference "subsec:Statement-pure-M-is-monad-morphism"
plural "false"
caps "false"
noprefix "false"
\end_inset
-),
-\begin_inset Formula $e^{E}(\text{pack})=e$
+).
+ So, we have proved that there exists a unique monad morphism of type
+\begin_inset Formula $\forall M^{:\text{Monad}}.\,\text{Id}\xrightarrow{\text{Monad}}M$
\end_inset
.
- So, we conclude the derivation:
+
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(b)
+\series default
+ Again, we first consider the given type without restricting the functions
+ of type
+\begin_inset Formula $M^{X}\rightarrow M^{X}$
+\end_inset
+
+ to monad morphisms (but still assuming that they are natural transformations):
\begin_inset Formula
-\begin{align*}
-\text{expect to equal }r(e):\quad & e\triangleright\big(r\triangleright\text{outF}\triangleright\text{inF}\big)=\gunderline{e^{R}(\forall A.\,\text{pack}^{A}\bef r)}\\
-\text{naturality law of }e:\quad & =r(\gunderline{e^{E}(\text{pack})})\\
-\text{identity law of }\text{pack}:\quad & =r(e)\quad.
-\end{align*}
+\[
+\forall M^{:\text{Monad}}.\,\forall X.\,M^{X}\rightarrow M^{X}\quad.
+\]
\end_inset
-We have proved the isomorphism and also verified Eq.
+This type will be in the form suitable for the Jaskelioff-O'Connor theorem
\begin_inset space ~
\end_inset
(
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:surjectivity-of-pack"
+reference "eq:jaskelioff-o-connor-theorem"
plural "false"
caps "false"
noprefix "false"
\end_inset
-).
-
-\begin_inset Formula $\square$
+) if we set
+\begin_inset Formula $F=M$
\end_inset
+,
+\begin_inset Formula $A=\bbnum 1$
+\end_inset
-\end_layout
-
-\begin_layout Subsection
-Greatest fixpoints and the Church-co-Yoneda identity
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:The-greatest-fixpoints-and-Church-co-Yoneda"
-
+, and
+\begin_inset Formula $B=C=X$
\end_inset
+.
+ The functor
+\begin_inset Formula $R$
+\end_inset
-\end_layout
+ is then defined by:
+\begin_inset Formula
+\[
+R^{T}\triangleq A\times(B\rightarrow T)\cong X\rightarrow T\quad,
+\]
-\begin_layout Standard
-We have seen that the least fixpoints of functors are expressed via the
- Church encoding type that involves a universally quantified higher-order
- function.
- An analogous encoding (with an existentially quantified type) exists for
- greatest fixpoints.
- We will now prove some properties of that encoding.
-\begin_inset Foot
-status open
+\end_inset
-\begin_layout Plain Layout
-This section follows the logic shown in P.
-\begin_inset space ~
+and the functor
+\begin_inset Formula $E^{R}$
\end_inset
-Wadler's paper
-\begin_inset Quotes eld
+ (the free monad on
+\begin_inset Formula $R$
\end_inset
-Recursive types for free
-\begin_inset Quotes erd
+) is defined recursively by:
+\begin_inset Formula
+\[
+(E^{R})^{T}\triangleq T+\big(X\rightarrow(E^{R})^{T}\big)\quad.
+\]
+
\end_inset
- except that the existential types are defined by Eq.
+ With these definitions, Eq.
\begin_inset space ~
\end_inset
(
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:existential-via-universal-Yoneda"
+reference "eq:jaskelioff-o-connor-theorem"
plural "false"
caps "false"
noprefix "false"
\end_inset
-) via the universal quantifier.
-\end_layout
+) gives:
+\begin_inset Formula
+\[
+\forall M^{:\text{Monad}}.\,\forall X.\,M^{X}\rightarrow M^{X}\cong\forall X.\,(E^{R})^{X}\quad.
+\]
\end_inset
+We are using the functor
+\begin_inset Formula $(E^{R})^{T}$
+\end_inset
-\end_layout
-
-\begin_layout Standard
-We work with a fixed covariant functor
-\begin_inset Formula $F$
+ with the type parameter
+\begin_inset Formula $T=X$
\end_inset
- and denote by
-\begin_inset Formula $C$
+; however,
+\begin_inset Formula $E^{R}$
\end_inset
- the following Church-encoded type:
-\begin_inset Formula
-\[
-C\triangleq\exists A.\,(A\rightarrow F^{A})\times A\quad.
-\]
+ also contains
+\begin_inset Formula $X$
+\end_inset
+ through the definition of
+\begin_inset Formula $R$
\end_inset
-We will prove that
-\begin_inset Formula $C$
+.
+ To avoid confusion and to simplify notation, let us write
+\begin_inset Formula $G^{X}$
\end_inset
- is the greatest fixpoint of the type equation
-\begin_inset Formula $X\cong F^{X}$
+ instead of
+\begin_inset Formula $(E^{R})^{X}$
\end_inset
-; that is,
-\begin_inset Formula $C=\nu X.\,F^{X}$
+, where the type constructor
+\begin_inset Formula $G$
\end_inset
-.
-
-\end_layout
+ is defined recursively by:
+\begin_inset Formula
+\[
+G^{X}\triangleq X+(X\rightarrow G^{X})\quad.
+\]
-\begin_layout Standard
-First, we define some auxiliary functions that work with the type
-\begin_inset Formula $C$
\end_inset
- and prove their properties.
-\end_layout
+(Note that
+\begin_inset Formula $G$
+\end_inset
-\begin_layout Standard
-The function
-\begin_inset listings
-inline true
-status open
+ is neither covariant nor contravariant.) With this definition, we obtain:
+\begin_inset Formula
+\[
+\forall M^{:\text{Monad}}.\,\forall X.\,M^{X}\rightarrow M^{X}\cong\forall X.\,G^{X}\quad.
+\]
+
+\end_inset
-\begin_layout Plain Layout
-unfold
\end_layout
+\begin_layout Standard
+To simpify the type
+\begin_inset Formula $\forall X.\,G^{X}$
\end_inset
- constructs values of type
-\begin_inset Formula $C$
+, begin by expanding the recursive type
+\begin_inset Formula $G^{X}$
\end_inset
:
\begin_inset Formula
\begin{align*}
- & \text{unfold}:\forall T.\,(T\rightarrow F^{T})\times T\rightarrow C\quad,\\
- & \text{unfold}^{T}(u^{:T\rightarrow F^{T}}\times t^{:T})\triangleq\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R}\rightarrow p^{T}(u\times t)\quad.
+ & \forall X.\,G^{X}\cong\forall X.\,X+(X\rightarrow G^{X})\\
+\text{non-disjunctivity}:\quad & \cong(\forall X.\,X)+(\forall X.\,X\rightarrow G^{X})\\
+\text{use }\forall X.\,X\cong\bbnum 0:\quad & \cong\forall X.\,X\rightarrow G^{X}\quad.
\end{align*}
\end_inset
-Note that
-\begin_inset listings
-inline true
-status open
+Here we used the non-disjunctivity property from Example
+\begin_inset space ~
+\end_inset
-\begin_layout Plain Layout
-unfold
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-undisjunctive-type-constructors"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
- is the same as the function
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-
-pack
+(e).
\end_layout
+\begin_layout Standard
+Continue expanding the recursive type:
+\begin_inset Formula
+\begin{align*}
+ & \forall X.\,X\rightarrow G^{X}\cong\forall X.\,X\rightarrow(X+(X\rightarrow G^{X}))\\
+\text{non-disjunctivity}:\quad & \cong(\gunderline{\forall X.\,X\rightarrow X})+\big(\forall X.\,X\rightarrow X\rightarrow G^{X}\big)\\
+ & \cong\bbnum 1+\forall X.\,X\times X\rightarrow G^{X}\quad.
+\end{align*}
+
\end_inset
- from Statement
+The relevant non-disjunctivity property was shown in Example
\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-identity-law-of-pack"
+reference "subsec:Example-undisjunctive-type-constructors"
plural "false"
caps "false"
noprefix "false"
\end_inset
- if we set
-\begin_inset Formula $E=C$
-\end_inset
+(f).
+ Expand further, using the same non-disjunctivity property:
+\begin_inset Formula
+\begin{align*}
+ & \forall X.\,G^{X}\cong\bbnum 1+\forall X.\,X\times X\rightarrow G^{X}\\
+ & \cong\bbnum 1+\forall X.\,X\times X\rightarrow(X+(X\rightarrow G^{X}))\\
+\text{non-disjunctivity}:\quad & \cong\bbnum 1+(\gunderline{\forall X.\,X\times X\rightarrow X})+\big(\forall X.\,X\times X\rightarrow X\rightarrow G^{X}\big)\\
+ & \cong\bbnum 1+\bbnum 2+\forall X.\,X\times X\times X\rightarrow G^{X}\quad.
+\end{align*}
- and
-\begin_inset Formula $P^{A}\triangleq(A\rightarrow F^{A})\times A$
\end_inset
- in the definition of
-\begin_inset listings
-inline true
-status open
+Proceeding similarly, we obtain:
+\begin_inset Formula
+\[
+\forall X.\,\underbrace{X\times...\times X}_{n\text{ times}}\rightarrow G^{X}\cong\underbrace{\bbnum 1+...+\bbnum 1}_{n\text{ times}}+\forall X.\,\underbrace{X\times...\times X}_{n+1\text{ times}}\rightarrow G^{X}\quad.
+\]
-\begin_layout Plain Layout
+\end_inset
-pack
-\end_layout
+It follows by induction that
+\begin_inset Formula $\forall X.\,G^{X}$
+\end_inset
+ is equivalent to an
+\begin_inset Quotes eld
\end_inset
-.
-\end_layout
+infinite
+\begin_inset Quotes erd
+\end_inset
-\begin_layout Standard
-By parametricity, the function
-\begin_inset listings
-inline true
-status open
+ sum type:
+\begin_inset Formula
+\[
+\forall X.\,G^{X}\cong\bbnum 1+\bbnum 2+\bbnum 3+...
+\]
-\begin_layout Plain Layout
+\end_inset
-unfold
-\end_layout
+Values of that type may be described by pairs
+\begin_inset Formula $\left(n,k\right)$
+\end_inset
+ of natural numbers such that
+\begin_inset Formula $1\le k\le n$
\end_inset
- satisfies a relational naturality law: for all types
-\begin_inset Formula $A$
+.
+ The number
+\begin_inset Formula $n$
\end_inset
-,
-\begin_inset Formula $B$
+ chooses the part
+\begin_inset Quotes eld
\end_inset
- and all functions
-\begin_inset Formula $f^{:A\rightarrow B}$
+
+\begin_inset Formula $\bbnum n$
\end_inset
-,
-\begin_inset Formula
-\begin{equation}
-\text{if}\quad u\bef f^{\uparrow F}=f\bef v\quad\text{then}\quad\text{unfold}^{A}(u^{:A\rightarrow F^{A}}\times a^{:A})=\text{unfold}^{B}(v^{:B\rightarrow F^{B}}\times f(a))\quad.\label{eq:relational-naturality-law-of-unfold}
-\end{equation}
+\begin_inset Quotes erd
\end_inset
-In category theory, the precondition
-\begin_inset Formula $u\bef f^{\uparrow F}=f\bef v$
+ within the disjunctive type
+\begin_inset Formula $\bbnum 1+\bbnum 2+\bbnum 3+...$
\end_inset
- is known as the
+, where we denoted by
\begin_inset Quotes eld
\end_inset
-\begin_inset Formula $F$
+\begin_inset Formula $\bbnum n$
\end_inset
--coalgebra morphism law
+
\begin_inset Quotes erd
\end_inset
- of
-\begin_inset Formula $f$
+ the type
+\begin_inset Formula $\underbrace{\bbnum 1+...+\bbnum 1}_{n\text{ times}}$
+\end_inset
+
+.
+ The number
+\begin_inset Formula $k$
+\end_inset
+
+ chooses a specific unit value within
+\begin_inset Formula $\underbrace{\bbnum 1+...+\bbnum 1}_{n\text{ times}}$
\end_inset
.
- Let us give some definitions for reference:
\end_layout
-\begin_layout Subsubsection
-Definition
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Definition-F-coalgebra"
+\begin_layout Standard
+The next step is to convert values
+\begin_inset Formula $\left(n,k\right)$
+\end_inset
+
+ of that type into functions of type
+\begin_inset Formula $M^{X}\rightarrow M^{X}$
+\end_inset
+
+ that work in the same way for all monads
+\begin_inset Formula $M$
+\end_inset
+
+ and all types
+\begin_inset Formula $X$
+\end_inset
+.
+ We have to find out whether any of those functions obey the laws of monad
+ morphisms.
+ For that, we need to derive the specific code of those functions.
+ We follow the steps outlined in the proof of Statement
+\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Definition-F-coalgebra"
+reference "subsec:Statement-Jaskelioff-OConnor"
plural "false"
caps "false"
noprefix "false"
\end_inset
-
+.
\end_layout
\begin_layout Standard
-Given a functor
-\begin_inset Formula $F$
+First, we translate pairs
+\begin_inset Formula $\left(n,k\right)$
\end_inset
-, a type
-\begin_inset Formula $A$
+ into values of type
+\begin_inset Formula $\forall X.\,G^{X}$
\end_inset
- together with a function
-\begin_inset Formula $u:A\rightarrow F^{A}$
+ that we will denote by
+\begin_inset Formula $q_{n,k}$
\end_inset
- is called an
-\begin_inset Formula $F$
+.
+ To achieve that, we need to retrace the way we expanded the recursive type
+
+\begin_inset Formula $G^{X}$
\end_inset
-
-\series bold
--coalgebra
-\series default
.
-\begin_inset Index idx
-status open
-
-\begin_layout Plain Layout
-\begin_inset Formula $F$
+ As an example, consider the pair
+\begin_inset Formula $\left(n=2,k=1\right)$
\end_inset
--coalgebra
-\end_layout
-
+.
+ The value
+\begin_inset Formula $n=2$
\end_inset
- The type
-\begin_inset Formula $A$
+ corresponds to the type
+\begin_inset Formula $\bbnum 2$
\end_inset
- is called the
-\series bold
-carrier
-\series default
- of the
-\begin_inset Formula $F$
+, which was obtained from
+\begin_inset Formula $\forall X.\,X\rightarrow X\rightarrow X$
\end_inset
--coalgebra, and the function
-\begin_inset Formula $u$
+ during expansion of
+\begin_inset Formula $\forall X.\,G^{X}$
\end_inset
- is called the
-\series bold
-structure map
-\series default
- of the
-\begin_inset Formula $F$
+.
+ The type
+\begin_inset Formula $\forall X.\,X\rightarrow X\rightarrow X$
\end_inset
--coalgebra.
- (Keep in mind that
-\begin_inset Formula $u$
+ has only two distinct values, which are functions that return the first
+ or the second argument of type
+\begin_inset Formula $X$
\end_inset
- is not universally quantified over
-\begin_inset Formula $A$
+.
+ The index
+\begin_inset Formula $k=1$
\end_inset
-; it is a function that only works with a single, specified type
-\begin_inset Formula $A$
+ selects the first of those values, which is a function whose code is written
+ as
+\begin_inset Formula $x_{1}^{:X}\rightarrow x_{2}^{:X}\rightarrow x_{1}$
\end_inset
.
- For a given type
-\begin_inset Formula $A$
-\end_inset
-
-, there could be several different structure maps
-\begin_inset Formula $u$
-\end_inset
+
+\end_layout
-,
-\begin_inset Formula $u^{\prime}$
+\begin_layout Standard
+To simplify notation, let us temporarily fix the type parameter
+\begin_inset Formula $X$
\end_inset
-, and so on; each of them will then define a different
-\begin_inset Formula $F$
+; we will restore the quantifier
+\begin_inset Formula $\forall X$
\end_inset
--coalgebra.)
+ at the end of the derivation.
\end_layout
\begin_layout Standard
-If
-\begin_inset Formula $A$
+The type
+\begin_inset Formula $X\rightarrow X\rightarrow X$
\end_inset
- and
-\begin_inset Formula $B$
+ was found during expansion of the recursive type
+\begin_inset Formula $G^{X}$
\end_inset
- are two
-\begin_inset Formula $F$
+ as:
+\begin_inset Formula
+\[
+G^{X}=X+(X\rightarrow(X+(X\rightarrow(X+...))))\quad.
+\]
+
\end_inset
--coalgebras with structure maps
-\begin_inset Formula $u:A\rightarrow F^{A}$
+So, the pair
+\begin_inset Formula $\left(n=2,k=1\right)$
\end_inset
- and
-\begin_inset Formula $v:B\rightarrow F^{B}$
+ corresponds to the function
+\begin_inset Formula $q_{2,1}^{X}:G^{X}$
\end_inset
- then a function
-\begin_inset Formula $f:A\rightarrow B$
+ written as:
+\begin_inset Formula
+\begin{align*}
+ & q_{2,1}^{X}:X+(X\rightarrow(X+(X\rightarrow(X+(X\rightarrow G^{X})))))\quad,\\
+ & q_{2,1}^{X}\triangleq\bbnum 0^{:X}+(x_{1}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{2}^{:X}\rightarrow(x_{1}+\bbnum 0^{:X\rightarrow G^{X}}))))\quad.
+\end{align*}
+
\end_inset
- is called an
-\begin_inset Formula $F$
+In a similar way, we define the functions
+\begin_inset Formula $q_{n,k}$
\end_inset
--coalgebra morphism if this law holds:
-\begin_inset Preview
+ for any
+\begin_inset Formula $1\le k\le n$
+\end_inset
-\begin_layout Standard
+:
\begin_inset Formula
\[
-\xymatrix{\xyScaleY{2.3pc}\xyScaleX{2.5pc}A\ar[d]\sb(0.4){u}\ar[r]\sp(0.5){f} & B\ar[d]\sp(0.4){v}\\
-F^{A}\ar[r]\sp(0.5){f^{\uparrow F}} & F^{B}
-}
+q_{n,k}^{X}\triangleq\bbnum 0^{:X}+(x_{1}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{2}^{:X}\rightarrow...\rightarrow(\bbnum 0^{:X}+(x_{n}^{:X}\rightarrow(x_{k}+\bbnum 0^{:X\rightarrow G^{X}})))...)))\quad.
\]
\end_inset
-
-\end_layout
-
+To make this code description rigorous, let us define
+\begin_inset Formula $u_{i,n,k}$
\end_inset
+ and
+\begin_inset Formula $v_{i,n}$
+\end_inset
+ like this:
\begin_inset Formula
-\[
-u\bef f^{\uparrow F}=f\bef v\quad.
-\]
+\begin{align*}
+ & u_{i,n,k}\triangleq\bbnum 0^{:X}+(x_{i}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{i+1}^{:X}\rightarrow...\rightarrow(x_{n}^{:X}\rightarrow(x_{k}+\bbnum 0^{:X\rightarrow G^{X}}))...))),\\
+ & v_{i,n}(x_{0})\triangleq\bbnum 0^{:X}+(x_{i}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{i+1}^{:X}\rightarrow...\rightarrow(x_{n}^{:X}\rightarrow(x_{0}+\bbnum 0^{:X\rightarrow G^{X}}))...))).
+\end{align*}
\end_inset
-This is the
-\begin_inset Formula $F$
+These formulas hold for
+\begin_inset Formula $1\le i\le k\le n$
\end_inset
--coalgebra morphism law of
-\begin_inset Formula $f$
+.
+ An inductive definition of
+\begin_inset Formula $q_{n,k}^{X}$
\end_inset
-.
-
-\begin_inset Formula $\square$
+,
+\begin_inset Formula $u_{i,n,k}$
\end_inset
+, and
+\begin_inset Formula $v_{i,n}$
+\end_inset
-\end_layout
+ is:
+\begin_inset Formula
+\begin{align*}
+ & q_{n,k}^{X}=u_{1,n,k}\quad,\quad\quad u_{i,n,k}:G^{X}\quad,\quad\quad v_{i,n}:X\rightarrow G^{X}\quad,\\
+\text{for }1\le i m.flatMap { x_2 => pure(x_1)
+ } }
+\end_layout
-This is now equal to the left-hand side.
-
-\begin_inset Formula $\square$
\end_inset
+This code can be rewritten as a functor block, making its logic more visually
+ clear:
+\begin_inset listings
+inline false
+status open
-\end_layout
+\begin_layout Plain Layout
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-identity-law-of-unfold"
+def h_2_1(m: M[X]): M[X] = for {
+\end_layout
-\end_inset
+\begin_layout Plain Layout
+ x_1 <- m
+\end_layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-identity-law-of-unfold"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Plain Layout
-\end_inset
+ x_2 <- m
+\end_layout
+\begin_layout Plain Layout
+} yield x_1
\end_layout
-\begin_layout Standard
-The function
+\end_inset
+
+The code runs two effects of
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-unfold
+m
\end_layout
\end_inset
- satisfies an
-\series bold
-identity law
-\series default
-:
-\begin_inset Formula
-\[
-\text{for all }c^{:C}:\quad\text{unfold}^{C}(\text{unfix}\times c)\overset{?}{=}c\quad.
-\]
-
-\end_inset
-
-This law
-\begin_inset Index idx
+ but returns the first value (
+\begin_inset listings
+inline true
status open
\begin_layout Plain Layout
-identity laws!of
+
+x_1
+\end_layout
+
+\end_inset
+
+), ignoring
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-unfold
+x_2
\end_layout
\end_inset
-
+.
\end_layout
+\begin_layout Standard
+Now we can generalize the code pattern from
+\begin_inset Formula $h_{2,1}$
\end_inset
- is similar to the identity law of
+ to
+\begin_inset Formula $h_{n,k}$
+\end_inset
+
+ and write symbolically:
\begin_inset listings
-inline true
+inline false
status open
\begin_layout Plain Layout
-pack
+def h_n_k(m: M[X]): M[X] = for {
\end_layout
-\end_inset
+\begin_layout Plain Layout
- (Statement
-\begin_inset space ~
-\end_inset
+ x_1 <- m
+\end_layout
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-identity-law-of-pack"
-plural "false"
-caps "false"
-noprefix "false"
+ x_2 <- m
+\end_layout
-\end_inset
+\begin_layout Plain Layout
-).
+ ...
\end_layout
-\begin_layout Subparagraph
-Proof
+\begin_layout Plain Layout
+
+ x_n <- m
+\end_layout
+
+\begin_layout Plain Layout
+
+} yield x_k
+\end_layout
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
-Apply Statement
-\begin_inset space ~
+To prove that this is indeed the correct code for
+\begin_inset Formula $h_{n,k}^{M}(m)$
\end_inset
+, we need to use induction in
+\begin_inset Formula $n$
+\end_inset
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-identity-law-of-pack"
-plural "false"
-caps "false"
-noprefix "false"
+.
+ We rewrite
+\begin_inset Formula $q_{n,k}^{X}=u_{1,n,k}$
+\end_inset
+ and compute
+\begin_inset Formula $\text{run}_{E}^{R,X}(p)(q_{n,k})=\text{run}_{E}^{R,X}(p)(u_{1,n,k})$
\end_inset
-, which gives
-\begin_inset Formula $e^{E}(\text{pack})=e$
+.
+ Using the code of
+\begin_inset Formula $\text{run}_{E}$
\end_inset
-, and substitute
-\begin_inset Formula $E=C$
+, we obtain the following inductive code definitions:
+\begin_inset Formula
+\begin{align*}
+\text{for }1\le i (A, Int)
+\end_layout
+
+\begin_layout Plain Layout
+
+val q: M[M[Unit]] = { s => ( { t => ((), s + 1) }, s) }
+\end_layout
+
\end_inset
-:
+
\begin_inset Formula
-\begin{equation}
-\text{unfold}^{A}(u\times a)=\text{unfold}^{C}(\text{unfix}\times\text{unfold}^{A}(u\times a)))\quad.\label{eq:unfold-id-law-derivation2}
-\end{equation}
+\[
+M^{A}\triangleq\text{Int}\rightarrow A\times\text{Int}\quad,\quad\quad q:M^{M^{\bbnum 1}}\quad,\quad q\triangleq s^{:\text{Int}}\rightarrow(\_^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}})\times s\quad.
+\]
\end_inset
-The precondition of this law (
-\begin_inset Formula $u\bef f^{\uparrow F}\overset{?}{=}f\bef v$
-\end_inset
+For more intuition, let us express
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+q
+\end_layout
-) is the
-\begin_inset Formula $F$
\end_inset
--coalgebra morphism law of
+ via the
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-unfold
+State
\end_layout
\end_inset
-, and it has been demonstrated in Statement
-\begin_inset space ~
-\end_inset
+ monad operations
+\begin_inset listings
+inline true
+status open
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-coalgebra-morphism-unfold"
-plural "false"
-caps "false"
-noprefix "false"
+get
+\end_layout
\end_inset
-.
- So, Eq.
-\begin_inset space ~
-\end_inset
+ and
+\begin_inset listings
+inline true
+status open
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:unfold-id-law-derivation2"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Plain Layout
+
+set
+\end_layout
\end_inset
-) holds.
-
-\end_layout
+:
+\begin_inset listings
+inline false
+status open
-\begin_layout Standard
-Finally, we can finish the proof:
-\begin_inset Formula
-\begin{align*}
-\text{expect to equal }c:\quad & \text{unfold}^{C}(\text{unfix}\times c)\\
-\text{use Eq.~(\ref{eq:unfold-id-law-derivation3})}:\quad & =c^{C}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times a^{:A}\rightarrow\gunderline{\text{unfold}^{C}(\text{unfix}\times\text{unfold}^{A}(u\times a)))}\big)\\
-\text{use Eq.~(\ref{eq:unfold-id-law-derivation2})}:\quad & =c^{C}\big(\gunderline{\forall A.\,u^{:A\rightarrow F^{A}}\times a^{:A}\rightarrow\text{unfold}^{A}(u\times a)}\big)=c^{C}(\text{unfold})\\
-\text{use Eq.~(\ref{eq:unfold-id-law-derivation1})}:\quad & =c\quad.
-\end{align*}
+\begin_layout Plain Layout
-\end_inset
+val get: M[Int] = s => (s, s)
+\end_layout
+\begin_layout Plain Layout
+val set: Int => M[Unit] = x => s => ((), x)
\end_layout
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-greatest-fixpoint-church-encoding"
+\begin_layout Plain Layout
-\end_inset
+// Assuming that map and flatMap are defined for M:
+\end_layout
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-greatest-fixpoint-church-encoding"
-plural "false"
-caps "false"
-noprefix "false"
+val q: M[M[Unit]] = for {
+\end_layout
-\end_inset
+\begin_layout Plain Layout
+ s <- get
+\end_layout
+
+\begin_layout Plain Layout
+} yield set(s + 1)
\end_layout
-\begin_layout Standard
-The functions
+\end_inset
+
+Now we compute the two sides of the composition law, step by step.
+ First, we will use Scala's functor block syntax.
+ The
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-fix
+flatten
\end_layout
\end_inset
- and
+ method can be written as:
\begin_inset listings
-inline true
+inline false
status open
\begin_layout Plain Layout
-unfix
+def flatten[A](mm: M[M[A]]): M[A] = for {
\end_layout
-\end_inset
+\begin_layout Plain Layout
- are inverses to each other.
+ m <- mm
\end_layout
-\begin_layout Subparagraph
-Proof
+\begin_layout Plain Layout
+
+ x <- m
\end_layout
-\begin_layout Standard
-Translate the existential quantifier via Eq.
-\begin_inset space ~
-\end_inset
+\begin_layout Plain Layout
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:existential-via-universal-Yoneda"
-plural "false"
-caps "false"
-noprefix "false"
+} yield x
+\end_layout
\end_inset
-) and write
-\begin_inset Formula $C$
-\end_inset
+Substituting the value
+\begin_inset listings
+inline true
+status open
- as:
-\begin_inset Formula
-\[
-C\triangleq\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R)\rightarrow R\quad.
-\]
+\begin_layout Plain Layout
+
+q
+\end_layout
\end_inset
-We need to verify that:
-\end_layout
+ defined above, we get:
+\begin_inset listings
+inline false
+status open
-\begin_layout Standard
+\begin_layout Plain Layout
-\series bold
-(1)
-\series default
- For any
-\begin_inset Formula $c:C$
-\end_inset
+val flatten_q: M[Unit] = for { // This is flatten(q).
+\end_layout
- we have
-\begin_inset Formula $\text{fix}\,(\text{unfix}\,(c))=c$
-\end_inset
+\begin_layout Plain Layout
-.
+ m <- for {
\end_layout
-\begin_layout Standard
+\begin_layout Plain Layout
-\series bold
-(2)
-\series default
- For any
-\begin_inset Formula $q:F^{C}$
-\end_inset
+ s <- get
+\end_layout
- we have
-\begin_inset Formula $\text{unfix}\,(\text{fix}\,(q))=q$
-\end_inset
+\begin_layout Plain Layout
-.
+ } yield set(s + 1)
\end_layout
-\begin_layout Standard
-To prove item
-\series bold
-(1)
-\series default
-:
-\begin_inset Formula
-\begin{align*}
-\text{expect to equal }c:\quad & \gunderline{\text{fix}}\,(\text{unfix}\,(c))\\
-\text{definition of }\text{fix}:\quad & =\text{unfold}^{F^{C}}(\text{unfix}^{\uparrow F}\times\text{unfix}\,(c))\\
-\text{naturality law of }\text{unfold}:\quad & =\text{unfold}^{C}(\text{unfix}\times c)\\
-\text{identity law of }\text{unfold}:\quad & =c\quad.
-\end{align*}
+\begin_layout Plain Layout
-\end_inset
+ x <- m
+\end_layout
-Here we applied the naturality law
-\begin_inset space ~
-\end_inset
+\begin_layout Plain Layout
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:relational-naturality-law-of-unfold"
-plural "false"
-caps "false"
-noprefix "false"
+} yield x
+\end_layout
\end_inset
-) with
-\begin_inset Formula $A=C$
-\end_inset
+Eliminate the nested
+\begin_inset listings
+inline true
+status open
-,
-\begin_inset Formula $B=F^{C}$
-\end_inset
+\begin_layout Plain Layout
-,
-\begin_inset Formula $a=c$
-\end_inset
+for
+\end_layout
-,
-\begin_inset Formula $f=\text{unfix}$
\end_inset
-,
-\begin_inset Formula $u=\text{unfix}$
-\end_inset
+ and obtain:
+\begin_inset listings
+inline false
+status open
-, and
-\begin_inset Formula $v=\text{unfix}^{\uparrow F}$
-\end_inset
+\begin_layout Plain Layout
-.
- To verify the precondition of that law, write:
-\begin_inset Formula
-\[
-u\bef f^{\uparrow F}\overset{?}{=}f\bef v\quad,\quad\text{or equivalently:}\quad\text{unfix}\bef\text{unfix}^{\uparrow F}\overset{?}{=}\text{unfix}\bef\text{unfix}^{\uparrow F}\quad.
-\]
+val flatten_q: M[Unit] = for {
+\end_layout
-\end_inset
+\begin_layout Plain Layout
-This holds trivially.
+ s <- get
\end_layout
-\begin_layout Standard
-To prove item
-\series bold
-(2)
-\series default
-, write:
-\begin_inset Formula
-\begin{align*}
-\text{expect to equal }q:\quad & \text{unfix}\,(\gunderline{\text{fix}\,(q)})\\
-\text{definition of }\text{fix}:\quad & =\gunderline{\text{unfix}}\,\big(\text{unfold}^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\big)\\
-\text{definition of }\text{unfold}:\quad & =\text{unfix}\,\big(\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R}\rightarrow p^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\big)\\
-\text{definition of }\text{unfix}:\quad & =\big(\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R}\rightarrow p^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\big)^{F^{C}}(\text{unfoldF})\\
-\text{apply function}:\quad & =\text{unfoldF}^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\\
-\text{definition of }\text{unfoldF}:\quad & =q\triangleright\gunderline{\text{unfix}^{\uparrow F}\bef\big(a^{:F^{C}}\rightarrow\text{unfold}\,(\text{unfix}^{\uparrow F}\times a)\big)^{\uparrow F}}\\
-\text{composition under }^{\uparrow F}:\quad & =q\triangleright\big(x^{:C}\rightarrow\gunderline{\text{unfold}\,(\text{unfix}^{\uparrow F}\times\text{unfix}\,(x))}\big)^{\uparrow F}\\
-\text{definition of }\text{fix}:\quad & =q\triangleright\big(x^{:C}\rightarrow\gunderline{\text{fix}\,(\text{unfix}\,(x))}\big)^{\uparrow F}\\
-\text{item \textbf{(1)}}:\quad & =q\triangleright\gunderline{(x^{:C}\rightarrow x)^{\uparrow F}}=x\triangleright\text{id}=q\quad.
-\end{align*}
+\begin_layout Plain Layout
-\end_inset
+ m = set(s + 1)
+\end_layout
+\begin_layout Plain Layout
-\begin_inset Formula $\square$
-\end_inset
+ x <- m
+\end_layout
+\begin_layout Plain Layout
+} yield x
\end_layout
-\begin_layout Standard
-It follows that
-\begin_inset Formula $C$
\end_inset
- is a fixpoint of the type equation
-\begin_inset Formula $C\cong F^{C}$
-\end_inset
+Or equivalently (as the returned value is always a unit value):
+\begin_inset listings
+inline false
+status open
-.
- To show that
-\begin_inset Formula $C$
-\end_inset
+\begin_layout Plain Layout
- is indeed the
-\emph on
-greatest
-\emph default
- fixpoint, we need to prove that for any other fixpoint
-\begin_inset Formula $T$
-\end_inset
+val flatten_q: M[Unit] = for {
+\end_layout
- there exists a unique fixpoint-preserving morphism
-\begin_inset Formula $\psi^{T}:T\rightarrow C$
-\end_inset
+\begin_layout Plain Layout
-.
- Similarly to what we saw in Statement
-\begin_inset space ~
-\end_inset
+ s <- get
+\end_layout
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-fixpoint-preserving-fix"
-plural "false"
-caps "false"
-noprefix "false"
+ _ <- set(s + 1)
+\end_layout
-\end_inset
+\begin_layout Plain Layout
-, it is sufficient to check that
-\begin_inset Formula $\psi^{T}$
-\end_inset
+} yield ()
+\end_layout
- is an
-\begin_inset Formula $F$
\end_inset
--coalgebra morphism.
-\end_layout
+Applying
+\begin_inset listings
+inline true
+status open
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-greatest-fixpoint-Church-encoding-morphism"
+\begin_layout Plain Layout
+
+h_n_k
+\end_layout
\end_inset
+ to this value means writing code of the form:
+\begin_inset listings
+inline false
+status open
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-greatest-fixpoint-Church-encoding-morphism"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Plain Layout
-\end_inset
+val h_flatten_q: M[Unit] = for {
+\end_layout
+\begin_layout Plain Layout
+ x_1 <- flatten_q
\end_layout
-\begin_layout Standard
-For any
-\begin_inset Formula $F$
-\end_inset
+\begin_layout Plain Layout
--coalgebra
-\begin_inset Formula $A$
-\end_inset
+ ...
+\end_layout
- with a structure map
-\begin_inset Formula $u:A\rightarrow F^{A}$
-\end_inset
+\begin_layout Plain Layout
-, there exists a unique
-\begin_inset Formula $F$
-\end_inset
+ x_n <- flatten_q
+\end_layout
--algebra morphism
-\begin_inset Formula $\psi_{u}^{A}$
-\end_inset
+\begin_layout Plain Layout
- of type
-\begin_inset Formula $A\rightarrow C$
-\end_inset
+} yield x_k
+\end_layout
-.
- The function
-\begin_inset Formula $\psi_{u}^{A}$
\end_inset
- is known as the
-\series bold
-anamorphism
-\series default
-
-\begin_inset Index idx
+The returned value in
+\begin_inset listings
+inline true
status open
\begin_layout Plain Layout
-anamorphism
+
+x_k
\end_layout
\end_inset
- and was defined as in Statement
-\begin_inset space ~
-\end_inset
+ is in any case the unit value, so let us focus on the state updates.
+ Each
+\begin_inset listings
+inline true
+status open
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-coalgebra-morphism-unfold"
-plural "false"
-caps "false"
-noprefix "false"
+flatten_q
+\end_layout
\end_inset
-:
-\begin_inset Formula
-\[
-\psi_{u}^{A}:A\rightarrow C\quad,\quad\quad\psi_{u}^{A}\triangleq a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\quad.
-\]
+ has the effect of reading a state value
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+s
+\end_layout
\end_inset
+ and storing the incremented value
+\begin_inset listings
+inline true
+status open
-\end_layout
+\begin_layout Plain Layout
-\begin_layout Subparagraph
-Proof
+s + 1
\end_layout
-\begin_layout Standard
-We know from Statement
-\begin_inset space ~
\end_inset
+.
+ The function
+\begin_inset listings
+inline true
+status open
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-coalgebra-morphism-unfold"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Plain Layout
+
+h_n_k
+\end_layout
\end_inset
- that
-\begin_inset Formula $\psi_{u}^{A}$
+ repeats
+\begin_inset Formula $n$
\end_inset
- satisfies the law of
-\begin_inset Formula $F$
+ times the effect of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatten_q
+\end_layout
+
\end_inset
--coalgebra morphisms.
- Let
-\begin_inset Formula $f:A\rightarrow C$
+.
+ This increments the state
+\begin_inset Formula $n$
\end_inset
- be any other
-\begin_inset Formula $F$
-\end_inset
+ times.
+ So, the left-hand side of the law becomes:
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+val lhs: M[Unit] = for { // This is h_flatten_q === h_n_k(flatten(q)).
+\end_layout
--coalgebra morphism; we need to prove that
-\begin_inset Formula $f=\psi_{u}^{A}$
-\end_inset
+\begin_layout Plain Layout
-.
+ s <- get
\end_layout
-\begin_layout Standard
-We know that
-\begin_inset Formula $f$
-\end_inset
+\begin_layout Plain Layout
- satisfies the
-\begin_inset Formula $F$
-\end_inset
+ _ <- set(s + n)
+\end_layout
--coalgebra morphism law:
-\begin_inset Formula
-\[
-u\bef f^{\uparrow F}=f\bef\text{unfix}\quad.
-\]
+\begin_layout Plain Layout
-\end_inset
+} yield ()
+\end_layout
-This is the precondition of the relational naturality law
-\begin_inset space ~
\end_inset
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:relational-naturality-law-of-unfold"
-plural "false"
-caps "false"
-noprefix "false"
+\end_layout
+
+\begin_layout Standard
+Turning now to the right-hand side of the law, we write the first sub-expression
+ (
+\begin_inset Formula $q\triangleright h_{n,k}^{\uparrow M}$
\end_inset
-) of
+, or in Scala,
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-unfold
+q.map(h_n_k)
\end_layout
\end_inset
- if we set
-\begin_inset Formula $B=C$
-\end_inset
+) as the following Scala code:
+\begin_inset listings
+inline false
+status open
- and
-\begin_inset Formula $v=\text{unfix}$
-\end_inset
+\begin_layout Plain Layout
-.
- So, the conclusion of that law holds.
- We use that equation as well as Statement
-\begin_inset space ~
-\end_inset
+val q_map_h: M[M[Unit]] = for {
+\end_layout
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-identity-law-of-unfold"
-plural "false"
-caps "false"
-noprefix "false"
+ m <- q
+\end_layout
-\end_inset
+\begin_layout Plain Layout
- and get:
-\begin_inset Formula
-\begin{align*}
-\text{for any }a^{:A}:\quad & \psi_{u}^{A}(a)=\text{unfold}^{A}(u^{:A\rightarrow F^{A}}\times a^{:A})\\
-\text{naturality law of }\text{unfold}:\quad & =\text{unfold}^{C}(\text{unfix}\times f(a))\\
-\text{identity law of }\text{unfold}:\quad & =f(a)\quad.
-\end{align*}
+} yield h_n_k(m)
+\end_layout
\end_inset
-It follows that
-\begin_inset Formula $\psi_{u}^{A}=f$
-\end_inset
+Substituting the code of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+q
+\end_layout
-.
-
-\begin_inset Formula $\square$
\end_inset
+ (but not yet expanding
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+h_n_k
\end_layout
-\begin_layout Standard
-We conclude this Appendix with the proof of a type identity dual to the
- Church-Yoneda identity
-\begin_inset Index idx
+\end_inset
+
+), we find:
+\begin_inset listings
+inline false
status open
\begin_layout Plain Layout
-Church-co-Yoneda identity
+
+val q_map_h: M[M[Unit]] = for {
\end_layout
-\end_inset
+\begin_layout Plain Layout
- shown in Statement
-\begin_inset space ~
-\end_inset
+ s <- get
+\end_layout
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-Church-Yoneda-identity"
-plural "false"
-caps "false"
-noprefix "false"
+} yield h_n_k(set(s + 1))
+\end_layout
\end_inset
-.
- That identity has no accepted name, and this book calls it the
-\begin_inset Quotes eld
-\end_inset
+The function call
+\begin_inset listings
+inline true
+status open
-Church-co-Yoneda
-\begin_inset Quotes erd
-\end_inset
+\begin_layout Plain Layout
- identity.
+h_n_k(set(s + 1))
\end_layout
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-Church-co-Yoneda"
+\end_inset
+ repeats
+\begin_inset Formula $n$
\end_inset
+ times the effect of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-Church-co-Yoneda"
-plural "false"
-caps "false"
-noprefix "false"
+set(s + 1)
+\end_layout
\end_inset
+, but
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+s
\end_layout
-\begin_layout Standard
-For any covariant functors
-\begin_inset Formula $F$
\end_inset
- and
-\begin_inset Formula $G$
-\end_inset
+ is a fixed value in that scope, so the result is equal to just a single
+ effect:
+\begin_inset listings
+inline false
+status open
-:
-\begin_inset Formula
-\[
-G^{\nu X.\,F^{X}}\cong\exists A.\,(A\rightarrow F^{A})\times G^{A}\quad.
-\]
+\begin_layout Plain Layout
-\end_inset
+val q_map_h: M[M[Unit]] = for {
+\end_layout
+\begin_layout Plain Layout
+ s <- get
\end_layout
-\begin_layout Subparagraph
-Proof
+\begin_layout Plain Layout
+
+} yield set(s + 1)
\end_layout
-\begin_layout Standard
-Denote for brevity
-\begin_inset Formula $C\triangleq\nu X.\,F^{X}$
\end_inset
-.
- The existential type is rewritten as:
-\begin_inset Formula
-\[
-\exists A.\,(A\rightarrow F^{A})\times G^{A}=\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R\quad.
-\]
+This is the same value as
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+q
+\end_layout
\end_inset
-We will demonstrate the isomorphism if we define functions
+ itself.
+\end_layout
+
+\begin_layout Standard
+The next sub-expression is
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-toG
+h_n_k(q_map_h)
\end_layout
\end_inset
- and
+, which equals
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-fromG
+h_n_k(q)
\end_layout
\end_inset
- that are mutual inverses, with type signatures:
-\begin_inset Formula
-\[
-\text{toG}:(\exists A.\,(A\rightarrow F^{A})\times G^{A})\rightarrow G^{C}\quad,\quad\quad\text{fromG}:G^{C}\rightarrow\exists A.\,(A\rightarrow F^{A})\times G^{A}\quad.
-\]
+:
+\begin_inset listings
+inline false
+status open
-\end_inset
+\begin_layout Plain Layout
-The first type signature can be implemented as:
-\begin_inset Formula
-\begin{align*}
- & \text{toG}:\big(\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R\big)\rightarrow G^{C}\quad,\\
- & \text{toG}\triangleq k^{:\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R}\rightarrow k^{G^{C}}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)\quad,
-\end{align*}
+val h_q_map_h: M[M[Unit]] = for {
+\end_layout
-\end_inset
+\begin_layout Plain Layout
-where
-\begin_inset Formula $\psi_{u}^{A}$
-\end_inset
+ x_1 <- q
+\end_layout
- is the anamorphism of type
-\begin_inset Formula $A\rightarrow C$
-\end_inset
+\begin_layout Plain Layout
- defined in Statement
-\begin_inset space ~
-\end_inset
+ ...
+\end_layout
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-coalgebra-morphism-unfold"
-plural "false"
-caps "false"
-noprefix "false"
+ x_n <- q
+\end_layout
-\end_inset
+\begin_layout Plain Layout
-.
+} yield x_k
\end_layout
-\begin_layout Standard
-The function
+\end_inset
+
+Substituting the code for
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-fromG
+q
\end_layout
\end_inset
- is implemented as:
-\begin_inset Formula
-\begin{align*}
- & \text{fromG}:G^{C}\rightarrow\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R\quad,\\
- & \text{fromG}\triangleq g^{:G^{C}}\rightarrow\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R}\rightarrow p^{C}(\text{unfix}\times g)\quad.
-\end{align*}
-
-\end_inset
+, we get:
+\begin_inset listings
+inline false
+status open
+\begin_layout Plain Layout
+val h_q_map_h: M[M[Unit]] = for {
\end_layout
-\begin_layout Standard
-It remains to prove the two directions of the isomorphism roundtrip:
+\begin_layout Plain Layout
+
+ x_1 <- for {
\end_layout
-\begin_layout Standard
+\begin_layout Plain Layout
-\series bold
-(1)
-\series default
- For any
-\begin_inset Formula $g:G^{C}$
-\end_inset
+ s <- get
+\end_layout
- we have:
-\begin_inset Formula $\text{toG}\,(\text{fromG}\,(g))=g$
-\end_inset
+\begin_layout Plain Layout
-.
+ } yield set(s + 1)
\end_layout
-\begin_layout Standard
+\begin_layout Plain Layout
-\series bold
-(2)
-\series default
- For any
-\begin_inset Formula $k:\exists A.\,(A\rightarrow F^{A})\times G^{A}$
-\end_inset
+ ...
+\end_layout
- we have:
-\begin_inset Formula $\text{fromG}\,(\text{toG}\,(k))=k$
-\end_inset
+\begin_layout Plain Layout
-.
+ x_n <- for {
\end_layout
-\begin_layout Standard
-To prove item
-\series bold
-(1)
-\series default
-:
-\begin_inset Formula
-\begin{align*}
- & \text{toG}\,(\gunderline{\text{fromG}}\,(g))=\gunderline{\text{toG}}\,\big(\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R}\rightarrow p^{C}(\text{unfix}\times g)\big)\\
- & =\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)^{C}(\text{unfix}\times g)\\
- & =g\triangleright(\psi_{\text{unfix}}^{C})^{\uparrow F}\quad.
-\end{align*}
+\begin_layout Plain Layout
-\end_inset
+ s <- get
+\end_layout
-We note that
-\begin_inset Formula $\psi_{\text{unfix}}^{C}$
-\end_inset
+\begin_layout Plain Layout
- is the identity function (
-\begin_inset Formula $\text{id}^{:C\rightarrow C}$
-\end_inset
+ } yield set(s + 1)
+\end_layout
-) because it is the unique
-\begin_inset Formula $F$
-\end_inset
+\begin_layout Plain Layout
--coalgebra morphism of type
-\begin_inset Formula $C\rightarrow C$
-\end_inset
+} yield x_k
+\end_layout
- by Statement
-\begin_inset space ~
\end_inset
+Eliminate the nested
+\begin_inset listings
+inline true
+status open
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-greatest-fixpoint-Church-encoding-morphism"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Plain Layout
+
+for
+\end_layout
\end_inset
-.
- It follows that:
-\begin_inset Formula
-\[
-\text{toG}\,(\text{fromG}\,(g))=g\triangleright(\psi_{\text{unfix}}^{C})^{\uparrow F}=g\triangleright\text{id}^{\uparrow F}=g\quad.
-\]
+ and obtain:
+\begin_inset listings
+inline false
+status open
-\end_inset
+\begin_layout Plain Layout
+
+val h_q_map_h: M[M[Unit]] = for {
+\end_layout
+\begin_layout Plain Layout
+ s <- get
\end_layout
-\begin_layout Standard
-To prove item
-\series bold
-(2)
-\series default
-, apply both sides to a type
-\begin_inset Formula $R$
-\end_inset
+\begin_layout Plain Layout
- and a value
-\begin_inset Formula $p^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R}$
-\end_inset
+ x_1 = set(s + 1)
+\end_layout
-:
-\begin_inset Formula
-\begin{align*}
-\text{expect to equal }k^{R}(p):\quad & \big(\text{fromG}\,(\text{toG}\,(k))\big)^{R}(p)=p^{C}(\text{unfix}\times\text{toG}\,(k))\\
- & =p^{C}\big(\text{unfix}\times k^{G^{C}}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)\big)\quad.
-\end{align*}
+\begin_layout Plain Layout
-\end_inset
+ ...
+\end_layout
-To proceed, we need to use the naturality law of
-\begin_inset Formula $k$
-\end_inset
+\begin_layout Plain Layout
-:
-\begin_inset Formula
-\[
-\text{for all }Q,R,f^{:Q\rightarrow R},q^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow Q}:\quad k^{R}(\forall A.\:q^{A}\bef f)=f(k^{Q}(q))\quad.
-\]
+ s <- get
+\end_layout
-\end_inset
+\begin_layout Plain Layout
-Setting the following parameters in this law:
-\begin_inset Formula
-\[
-Q=G^{C}\quad,\quad\quad f=t^{:G^{C}}\rightarrow p^{C}(\text{unfix}\times t)\quad,\quad q=\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\quad,
-\]
+ x_n = set(s + 1)
+\end_layout
-\end_inset
+\begin_layout Plain Layout
-we obtain:
-\begin_inset Formula
-\begin{align*}
- & k^{R}(\forall A.\:u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F}))\\
- & =p^{C}\big(\text{unfix}\times k^{G^{C}}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)\big)\quad.
-\end{align*}
+} yield x_k
+\end_layout
\end_inset
-We expect the left-hand side to equal
-\begin_inset Formula $k^{R}(p)$
+The code runs
+\begin_inset Formula $n$
\end_inset
-, so the remaining difference is:
-\begin_inset Formula
-\begin{align*}
- & p\overset{?}{=}\forall A.\:u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F})\quad,\\
-\text{or equivalently}:\quad & p^{A}(u^{:A\rightarrow F^{A}}\times g^{:G^{A}})\overset{?}{=}p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F})\quad.
-\end{align*}
+ times the effect of
+\begin_inset listings
+inline true
+status open
-\end_inset
+\begin_layout Plain Layout
-This should hold for all types
-\begin_inset Formula $A$
-\end_inset
+get
+\end_layout
- and for all
-\begin_inset Formula $g^{:G^{A}}$
\end_inset
-,
-\begin_inset Formula $u^{:A\rightarrow F^{A}}$
-\end_inset
+ but actually never runs the effect of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+set
+\end_layout
-,
-\begin_inset Formula $p:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R$
\end_inset
-.
- We may assume that all such
-\begin_inset Formula $p$
+: the
+\emph on
+unevaluated
+\emph default
+ effectful value
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+set(s + 1)
+\end_layout
+
\end_inset
- obey their relational naturality law:
-\begin_inset Formula
-\[
-\forall A,B,f^{:A\rightarrow B}:\quad\text{if}\quad u^{:A\rightarrow F^{A}}\bef f^{\uparrow F}=f\bef v^{:B\rightarrow F^{B}}\quad\text{then}\quad p^{A}(u\times a)=p^{B}(v\times a\triangleright f^{\uparrow F})\quad.
-\]
+ is merely assigned to each
+\begin_inset listings
+inline true
+status open
-\end_inset
+\begin_layout Plain Layout
-We set the following parameters in this law,
-\begin_inset Formula
-\[
-B=C\quad,\quad a=g\quad,\quad f=\psi_{u}^{A}\quad,\quad v=\text{unfix}\quad,
-\]
+x_i
+\end_layout
\end_inset
-and obtain:
-\begin_inset Formula
-\[
-p^{A}(u\times g)=p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F})\quad.
-\]
+ and then returned under a monad wrapper.
+ So, the code shown above for
+\begin_inset listings
+inline true
+status open
-\end_inset
+\begin_layout Plain Layout
-This will complete the proof of item
-\series bold
-(2)
-\series default
- as long as the precondition holds:
-\begin_inset Formula
-\begin{align*}
- & u^{:A\rightarrow F^{A}}\bef f^{\uparrow F}\overset{?}{=}f\bef v^{:B\rightarrow F^{B}}\quad,\\
-\text{or equivalently}:\quad & u\bef(\psi_{u}^{A})^{\uparrow F}\overset{?}{=}\psi_{u}^{A}\bef\text{unfix}\quad.
-\end{align*}
+h_q_map_h
+\end_layout
\end_inset
-This holds by Statement
-\begin_inset space ~
-\end_inset
+ can be simplified to just a single
+\begin_inset listings
+inline true
+status open
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-coalgebra-morphism-unfold"
-plural "false"
-caps "false"
-noprefix "false"
+get
+\end_layout
\end_inset
-: it is the
-\begin_inset Formula $F$
-\end_inset
+:
+\begin_inset listings
+inline false
+status open
--coalgebra morphism law of
-\begin_inset Formula $\psi_{u}^{A}$
-\end_inset
+\begin_layout Plain Layout
-.
-
-\begin_inset Formula $\square$
-\end_inset
+val h_q_map_h: M[M[Unit]] = for {
+\end_layout
+\begin_layout Plain Layout
+ s <- get
+\end_layout
+
+\begin_layout Plain Layout
+
+} yield set(s + 1)
\end_layout
-\begin_layout Standard
-The Church-co-Yoneda identity can be used to prove the Church encoding formula
- for simultaneous greatest fixpoints of several functors, similarly to what
- we did in Section
-\begin_inset space ~
\end_inset
+This is again just equal to
+\begin_inset listings
+inline true
+status open
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Least-fixpoints-of-mutually-recursive-types"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Plain Layout
+
+q
+\end_layout
\end_inset
.
- For simplicity, we will now show a proof for just two mutually recursive
- types; the proof can be extended to any number of types.
-
\end_layout
\begin_layout Standard
-We will first prove a property of nested fixpoints.
-\end_layout
-
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-nested-greatest-fixpoints"
-
-\end_inset
+It remains to apply
+\begin_inset listings
+inline true
+status open
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-nested-greatest-fixpoints"
-plural "false"
-caps "false"
-noprefix "false"
+flatten
+\end_layout
\end_inset
+ to
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+h_q_map_h
\end_layout
-\begin_layout Standard
-For any bifunctor
-\begin_inset Formula $F$
\end_inset
-, the following equivalence holds:
-\begin_inset Formula
-\[
-\nu A.\,(\nu B.\,F^{A,B})\cong\nu B.\,F^{B,B}\quad.
-\]
+, which is the same as
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatten(q)
+\end_layout
\end_inset
+ and was already computed as
+\begin_inset listings
+inline true
+status open
-\end_layout
+\begin_layout Plain Layout
-\begin_layout Subparagraph
-Proof
+flatten_q
\end_layout
-\begin_layout Standard
-Denote
-\begin_inset Formula $G^{A,C}\triangleq(A\rightarrow C)\times A$
\end_inset
- and write the Church encoding for the fixpoints:
-\begin_inset Formula
-\[
-\nu A.\,(\nu B.\,F^{A,B})=\exists A.\,(A\rightarrow\nu B.\,F^{A,B})\times A=\exists A.\,G^{A,\,\nu B.\,F^{A,B}}\quad.
-\]
+ above:
+\begin_inset listings
+inline false
+status open
-\end_inset
+\begin_layout Plain Layout
-View
-\begin_inset Formula $A$
-\end_inset
+val rhs: M[Unit] = for { // This is flatten(h_q_map_h) === flatten(q).
+\end_layout
- as fixed and use the Church-co-Yoneda identity (Statement
-\begin_inset space ~
-\end_inset
+\begin_layout Plain Layout
+ s <- get
+\end_layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-Church-co-Yoneda"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Plain Layout
-\end_inset
+ _ <- set(s + 1)
+\end_layout
-):
-\begin_inset Formula
-\begin{align*}
- & G^{A,\,\nu B.\,F^{A,B}}\cong\exists B.\,(B\rightarrow F^{A,B})\times\gunderline{G^{A,B}}\\
- & =\exists B.\,(B\rightarrow F^{A,B})\times(A\rightarrow B)\times A\\
- & =\exists B.\,(A\rightarrow B)\times H^{A,B}\quad,
-\end{align*}
+\begin_layout Plain Layout
-\end_inset
+} yield ()
+\end_layout
-where we defined
-\begin_inset Formula $H$
\end_inset
- by:
-\begin_inset Formula
-\[
-H^{A,B}\triangleq(B\rightarrow F^{A,B})\times A\quad.
-\]
-\end_inset
+\end_layout
-Now we can simplify the nested fixpoints:
-\begin_inset Formula
-\begin{align*}
-\text{expect }\nu B.\,F^{B,B}:\quad & \nu A.\,(\nu B.\,F^{A,B})=\gunderline{\exists A.\,\exists B.}\,(A\rightarrow B)\times H^{A,B}\\
-\text{co-Fubini theorem (Statement~\ref{subsec:Statement-commute-existential})}:\quad & \cong\exists B.\,\exists A.\,(A\rightarrow B)\times H^{A,B}\\
-\text{co-Yoneda identity}:\quad & \cong\exists B.\,\gunderline{H^{B,B}}=\exists B.\,(B\rightarrow F^{B,B})\times B\\
-\text{Church encoding}:\quad & \cong\nu B.\,F^{B,B}\quad.
-\end{align*}
+\begin_layout Standard
+The left-hand side and the right-hand side of the law differ only in the
+
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+set
+\end_layout
\end_inset
+ operation (
+\begin_inset listings
+inline true
+status open
-\end_layout
+\begin_layout Plain Layout
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-mutually-recursive-greatest-fixpoints"
+set(s + n)
+\end_layout
\end_inset
+ vs.
+\begin_inset space ~
+\end_inset
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-mutually-recursive-greatest-fixpoints"
-plural "false"
-caps "false"
-noprefix "false"
-\end_inset
+\begin_inset listings
+inline true
+status open
+\begin_layout Plain Layout
+set(s + 1)
\end_layout
-\begin_layout Standard
-Given any bifunctors
-\begin_inset Formula $F$
\end_inset
-,
-\begin_inset Formula $G$
+).
+ So, they are equal only when
+\begin_inset Formula $n=1$
\end_inset
-, define
-\begin_inset Formula $T$
-\end_inset
+ (that is, for
+\begin_inset listings
+inline true
+status open
- and
-\begin_inset Formula $U$
-\end_inset
+\begin_layout Plain Layout
- as the simultaneous greatest fixpoints of two type equations:
-\begin_inset Formula
-\[
-T=F^{T,U}\quad,\quad\quad U=G^{T,U}\quad.
-\]
+h_1_1
+\end_layout
\end_inset
-Then the types
-\begin_inset Formula $T$
+).
+ It follows that, for all
+\begin_inset Formula $n\ge2$
\end_inset
- and
-\begin_inset Formula $U$
+ and for all
+\begin_inset Formula $1\le k\le n$
\end_inset
- can be expressed as:
-\begin_inset Formula
-\begin{align*}
- & T\cong\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times A\quad,\\
- & U\cong\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times B\quad.
-\end{align*}
-
+, the function
+\begin_inset Formula $h_{n,k}$
\end_inset
+ of type
+\begin_inset Formula $M^{X}\rightarrow M^{X}$
+\end_inset
-\end_layout
+ violates the composition law of monad morphisms when applied to the chosen
+ value
+\begin_inset Formula $q:M^{M^{X}}$
+\end_inset
-\begin_layout Subparagraph
-Proof
+.
\end_layout
\begin_layout Standard
-If
-\begin_inset Formula $T$
-\end_inset
-
- and
-\begin_inset Formula $U$
-\end_inset
-
- are fixed (and equal to the correct greatest fixpoints) then we can write:
+Let us now summarize this derivation in code notation.
+ The left-hand side of the composition law is:
\begin_inset Formula
-\[
-T=\nu A.\,F^{A,U}\quad,\quad\quad U=\nu B.\,G^{T,B}\quad.
-\]
+\begin{align*}
+ & \text{ftn}_{M}(q)=s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}}\quad,\\
+ & h_{n,k}(\text{ftn}_{M}(q))=s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+n)^{:\text{Int}}\quad.
+\end{align*}
\end_inset
-Now we can substitute
-\begin_inset Formula $U$
+Here we used the fact that
+\begin_inset Formula $h_{n,k}(m)$
\end_inset
- into the equation for
-\begin_inset Formula $T$
+ repeats
+\begin_inset Formula $n$
\end_inset
-:
-\begin_inset Formula
-\[
-T=\nu A.\,F^{A,\,\nu B.\,G^{T,B}}\quad.
-\]
-
+ times the effect of
+\begin_inset Formula $m$
\end_inset
-The last line is a fixpoint equation involving only
-\begin_inset Formula $T$
+ (and that effect increments the value
+\begin_inset Formula $s$
\end_inset
-, so we may express
-\begin_inset Formula $T$
-\end_inset
+).
+
+\end_layout
- as the greatest fixpoint of that equation.
- Then we get:
+\begin_layout Standard
+Turn to the right-hand side of the law and calculate:
\begin_inset Formula
\begin{align*}
- & T=\nu C.\,\nu A.\,F^{A,\,\nu B.\,G^{C,B}}\\
-\text{use Statement~\ref{subsec:Statement-nested-greatest-fixpoints} and set }A=C:\quad & \cong\gunderline{\nu A.}\,F^{A,\,\nu B.\,G^{A,B}}\\
-\text{use Church encoding}:\quad & \cong\exists A.\:(A\rightarrow F^{A,\,\nu B.\,G^{A,B}})\times A\\
-\text{define }N^{A,C}\triangleq(A\rightarrow F^{A,C})\times A:\quad & =\exists A.\:N^{A,\,\nu B.\,G^{A,B}}\\
-\text{Church-co-Yoneda identity (Statement~\ref{subsec:Statement-Church-co-Yoneda})}:\quad & \cong\gunderline{\exists A.\,\exists B.}\,(B\rightarrow G^{A,B})\times N^{A,B}\quad.
+ & q\triangleright h_{n,k}^{\uparrow M}=s^{:\text{Int}}\rightarrow(\_^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}})\times s=q\quad,\\
+ & h_{n,k}(q\triangleright h_{n,k}^{\uparrow M})=s^{:\text{Int}}\rightarrow(\_^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}})\times s=q\quad,\\
+ & \text{ftn}_{M}(q)=s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}}\quad.
\end{align*}
\end_inset
-Writing out the definition of
-\begin_inset Formula $N^{A,B}$
+The condition for the two sides of the law to be equal is:
+\begin_inset Formula
+\[
+s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+n)^{:\text{Int}}\overset{?}{=}s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}}\quad.
+\]
+
\end_inset
-, we obtain the claimed Church encoding for
-\begin_inset Formula $T$
+This holds only if
+\begin_inset Formula $n=1$
\end_inset
-:
-\begin_inset Formula
-\[
-T\cong\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times A\quad.
-\]
+.
+\end_layout
+\begin_layout Standard
+It follows that
+\begin_inset Formula $h_{1,1}$
\end_inset
- The formula for
-\begin_inset Formula $U$
+ (which is an identity function of type
+\begin_inset Formula $M^{X}\rightarrow M^{X}$
\end_inset
- is derived similarly.
+) is the only monad morphism that fits the required type.
\begin_inset Formula $\square$
\end_inset
@@ -52221,7 +55583,7 @@ T\cong\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})
\end_layout
\begin_layout Chapter
-Solutions of some exercises
+Solutions for selected exercises
\end_layout
\begin_layout Addsec
@@ -58405,7 +61767,14 @@ M^{N^{A}} & \gamma_{M}^{\uparrow M}\bef\text{ftn}_{M}
\hline A & \text{pu}_{M}\\
M^{A} & \text{id}\\
M^{N^{A}} & \gamma_{M}^{\uparrow M}\bef\text{ftn}_{M}
-\end{array}\quad,\\
+\end{array}\quad,
+\end{align*}
+
+\end_inset
+
+
+\begin_inset Formula
+\begin{align*}
\text{right-hand side}:\quad & \text{ftn}_{N}\bef\gamma_{M}=\,\begin{array}{|c||cc|}
& A & M^{A}\\
\hline A & \text{id} & \bbnum 0\\
@@ -59658,8 +63027,12 @@ status open
\begin_layout Plain Layout
-def flatten[A](p: List[List[A]]): List[A] = p.takeWhile(_.nonEmpty).flatten
- // $
+def flatten[A](p: List[List[A]]): List[A] =
+\end_layout
+
+\begin_layout Plain Layout
+
+ p.takeWhile(_.nonEmpty).flatten // $
\backslash
color{dkgreen}
\backslash
@@ -59948,7 +63321,7 @@ noprefix "false"
(a)
\series default
Denote for brevity
-\begin_inset Formula $\text{Cod}_{F}^{M,A}\triangleq C^{A}$
+\begin_inset Formula $C^{A}\triangleq\text{Cod}_{F}^{M,A}$
\end_inset
.
@@ -60048,7 +63421,7 @@ In the last line, we have used the naturality law of
\end_inset
-which follows from the associativity law of
+which disappears due to the associativity law of
\begin_inset Formula $\text{ftn}_{M}$
\end_inset
@@ -60072,10 +63445,14 @@ flatMap
\end_inset
- method must have the type signature:
+ method of
+\begin_inset Formula $P$
+\end_inset
+
+ must have the type signature:
\begin_inset Formula
\[
-\text{flm}_{L}:\big((A\rightarrow X)\rightarrow M^{X}\big)\rightarrow(A\rightarrow(B\rightarrow X)\rightarrow M^{X})\rightarrow(B\rightarrow X)\rightarrow M^{X}\quad.
+\text{flm}_{P}:\big((A\rightarrow X)\rightarrow M^{X}\big)\rightarrow(A\rightarrow(B\rightarrow X)\rightarrow M^{X})\rightarrow(B\rightarrow X)\rightarrow M^{X}\quad.
\]
\end_inset
@@ -60087,8 +63464,8 @@ Choose
; now we need to implement the type signature:
\begin_inset Formula
\begin{align*}
- & \text{flm}_{L}:\big((A\rightarrow X)\rightarrow\bbnum 1+X\big)\rightarrow\left(A\rightarrow(B\rightarrow X)\rightarrow\bbnum 1+X\right)\rightarrow(B\rightarrow X)\rightarrow\bbnum 1+X\quad,\\
- & \text{flm}_{L}\triangleq p^{:(A\rightarrow X)\rightarrow\bbnum 1+X}\rightarrow q^{:\left(A\rightarrow(B\rightarrow X)\rightarrow\bbnum 1+X\right)}\rightarrow r^{:B\rightarrow X}\rightarrow\text{???}^{:\bbnum 1+X}\quad.
+ & \text{flm}_{P}:\big((A\rightarrow X)\rightarrow\bbnum 1+X\big)\rightarrow\left(A\rightarrow(B\rightarrow X)\rightarrow\bbnum 1+X\right)\rightarrow(B\rightarrow X)\rightarrow\bbnum 1+X\quad,\\
+ & \text{flm}_{P}\triangleq p^{:(A\rightarrow X)\rightarrow\bbnum 1+X}\rightarrow q^{:\left(A\rightarrow(B\rightarrow X)\rightarrow\bbnum 1+X\right)}\rightarrow r^{:B\rightarrow X}\rightarrow\text{???}^{:\bbnum 1+X}\quad.
\end{align*}
\end_inset
@@ -60142,23 +63519,135 @@ Can this function ever return a value of type
, which is not guaranteed to return nonempty values.
So, the only way of implementing
-\begin_inset listings
-inline true
-status open
+\begin_inset Formula $\text{flm}_{P}$
+\end_inset
-\begin_layout Plain Layout
+ via fully parametric code is to return the constant value
+\begin_inset Formula $1+\bbnum 0^{:X}$
+\end_inset
-flatMap
+.
+ This would lose information and violate an identity law of monads.
\end_layout
+\begin_layout Standard
+
+\series bold
+(c)
+\series default
+ In general, the type
+\begin_inset Formula $\forall A.\,M^{A}\rightarrow\forall X.\,(A\rightarrow F^{X})\rightarrow F^{M^{X}}$
+\end_inset
+
+ is equivalent (via the contravariant Yoneda identity) to
+\begin_inset Formula $\forall X.\,M^{F^{X}}\rightarrow F^{M^{X}}$
\end_inset
- via fully parametric code is to return the constant value
-\begin_inset Formula $1+\bbnum 0^{:X}$
+.
+ This cannot be implemented as a natural transformation for arbitrary monads
+
+\begin_inset Formula $M$
+\end_inset
+
+ and functors
+\begin_inset Formula $F$
\end_inset
.
- This would lose information and violate an identity law of monads.
+\end_layout
+
+\begin_layout Standard
+A simple counterexample is found with
+\begin_inset Formula $M^{A}\triangleq R\rightarrow A$
+\end_inset
+
+ and
+\begin_inset Formula $F^{A}\triangleq\bbnum 1+A$
+\end_inset
+
+.
+ Consider a function
+\begin_inset Formula $f$
+\end_inset
+
+ with the type signature of a monad morphism
+\begin_inset Formula $\forall A.\,M^{A}\rightarrow\text{Cod}_{F}^{M,A}$
+\end_inset
+
+ with these
+\begin_inset Formula $F$
+\end_inset
+
+ and
+\begin_inset Formula $M$
+\end_inset
+
+:
+\begin_inset Formula
+\[
+f:\forall A.\,(R\rightarrow A)\rightarrow\forall X.\,(A\rightarrow\bbnum 1+X)\rightarrow\bbnum 1+(R\rightarrow X)\quad.
+\]
+
+\end_inset
+
+Can
+\begin_inset Formula $f$
+\end_inset
+
+ be a monad morphism? We can simplify the type of
+\begin_inset Formula $f$
+\end_inset
+
+ by using the covariant Yoneda identity:
+\begin_inset Formula
+\begin{align*}
+ & \forall A.\,(R\rightarrow A)\rightarrow\forall X.\,(A\rightarrow\bbnum 1+X)\rightarrow\bbnum 1+(R\rightarrow X)\\
+ & \cong\forall X.\,(R\rightarrow\bbnum 1+X)\rightarrow\bbnum 1+(R\rightarrow X)\quad.
+\end{align*}
+
+\end_inset
+
+A function of type
+\begin_inset Formula $\forall X.\,(R\rightarrow\bbnum 1+X)\rightarrow\bbnum 1+(R\rightarrow X)$
+\end_inset
+
+ cannot make decisions based on its argument (of type
+\begin_inset Formula $R\rightarrow\bbnum 1+X$
+\end_inset
+
+) as
+\begin_inset Formula $R$
+\end_inset
+
+ and
+\begin_inset Formula $X$
+\end_inset
+
+ are unknown types.
+ The function cannot always return
+\begin_inset Formula $\bbnum 0+(R\rightarrow X)$
+\end_inset
+
+ as the function of type
+\begin_inset Formula $R\rightarrow\bbnum 1+X$
+\end_inset
+
+ could fail to return a value of type
+\begin_inset Formula $X$
+\end_inset
+
+ for some argument values
+\begin_inset Formula $r^{:R}$
+\end_inset
+
+.
+ So, the function must always return
+\begin_inset Formula $\bbnum 1+\bbnum 0^{:R\rightarrow X}$
+\end_inset
+
+.
+ But that code would lose information and fail the identity law of monad
+ morphisms.
\end_layout
\begin_layout Addsec
diff --git a/sofp-src/lyx/sofp-applicative.lyx b/sofp-src/lyx/sofp-applicative.lyx
index a58465622..b9f5d66d5 100644
--- a/sofp-src/lyx/sofp-applicative.lyx
+++ b/sofp-src/lyx/sofp-applicative.lyx
@@ -6339,7 +6339,7 @@ zipFold
\end_inset
- (shown above) follows unambiguously from its type signature.
+ can be derived unambiguously from its type signature.
So, let us use the
\begin_inset Index idx
status open
@@ -6386,7 +6386,7 @@ literal "false"
\end_inset
- to generate the code automatically:
+ to generate the code automatically (equivalent code is shown above):
\begin_inset listings
inline false
status open
@@ -8336,7 +8336,7 @@ combinators
\end_layout
\begin_layout Standard
-We will apply these parsing techniques to some toy
+We will now apply these parsing techniques to some toy
\begin_inset Quotes eld
\end_inset
@@ -9744,6 +9744,13 @@ e, monoidal, and other functionality for building up large parsers from
\begin_layout Subsection
Functor block syntax for applicative functors
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Functor-block-syntax-for-applicative"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -16290,505 +16297,484 @@ zip
.
So, each monad construction gives at least one applicative construction.
- We will focus on constructions that produce applicative functors and have
- no analogous monad constructions.
-\end_layout
-
-\begin_layout Paragraph
-Type parameters
-\end_layout
-
-\begin_layout Standard
-Three type constructions are based on using just type parameters: a constant
- functor,
-\begin_inset Formula $L^{A}\triangleq Z$
+ We will focus on constructions that produce applicative functors and do
+
+\emph on
+not
+\emph default
+ come from monad constructions.
+ The results are summarized in Table
+\begin_inset space ~
\end_inset
-, the identity functor
-\begin_inset Formula $L^{A}\triangleq A$
-\end_inset
-, and the functor composition,
-\begin_inset Formula $L^{A}\triangleq F^{G^{A}}$
-\end_inset
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:Constructions-of-applicative-functors"
+plural "false"
+caps "false"
+noprefix "false"
- (also written as
-\begin_inset Formula $L\triangleq F\circ G$
\end_inset
-).
+.
\end_layout
\begin_layout Standard
-Given a fixed
-\emph on
-monoid
-\emph default
- type
-\begin_inset Formula $Z$
-\end_inset
-
-, the constant functor
-\begin_inset Formula $L^{A}\triangleq Z$
-\end_inset
-
- is applicative.
- To see this, consider the operation
-\begin_inset listings
-inline true
+\begin_inset Float table
+wide false
+sideways false
status open
+\begin_layout Plain Layout
+\align center
+\begin_inset Tabular
+
+
+
+
+
+
+|
+\begin_inset Text
+
\begin_layout Plain Layout
-zip
+\series bold
+\size small
+Construction
\end_layout
\end_inset
+ |
+
+\begin_inset Text
- of type
-\begin_inset Formula $L^{A}\times L^{B}\rightarrow L^{A\times B}$
-\end_inset
+\begin_layout Plain Layout
-, which in this case becomes just
-\begin_inset Formula $Z\times Z\rightarrow Z$
-\end_inset
+\series bold
+\size small
+Type notation
+\end_layout
-, the monoid
-\begin_inset Formula $Z$
\end_inset
-
-'s
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-combine
+\series bold
+\size small
+Assumptions
\end_layout
\end_inset
-
- function.
- The value
-\begin_inset listings
-inline true
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-wu
+\size footnotesize
+fixed type
\end_layout
\end_inset
+ |
+
+\begin_inset Text
- of type
-\begin_inset Formula $L^{\bbnum 1}=Z$
-\end_inset
-
- is just the monoid
-\begin_inset Formula $Z$
-\end_inset
+\begin_layout Plain Layout
-'s empty value (
-\begin_inset Formula $e_{Z}$
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq Z$
\end_inset
-).
- The laws of
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-zip
\end_layout
\end_inset
+ |
+
+\begin_inset Text
- then reduce to the monoid laws of
+\begin_layout Plain Layout
+
+\size footnotesize
\begin_inset Formula $Z$
\end_inset
-.
- For the same reason, the applicative functor
-\begin_inset Formula $L^{A}\triangleq Z$
-\end_inset
+ is a monoid
+\end_layout
- will be commutative if the monoid
-\begin_inset Formula $Z$
\end_inset
+ |
+
+
+|
+\begin_inset Text
- is commutative.
+\begin_layout Plain Layout
+
+\size footnotesize
+identity
\end_layout
-\begin_layout Standard
-Comparing this with the corresponding monad construction, we note that
-\begin_inset Formula $L^{A}\triangleq Z$
\end_inset
+ |
+
+\begin_inset Text
- is
-\emph on
-not
-\emph default
- a monad unless
-\begin_inset Formula $Z=\bbnum 1$
-\end_inset
+\begin_layout Plain Layout
-.
- For an arbitrary monoid type
-\begin_inset Formula $Z$
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq A$
\end_inset
-, the functor
-\begin_inset Formula $L^{A}\triangleq Z$
-\end_inset
- is only a semimonad.
\end_layout
-\begin_layout Standard
-The identity functor
-\begin_inset Formula $L^{A}\triangleq A$
\end_inset
-
- is applicative and commutative: the
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-zip
-\end_layout
-
+\size footnotesize
+\begin_inset Formula $F$
\end_inset
- operation is the identity function of type
-\begin_inset Formula $A\times B\rightarrow A\times B$
-\end_inset
+ is commutative
+\end_layout
-, and the wrapped unit (
-\begin_inset listings
-inline true
-status open
+\end_inset
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-wu
+\size footnotesize
+composition
\end_layout
\end_inset
+ |
+
+\begin_inset Text
-) is just the unit value.
- All required laws hold for the identity function.
-\end_layout
-
-\begin_layout Standard
-The functor composition
-\begin_inset Formula $L\triangleq F\circ G$
-\end_inset
+\begin_layout Plain Layout
- of two applicative functors
-\begin_inset Formula $F$
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq G^{H^{A}}$
\end_inset
- and
-\begin_inset Formula $G$
-\end_inset
- is again applicative, unlike the functor composition of monads that often
- does not produce a new monad.
\end_layout
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-applicative-composition"
-
\end_inset
+ |
+
+\begin_inset Text
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-applicative-composition"
-plural "false"
-caps "false"
-noprefix "false"
-
+\size footnotesize
+\begin_inset Formula $G$
\end_inset
+ and
+\begin_inset Formula $H$
+\end_inset
+ are applicative functors
\end_layout
-\begin_layout Standard
-For any two applicative functors
-\begin_inset Formula $F$
\end_inset
-
- and
-\begin_inset Formula $G$
-\end_inset
-
- with lawful
-\begin_inset listings
-inline true
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-zip
+\size footnotesize
+product
\end_layout
\end_inset
-
- and
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-pure
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq P^{A}\times Q^{A}$
+\end_inset
+
+
\end_layout
\end_inset
+ |
+
+\begin_inset Text
- methods, the functor
-\begin_inset Formula $L^{A}\triangleq F^{G^{A}}$
-\end_inset
+\begin_layout Plain Layout
- is also applicative.
- Its
-\begin_inset listings
-inline true
-status open
+\size footnotesize
+\begin_inset Formula $P$
+\end_inset
-\begin_layout Plain Layout
+ and
+\begin_inset Formula $Q$
+\end_inset
-zip
+ are applicative
\end_layout
\end_inset
-
- and
-\begin_inset listings
-inline true
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-pure
+\size footnotesize
+co-product
\end_layout
\end_inset
+ |
+
+\begin_inset Text
- methods are defined by:
-\begin_inset Formula
-\begin{align*}
- & \text{zip}_{L}:F^{G^{A}}\times F^{G^{B}}\rightarrow F^{G^{A\times B}}\quad,\quad\quad\text{zip}_{L}\triangleq\text{zip}_{F}\bef\text{zip}_{G}^{\uparrow F}\quad,\\
- & \text{pu}_{L}:A\rightarrow F^{G^{A}}\quad,\quad\quad\text{pu}_{L}\triangleq\text{pu}_{G}\bef\text{pu}_{F}\quad,\quad\quad\text{wu}_{L}\triangleq\text{pu}_{F}(\text{wu}_{G})\quad.
-\end{align*}
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq Z+P^{A}$
\end_inset
-If
-\begin_inset Formula $F$
+
+\end_layout
+
\end_inset
+ |
+
+\begin_inset Text
- and
-\begin_inset Formula $G$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $Z$
\end_inset
- are commutative applicative functors, then so is
-\begin_inset Formula $L$
+ is a monoid and
+\begin_inset Formula $P$
\end_inset
-.
+ is applicative
\end_layout
-\begin_layout Subparagraph
-Proof
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+co-product
\end_layout
-\begin_layout Standard
-We note that the lifting to
-\begin_inset Formula $L$
\end_inset
+ |
+
+\begin_inset Text
- is defined by
-\begin_inset Formula $f^{\uparrow L}\triangleq f^{\uparrow G\uparrow F}=(f^{\uparrow G})^{\uparrow F}$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq P^{A}+Q^{A}$
\end_inset
-.
+
\end_layout
-\begin_layout Standard
-To verify the left identity law
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+conditions in Statement
\begin_inset space ~
\end_inset
-(
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:zip-left-identity-law"
+reference "subsec:Statement-co-product-with-co-pointed-applicative"
plural "false"
caps "false"
noprefix "false"
\end_inset
-):
-\begin_inset Formula
-\begin{align*}
-\text{expect to equal }p\triangleright\text{ilu}^{\uparrow L}:\quad & \text{zip}_{L}(\text{wu}_{L}\times p^{:F^{G^{A}}})=(\gunderline{\text{pu}_{F}(\text{wu}_{G})}\times p)\triangleright\gunderline{\text{zip}_{F}}\bef\text{zip}_{G}^{\uparrow F}\\
-\text{left identity law of }\text{zip}_{F}:\quad & =p\triangleright(g^{:G^{A}}\rightarrow\gunderline{\text{wu}_{G}\times g)^{\uparrow F}\bef\text{zip}_{G}^{\uparrow F}}\\
-\text{composition under }^{\uparrow F}:\quad & =p\triangleright\big(g^{:G^{A}}\rightarrow\gunderline{\text{zip}_{G}(\text{wu}_{G}\times g)}\big)^{\uparrow F}\\
-\text{left identity law of }\text{zip}_{G}:\quad & =p\triangleright(\gunderline{g\rightarrow g}\triangleright\text{ilu}^{\uparrow G})^{\uparrow F}=p\triangleright(\text{ilu}^{\uparrow G})^{\uparrow F}=p\triangleright\text{ilu}^{\uparrow L}\quad.
-\end{align*}
+
+\end_layout
\end_inset
+ |
+
+
+|
+\begin_inset Text
+\begin_layout Plain Layout
+\size footnotesize
+co-product
\end_layout
-\begin_layout Standard
-To verify the right identity law:
-\begin_inset Formula
-\begin{align*}
-\text{expect to equal }p\triangleright\text{iru}^{\uparrow L}:\quad & \text{zip}_{L}(p^{:F^{G^{A}}}\times\text{wu}_{L})=(p\times\gunderline{\text{pu}_{F}(\text{wu}_{G})})\triangleright\gunderline{\text{zip}_{F}}\bef\text{zip}_{G}^{\uparrow F}\\
-\text{right identity law of }\text{zip}_{F}:\quad & =p\triangleright(g^{:G^{A}}\rightarrow\gunderline{g\times\text{wu}_{G})^{\uparrow F}\bef\text{zip}_{G}^{\uparrow F}}\\
- & =p\triangleright\big(g^{:G^{A}}\rightarrow\gunderline{\text{zip}_{G}(g\times\text{wu}_{G})}\big)^{\uparrow F}\\
-\text{right identity law of }\text{zip}_{G}:\quad & =p\triangleright(\gunderline{g\rightarrow g\,\triangleright}\,\text{iru}^{\uparrow G})^{\uparrow F}=p\triangleright(\text{iru}^{\uparrow G})^{\uparrow F}=p\triangleright\text{iru}^{\uparrow L}\quad.
-\end{align*}
-
\end_inset
+ |
+
+\begin_inset Text
+\begin_layout Plain Layout
-\end_layout
-
-\begin_layout Standard
-To verify the associativity law, substitute the definition of
-\begin_inset Formula $\text{zip}_{L}$
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq P^{A}+Q^{A}\times R^{A}$
\end_inset
- into one side:
-\begin_inset Formula
-\begin{align*}
- & \quad\text{left-hand side}:\quad\\
- & \text{zip}_{L}\big(p\times\text{zip}_{L}(q\times r)\big)\triangleright\varepsilon_{1,23}^{\uparrow L}=\big(p\times\text{zip}_{L}(q\times r)\big)\triangleright\text{zip}_{F}\bef\text{zip}_{G}^{\uparrow F}\bef\gunderline{\varepsilon_{1,23}^{\uparrow L}}\\
- & \quad\text{definition of }^{\uparrow L}:\quad\\
- & =\big(p\times\big(\text{zip}_{F}(q\times r)\triangleright\gunderline{\text{zip}_{G}^{\uparrow F}}\big)\big)\triangleright\gunderline{\text{zip}_{F}}\bef\text{zip}_{G}^{\uparrow F}\bef\varepsilon_{1,23}^{\uparrow G\uparrow F}\\
- & \quad\text{naturality law of }\text{zip}_{F}:\quad\\
- & =\big(p\times\text{zip}_{F}(q\times r)\big)\triangleright\text{zip}_{F}\bef\big(g\times k^{:G^{B}\times G^{C}}\!\rightarrow\gunderline{g\times\text{zip}_{G}(k)\big)^{\uparrow F}\bef\text{zip}_{G}^{\uparrow F}\bef\varepsilon_{1,23}^{\uparrow G\uparrow F}}\\
- & \quad\text{composition under }^{\uparrow F}:\quad\\
- & =\text{zip}_{F}\big(p\times\text{zip}_{F}(q\times r)\big)\triangleright\big(g\times(h\times j)\rightarrow\text{zip}_{G}(g\times\text{zip}_{G}(h\times j))\triangleright\varepsilon_{1,23}^{\uparrow G}\big)^{\uparrow F}\quad.
-\end{align*}
+
+\end_layout
\end_inset
+ |
+
+\begin_inset Text
-Now rewrite the other side in a similar way:
-\begin_inset Formula
-\begin{align*}
- & \quad\text{right-hand side}:\quad\\
- & \text{zip}_{L}\big(\text{zip}_{L}(p\times q)\times r\big)\triangleright\varepsilon_{12,3}^{\uparrow L}=\big(\text{zip}_{L}(p\times q)\times r\big)\triangleright\text{zip}_{F}\bef\text{zip}_{G}^{\uparrow F}\bef\varepsilon_{12,3}^{\uparrow L}\\
- & \quad\text{definition of }^{\uparrow L}:\quad\\
- & =\big(\big(\text{zip}_{F}(p\times q)\triangleright\gunderline{\text{zip}_{G}^{\uparrow F}}\big)\times r\big)\triangleright\gunderline{\text{zip}_{F}}\bef\text{zip}_{G}^{\uparrow F}\bef\varepsilon_{12,3}^{\uparrow G\uparrow F}\\
- & \quad\text{naturality law of }\text{zip}_{F}:\quad\\
- & =\big(\text{zip}_{F}(p\times q)\times r\big)\triangleright\text{zip}_{F}\bef\big(k^{:G^{A}\times G^{B}}\!\times j\rightarrow\gunderline{\text{zip}_{G}(k)\times j\big)^{\uparrow F}\bef\text{zip}_{G}^{\uparrow F}\bef\varepsilon_{12,3}^{\uparrow G\uparrow F}}\\
- & \quad\text{composition under }^{\uparrow F}:\quad\\
- & =\text{zip}_{F}\big(\text{zip}_{F}(p\times q)\times r\big)\triangleright\big((g\times h)\times j\rightarrow\text{zip}_{G}(\text{zip}_{G}(g\times h)\times j)\triangleright\varepsilon_{12,3}^{\uparrow G}\big)^{\uparrow F}\quad.
-\end{align*}
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $P$
\end_inset
-The two sides become equal after using the associativity laws of
-\begin_inset Formula $\text{zip}_{F}$
+,
+\begin_inset Formula $Q$
\end_inset
- and
-\begin_inset Formula $\text{zip}_{G}$
+ are polynomial and
+\begin_inset Formula $R$
\end_inset
-:
-\begin_inset Formula
-\begin{align*}
- & \text{zip}_{F}\big(p\times\text{zip}_{F}(q\times r)\big)\triangleright\varepsilon_{1,23}^{\uparrow F}=\text{zip}_{F}\big(\text{zip}_{F}(p\times q)\times r\big)\triangleright\varepsilon_{12,3}^{\uparrow F}\quad,\\
- & \text{zip}_{G}(g\times\text{zip}_{G}(h\times j))\triangleright\varepsilon_{1,23}^{\uparrow G}=\text{zip}_{G}(\text{zip}_{G}(g\times h)\times j)\triangleright\varepsilon_{12,3}^{\uparrow G}\quad.
-\end{align*}
+ is applicative
+\end_layout
\end_inset
+ |
+
+
+|
+\begin_inset Text
+\begin_layout Plain Layout
+\size footnotesize
+recursive type
\end_layout
-\begin_layout Standard
-To verify the commutativity law
-\begin_inset space ~
\end_inset
+ |
+
+\begin_inset Text
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:commutativity-law-of-zip"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq S^{A,F^{P^{A}}}$
\end_inset
-) for
-\begin_inset Formula $L$
+
+\end_layout
+
\end_inset
+ |
+
+\begin_inset Text
-, we assume that the law holds for
-\begin_inset Formula $F$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $S$
\end_inset
and
-\begin_inset Formula $G$
+\begin_inset Formula $P$
\end_inset
-:
-\begin_inset Formula
-\begin{align*}
-\text{expect to equal }(\text{zip}_{L}\bef\text{swap}^{\uparrow L}):\quad & \text{swap}\bef\text{zip}_{L}=\gunderline{\text{swap}\bef\text{zip}_{F}}\bef\text{zip}_{G}^{\uparrow F}\\
-\text{commutativity law of }F:\quad & =\text{zip}_{F}\bef\gunderline{\text{swap}^{\uparrow F}\bef\text{zip}_{G}^{\uparrow F}}=\text{zip}_{F}\bef(\gunderline{\text{swap}\bef\text{zip}_{G}})^{\uparrow F}\\
-\text{commutativity law of }G\text{ under }^{\uparrow F}:\quad & =\gunderline{\text{zip}_{F}\bef\text{zip}_{G}^{\uparrow F}}\bef\text{swap}^{\gunderline{\uparrow G\uparrow F}}=\text{zip}_{L}\bef\text{swap}^{\uparrow L}\quad.
-\end{align*}
+ are polynomial
+\end_layout
\end_inset
+ |
+
+
+|
+\begin_inset Text
+\begin_layout Plain Layout
+
+\size footnotesize
+recursive type
+\end_layout
-\begin_inset Formula $\square$
\end_inset
+ |
+
+\begin_inset Text
+\begin_layout Plain Layout
-\end_layout
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq P^{A}+Q^{A}\times R^{F^{A}}$
+\end_inset
-\begin_layout Paragraph
-Products
-\end_layout
-\begin_layout Standard
-Similarly to most other typeclasses, the product of applicative functors
- is applicative:
\end_layout
-\begin_layout Subsubsection
-Statement
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Statement-applicative-product"
+\end_inset
+ |
+
+\begin_inset Text
+\begin_layout Plain Layout
+
+\size footnotesize
+conditions in Statement
+\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-applicative-product"
+reference "subsec:Statement-applicative-recursive-type-1"
plural "false"
caps "false"
noprefix "false"
@@ -16798,219 +16784,142 @@ noprefix "false"
\end_layout
-\begin_layout Standard
-For any applicative functors
-\begin_inset Formula $F$
\end_inset
+ |
+
+
- and
-\begin_inset Formula $G$
\end_inset
-, the functor
-\begin_inset Formula $L^{A}\triangleq F^{A}\times G^{A}$
-\end_inset
- is also applicative.
- Its
-\begin_inset listings
-inline true
-status open
+\end_layout
\begin_layout Plain Layout
+\begin_inset Caption Standard
-zip
-\end_layout
+\begin_layout Plain Layout
+Constructions of applicative functors.
+\begin_inset CommandInset label
+LatexCommand label
+name "tab:Constructions-of-applicative-functors"
\end_inset
- and
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-wu
\end_layout
\end_inset
- methods are defined by:
-\begin_inset Formula
-\begin{align*}
- & \text{zip}_{L}:(F^{A}\times G^{A})\times(F^{B}\times G^{B})\rightarrow F^{A\times B}\times G^{A\times B}\quad,\\
- & \text{zip}_{L}\big((m^{:F^{A}}\times n^{:G^{A}})\times(p^{:F^{B}}\times q^{:G^{B}})\big)\triangleq\text{zip}_{F}(m\times p)\times\text{zip}_{G}(n\times q)\quad,\\
- & \text{wu}_{L}:F^{\bbnum 1}\times G^{\bbnum 1}\quad,\quad\quad\text{wu}_{L}\triangleq\text{wu}_{F}\times\text{wu}_{G}\quad.
-\end{align*}
-
-\end_inset
-If
-\begin_inset Formula $F$
-\end_inset
+\end_layout
- and
-\begin_inset Formula $G$
\end_inset
- are commutative applicative functors, then so is
-\begin_inset Formula $L$
-\end_inset
-.
\end_layout
-\begin_layout Subparagraph
-Proof
+\begin_layout Paragraph
+Type parameters
\end_layout
\begin_layout Standard
-We note that the lifting to
-\begin_inset Formula $L$
+Three type constructions are based on using just type parameters: a constant
+ functor,
+\begin_inset Formula $L^{A}\triangleq Z$
\end_inset
- is defined by
-\begin_inset Formula $f^{\uparrow L}\triangleq f^{\uparrow F}\boxtimes f^{\uparrow G}$
+, the identity functor
+\begin_inset Formula $L^{A}\triangleq A$
\end_inset
-.
-\end_layout
-
-\begin_layout Standard
-To verify the left identity law of
-\begin_inset Formula $\text{zip}_{L}$
+, and the functor composition,
+\begin_inset Formula $L^{A}\triangleq F^{G^{A}}$
\end_inset
-:
-\begin_inset Formula
-\begin{align*}
-\text{expect to equal }(p\times q)\triangleright\text{ilu}^{\uparrow L}:\quad & \text{zip}_{L}\big(\gunderline{\text{wu}_{L}}\times(p^{:F^{A}}\times q^{:G^{A}})\big)\\
- & =\gunderline{\text{zip}_{L}}((\text{wu}_{F}\times\text{wu}_{G})\times(p\times q))\\
-\text{definition of }\text{zip}_{L}:\quad & =\text{zip}_{F}(\text{wu}_{F}\times p)\times\text{zip}_{G}(\text{wu}_{G}\times q)\\
-\text{left identity laws of }\text{zip}_{F}\text{ and }\text{zip}_{G}:\quad & =(p\triangleright\text{ilu}^{\uparrow F})\times(q\triangleright\text{ilu}^{\uparrow G})\\
- & =(p\times q)\triangleright(\text{ilu}^{\uparrow F}\boxtimes\text{ilu}^{\uparrow G})\\
-\text{definition of }^{\uparrow L}:\quad & =(p\times q)\triangleright\text{ilu}^{\uparrow L}\quad.
-\end{align*}
-
+ (also written as
+\begin_inset Formula $L\triangleq F\circ G$
\end_inset
-
+).
\end_layout
\begin_layout Standard
-To verify the right identity law of
-\begin_inset Formula $\text{zip}_{L}$
-\end_inset
-
-:
-\begin_inset Formula
-\begin{align*}
-\text{expect to equal }(p\times q)\triangleright\text{iru}^{\uparrow L}:\quad & \text{zip}_{L}\big((p^{:F^{A}}\times q^{:G^{A}})\times\gunderline{\text{wu}_{L}}\big)\\
- & =\gunderline{\text{zip}_{L}}((p\times q)\times(\text{wu}_{F}\times\text{wu}_{G}))\\
-\text{definition of }\text{zip}_{L}:\quad & =\text{zip}_{F}(p\times\text{wu}_{F})\times\text{zip}_{G}(q\times\text{wu}_{G})\\
-\text{right identity laws of }\text{zip}_{F}\text{ and }\text{zip}_{G}:\quad & =(p\triangleright\text{iru}^{\uparrow F})\times(q\triangleright\text{iru}^{\uparrow G})\\
- & =(p\times q)\triangleright(\text{iru}^{\uparrow F}\boxtimes\text{iru}^{\uparrow G})\\
-\text{definition of }^{\uparrow L}:\quad & =(p\times q)\triangleright\text{iru}^{\uparrow L}\quad.
-\end{align*}
-
+Given a fixed
+\emph on
+monoid
+\emph default
+ type
+\begin_inset Formula $Z$
\end_inset
-
-\end_layout
-
-\begin_layout Standard
-To verify the associativity law, begin with its left-hand side and use the
- definition of
-\begin_inset Formula $\text{zip}_{L}$
+, the constant functor
+\begin_inset Formula $L^{A}\triangleq Z$
\end_inset
-:
-\begin_inset Formula
-\begin{align*}
- & \text{zip}_{L}\big((p_{1}^{:F^{A}}\times p_{2}^{:G^{A}})\times\text{zip}_{L}\big((q_{1}^{:F^{B}}\times q_{2}^{:G^{B}})\times(r_{1}^{:F^{C}}\times r_{2}^{:G^{C}})\big)\big)\triangleright\gunderline{\varepsilon_{1,23}^{\uparrow L}}\\
- & =\text{zip}_{L}\big((p_{1}\times p_{2})\times\big(\text{zip}_{F}(q_{1}\times r_{1})\times\text{zip}_{G}(q_{2}\times r_{2})\big)\big)\triangleright\big(\varepsilon_{1,23}^{\uparrow F}\boxtimes\varepsilon_{1,23}^{\uparrow G}\big)\\
- & =\big(\gunderline{\text{zip}_{F}\big(p_{1}\times\text{zip}_{F}(q_{1}\times r_{1})\big)\triangleright\varepsilon_{1,23}^{\uparrow F}}\big)\times\big(\gunderline{\text{zip}_{G}\big(p_{2}\times\text{zip}_{G}(q_{2}\times r_{2})\big)\triangleright\varepsilon_{1,23}^{\uparrow G}}\big)\quad.
-\end{align*}
+ is applicative.
+ To see this, consider the operation
+\begin_inset listings
+inline true
+status open
-\end_inset
+\begin_layout Plain Layout
-The right-hand side is rewritten in a similar way:
-\begin_inset Formula
-\begin{align*}
- & \text{zip}_{L}\big(\text{zip}_{L}\big((p_{1}^{:F^{A}}\times p_{2}^{:G^{A}})\times(q_{1}^{:F^{B}}\times q_{2}^{:G^{B}})\big)\times(r_{1}^{:F^{C}}\times r_{2}^{:G^{C}})\big)\triangleright\gunderline{\varepsilon_{12,3}^{\uparrow L}}\\
- & =\text{zip}_{L}\big(\big(\text{zip}_{F}(p_{1}\times q_{1})\times\text{zip}_{G}(p_{2}\times q_{2})\big)\times(r_{1}\times r_{2})\big)\big)\triangleright\big(\varepsilon_{12,3}^{\uparrow F}\boxtimes\varepsilon_{12,3}^{\uparrow G}\big)\\
- & =\big(\gunderline{\text{zip}_{F}\big(\text{zip}_{F}(p_{1}\times q_{1})\times r_{1}\big)\triangleright\varepsilon_{12,3}^{\uparrow F}}\big)\times\big(\gunderline{\text{zip}_{G}\big(\text{zip}_{G}(p_{2}\times q_{2})\times r_{2}\big)\triangleright\varepsilon_{12,3}^{\uparrow G}}\big)\quad.
-\end{align*}
+zip
+\end_layout
\end_inset
-The underlined expressions in both sides are equal due to associativity
- laws of
-\begin_inset Formula $\text{zip}_{F}$
+ of type
+\begin_inset Formula $L^{A}\times L^{B}\rightarrow L^{A\times B}$
\end_inset
- and
-\begin_inset Formula $\text{zip}_{G}$
+, which in this case becomes just
+\begin_inset Formula $Z\times Z\rightarrow Z$
\end_inset
-.
-\end_layout
-
-\begin_layout Standard
-To verify the commutativity law of
-\begin_inset Formula $L$
+, the monoid
+\begin_inset Formula $Z$
\end_inset
- when it holds for
-\begin_inset Formula $F$
-\end_inset
+'s
+\begin_inset listings
+inline true
+status open
- and
-\begin_inset Formula $G$
-\end_inset
+\begin_layout Plain Layout
-:
-\begin_inset Formula
-\begin{align*}
- & \quad\text{expect to equal }\text{zip}_{L}\big((p\times q)\times(m\times n)\big):\quad\\
- & \text{zip}_{L}\big((m\times n)\times(p\times q)\big)\triangleright\text{swap}^{\uparrow L}\\
- & \quad\text{definitions of }\text{zip}_{L}\text{ and }^{\uparrow L}:\quad\\
- & =\big(\text{zip}_{F}(m\times p)\times\text{zip}_{G}(n\times q)\big)\triangleright(\text{swap}^{\uparrow F}\boxtimes\text{swap}^{\uparrow G})\\
- & \quad\text{definition of }\boxtimes:\quad\\
- & =\big(\text{zip}_{F}(m\times p)\triangleright\text{swap}^{\uparrow F}\big)\times\big(\text{zip}_{G}(n\times q)\triangleright\text{swap}^{\uparrow G}\big)\\
- & \quad\text{commutativity laws of }F\text{ and }G:\quad\\
- & =\text{zip}_{F}(p\times m)\times\text{zip}_{G}(q\times n)=\text{zip}_{L}\big((p\times q)\times(m\times n)\big)\quad.
-\end{align*}
+combine
+\end_layout
\end_inset
+ function.
+ The value
+\begin_inset listings
+inline true
+status open
-\begin_inset Formula $\square$
-\end_inset
-
+\begin_layout Plain Layout
+wu
\end_layout
-\begin_layout Paragraph
-Co-products
-\end_layout
+\end_inset
-\begin_layout Standard
-The co-product
-\begin_inset Formula $F+G$
+ of type
+\begin_inset Formula $L^{\bbnum 1}=Z$
\end_inset
- of two arbitrary applicative functors
-\begin_inset Formula $F$
+ is just the monoid
+\begin_inset Formula $Z$
\end_inset
- and
-\begin_inset Formula $G$
+'s empty value (
+\begin_inset Formula $e_{Z}$
\end_inset
- is not always applicative (just as with monads).
- One case where the
+).
+ The laws of
\begin_inset listings
inline true
status open
@@ -17022,34 +16931,90 @@ zip
\end_inset
- method cannot be implemented for
-\begin_inset Formula $F+G$
+ then reduce to the monoid laws of
+\begin_inset Formula $Z$
\end_inset
- was given in Example
-\begin_inset space ~
-\end_inset
-
-
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:tc-Example-10"
-plural "false"
-caps "false"
-noprefix "false"
+.
+ For the same reason, the applicative functor
+\begin_inset Formula $L^{A}\triangleq Z$
+\end_inset
+ will be commutative if the monoid
+\begin_inset Formula $Z$
\end_inset
-(b).
- However, the following statements show that the co-product
-\begin_inset Formula $F+G$
+ is commutative.
+\end_layout
+
+\begin_layout Standard
+Comparing this with the corresponding monad construction, we note that
+\begin_inset Formula $L^{A}\triangleq Z$
\end_inset
-
+ is
\emph on
-can
+not
\emph default
- be applicative under certain restrictions on
+ a monad unless
+\begin_inset Formula $Z=\bbnum 1$
+\end_inset
+
+.
+ For an arbitrary monoid type
+\begin_inset Formula $Z$
+\end_inset
+
+, the functor
+\begin_inset Formula $L^{A}\triangleq Z$
+\end_inset
+
+ is only a semimonad.
+\end_layout
+
+\begin_layout Standard
+The identity functor
+\begin_inset Formula $L^{A}\triangleq A$
+\end_inset
+
+ is applicative and commutative: the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ operation is the identity function of type
+\begin_inset Formula $A\times B\rightarrow A\times B$
+\end_inset
+
+, and the wrapped unit (
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+wu
+\end_layout
+
+\end_inset
+
+) is just the unit value.
+ All required laws hold for the identity function.
+\end_layout
+
+\begin_layout Standard
+The functor composition
+\begin_inset Formula $L\triangleq F\circ G$
+\end_inset
+
+ of two applicative functors
\begin_inset Formula $F$
\end_inset
@@ -17057,21 +17022,22 @@ can
\begin_inset Formula $G$
\end_inset
-.
+ is again applicative, unlike the functor composition of monads that often
+ does not produce a new monad.
\end_layout
\begin_layout Subsubsection
Statement
\begin_inset CommandInset label
LatexCommand label
-name "subsec:Statement-co-product-with-constant-functor-applicative"
+name "subsec:Statement-applicative-composition"
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-co-product-with-constant-functor-applicative"
+reference "subsec:Statement-applicative-composition"
plural "false"
caps "false"
noprefix "false"
@@ -17082,63 +17048,89 @@ noprefix "false"
\end_layout
\begin_layout Standard
-If
+For any two applicative functors
\begin_inset Formula $F$
\end_inset
- is applicative and
-\begin_inset Formula $Z$
+ and
+\begin_inset Formula $G$
\end_inset
- is a fixed monoid type then
-\begin_inset Formula $L^{A}\triangleq Z+F^{A}$
-\end_inset
+ with lawful
+\begin_inset listings
+inline true
+status open
- is applicative:
-\begin_inset Formula
-\begin{align*}
- & \text{zip}_{L}:(Z+F^{A})\times(Z+F^{B})\rightarrow Z+F^{A\times B}\quad,\\
- & \text{zip}_{L}\triangleq\,\begin{array}{|c||cc|}
- & Z & F^{A\times B}\\
-\hline Z\times Z & z_{1}\times z_{2}\rightarrow z_{1}\oplus z_{2} & \bbnum 0\\
-F^{A}\times Z & \_^{:F^{A}}\times z\rightarrow z & \bbnum 0\\
-Z\times F^{B} & z\times\_^{:F^{B}}\rightarrow z & \bbnum 0\\
-F^{A}\times F^{B} & \bbnum 0 & \text{zip}_{F}
-\end{array}\quad.
-\end{align*}
+\begin_layout Plain Layout
+
+zip
+\end_layout
\end_inset
-The
-\begin_inset Quotes eld
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pure
+\end_layout
+
\end_inset
-wrapped unit
-\begin_inset Quotes erd
+ methods, the functor
+\begin_inset Formula $L^{A}\triangleq F^{G^{A}}$
\end_inset
- (
-\begin_inset Formula $\text{wu}_{L}:Z+F^{\bbnum 1}$
+ is also applicative.
+ Its
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
\end_inset
-) is defined as
-\begin_inset Formula $\text{wu}_{L}\triangleq\bbnum 0^{:Z}+\text{wu}_{F}$
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pure
+\end_layout
+
\end_inset
-.
- If
-\begin_inset Formula $Z$
+ methods are defined by:
+\begin_inset Formula
+\begin{align*}
+ & \text{zip}_{L}:F^{G^{A}}\times F^{G^{B}}\rightarrow F^{G^{A\times B}}\quad,\quad\quad\text{zip}_{L}\triangleq\text{zip}_{F}\bef\text{zip}_{G}^{\uparrow F}\quad,\\
+ & \text{pu}_{L}:A\rightarrow F^{G^{A}}\quad,\quad\quad\text{pu}_{L}\triangleq\text{pu}_{G}\bef\text{pu}_{F}\quad,\quad\quad\text{wu}_{L}\triangleq\text{pu}_{F}(\text{wu}_{G})\quad.
+\end{align*}
+
\end_inset
- is a commutative monoid and
+If
\begin_inset Formula $F$
\end_inset
- is commutative then
+ and
+\begin_inset Formula $G$
+\end_inset
+
+ are commutative applicative functors, then so is
\begin_inset Formula $L$
\end_inset
- is also commutative.
+.
\end_layout
\begin_layout Subparagraph
@@ -17146,35 +17138,40 @@ Proof
\end_layout
\begin_layout Standard
-We will verify the laws of
-\begin_inset Formula $\text{zip}_{L}$
-\end_inset
-
- and
-\begin_inset Formula $\text{wu}_{L}$
+We note that the lifting to
+\begin_inset Formula $L$
\end_inset
-, assuming that
-\begin_inset Formula $F$
+ is defined by
+\begin_inset Formula $f^{\uparrow L}\triangleq f^{\uparrow G\uparrow F}=(f^{\uparrow G})^{\uparrow F}$
\end_inset
- is a lawful applicative functor.
+.
\end_layout
\begin_layout Standard
-The lifting to
-\begin_inset Formula $L$
+To verify the left identity law
+\begin_inset space ~
\end_inset
- is defined in the standard way:
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:zip-left-identity-law"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+):
\begin_inset Formula
-\[
-(f^{:A\rightarrow B})^{\uparrow L}\triangleq\,\begin{array}{|c||cc|}
- & Z & F^{B}\\
-\hline Z & \text{id} & \bbnum 0\\
-F^{A} & \bbnum 0 & f^{\uparrow F}
-\end{array}\quad.
-\]
+\begin{align*}
+\text{expect to equal }p\triangleright\text{ilu}^{\uparrow L}:\quad & \text{zip}_{L}(\text{wu}_{L}\times p^{:F^{G^{A}}})=(\gunderline{\text{pu}_{F}(\text{wu}_{G})}\times p)\triangleright\gunderline{\text{zip}_{F}}\bef\text{zip}_{G}^{\uparrow F}\\
+\text{left identity law of }\text{zip}_{F}:\quad & =p\triangleright(g^{:G^{A}}\rightarrow\gunderline{\text{wu}_{G}\times g)^{\uparrow F}\bef\text{zip}_{G}^{\uparrow F}}\\
+\text{composition under }^{\uparrow F}:\quad & =p\triangleright\big(g^{:G^{A}}\rightarrow\gunderline{\text{zip}_{G}(\text{wu}_{G}\times g)}\big)^{\uparrow F}\\
+\text{left identity law of }\text{zip}_{G}:\quad & =p\triangleright(\gunderline{g\rightarrow g}\triangleright\text{ilu}^{\uparrow G})^{\uparrow F}=p\triangleright(\text{ilu}^{\uparrow G})^{\uparrow F}=p\triangleright\text{ilu}^{\uparrow L}\quad.
+\end{align*}
\end_inset
@@ -17182,29 +17179,13 @@ F^{A} & \bbnum 0 & f^{\uparrow F}
\end_layout
\begin_layout Standard
-To verify the left identity law, we use the left identity law of
-\begin_inset Formula $\text{zip}_{F}$
-\end_inset
-
-:
+To verify the right identity law:
\begin_inset Formula
\begin{align*}
- & \text{zip}_{L}(\text{wu}_{L}\times p^{:Z+F^{B}})=\text{zip}_{L}((\bbnum 0+\text{wu}_{F})\times p)\\
- & =(\text{wu}_{F}\times p)\triangleright\,\begin{array}{|c||cc|}
- & Z & F^{\bbnum 1\times B}\\
-\hline F^{\bbnum 1}\times Z & \_^{:F^{\bbnum 1}}\times z\rightarrow z & \bbnum 0\\
-F^{\bbnum 1}\times F^{B} & \bbnum 0 & \text{zip}_{F}
-\end{array}\\
- & =p\triangleright\,\begin{array}{|c||cc|}
- & Z & F^{\bbnum 1\times B}\\
-\hline Z & \text{id} & \bbnum 0\\
-F^{B} & \bbnum 0 & k^{:F^{B}}\rightarrow\gunderline{\text{zip}_{F}(\text{wu}_{F}\times k)}
-\end{array}\,=p\triangleright\,\begin{array}{|c||cc|}
- & Z & F^{\bbnum 1\times B}\\
-\hline Z & \text{id} & \bbnum 0\\
-F^{B} & \bbnum 0 & k\rightarrow k\triangleright\text{ilu}^{\uparrow F}
-\end{array}\\
- & =p\triangleright\text{ilu}^{\uparrow L}\quad.
+\text{expect to equal }p\triangleright\text{iru}^{\uparrow L}:\quad & \text{zip}_{L}(p^{:F^{G^{A}}}\times\text{wu}_{L})=(p\times\gunderline{\text{pu}_{F}(\text{wu}_{G})})\triangleright\gunderline{\text{zip}_{F}}\bef\text{zip}_{G}^{\uparrow F}\\
+\text{right identity law of }\text{zip}_{F}:\quad & =p\triangleright(g^{:G^{A}}\rightarrow\gunderline{g\times\text{wu}_{G})^{\uparrow F}\bef\text{zip}_{G}^{\uparrow F}}\\
+ & =p\triangleright\big(g^{:G^{A}}\rightarrow\gunderline{\text{zip}_{G}(g\times\text{wu}_{G})}\big)^{\uparrow F}\\
+\text{right identity law of }\text{zip}_{G}:\quad & =p\triangleright(\gunderline{g\rightarrow g\,\triangleright}\,\text{iru}^{\uparrow G})^{\uparrow F}=p\triangleright(\text{iru}^{\uparrow G})^{\uparrow F}=p\triangleright\text{iru}^{\uparrow L}\quad.
\end{align*}
\end_inset
@@ -17213,9 +17194,552 @@ F^{B} & \bbnum 0 & k\rightarrow k\triangleright\text{ilu}^{\uparrow F}
\end_layout
\begin_layout Standard
-To verify the right identity law, we write a similar calculation:
-\begin_inset Formula
-\begin{align*}
+To verify the associativity law, substitute the definition of
+\begin_inset Formula $\text{zip}_{L}$
+\end_inset
+
+ into one side:
+\begin_inset Formula
+\begin{align*}
+ & \quad\text{left-hand side}:\quad\\
+ & \text{zip}_{L}\big(p\times\text{zip}_{L}(q\times r)\big)\triangleright\varepsilon_{1,23}^{\uparrow L}=\big(p\times\text{zip}_{L}(q\times r)\big)\triangleright\text{zip}_{F}\bef\text{zip}_{G}^{\uparrow F}\bef\gunderline{\varepsilon_{1,23}^{\uparrow L}}\\
+ & \quad\text{definition of }^{\uparrow L}:\quad\\
+ & =\big(p\times\big(\text{zip}_{F}(q\times r)\triangleright\gunderline{\text{zip}_{G}^{\uparrow F}}\big)\big)\triangleright\gunderline{\text{zip}_{F}}\bef\text{zip}_{G}^{\uparrow F}\bef\varepsilon_{1,23}^{\uparrow G\uparrow F}\\
+ & \quad\text{naturality law of }\text{zip}_{F}:\quad\\
+ & =\big(p\times\text{zip}_{F}(q\times r)\big)\triangleright\text{zip}_{F}\bef\big(g\times k^{:G^{B}\times G^{C}}\!\rightarrow\gunderline{g\times\text{zip}_{G}(k)\big)^{\uparrow F}\bef\text{zip}_{G}^{\uparrow F}\bef\varepsilon_{1,23}^{\uparrow G\uparrow F}}\\
+ & \quad\text{composition under }^{\uparrow F}:\quad\\
+ & =\text{zip}_{F}\big(p\times\text{zip}_{F}(q\times r)\big)\triangleright\big(g\times(h\times j)\rightarrow\text{zip}_{G}(g\times\text{zip}_{G}(h\times j))\triangleright\varepsilon_{1,23}^{\uparrow G}\big)^{\uparrow F}\quad.
+\end{align*}
+
+\end_inset
+
+Now rewrite the other side in a similar way:
+\begin_inset Formula
+\begin{align*}
+ & \quad\text{right-hand side}:\quad\\
+ & \text{zip}_{L}\big(\text{zip}_{L}(p\times q)\times r\big)\triangleright\varepsilon_{12,3}^{\uparrow L}=\big(\text{zip}_{L}(p\times q)\times r\big)\triangleright\text{zip}_{F}\bef\text{zip}_{G}^{\uparrow F}\bef\varepsilon_{12,3}^{\uparrow L}\\
+ & \quad\text{definition of }^{\uparrow L}:\quad\\
+ & =\big(\big(\text{zip}_{F}(p\times q)\triangleright\gunderline{\text{zip}_{G}^{\uparrow F}}\big)\times r\big)\triangleright\gunderline{\text{zip}_{F}}\bef\text{zip}_{G}^{\uparrow F}\bef\varepsilon_{12,3}^{\uparrow G\uparrow F}\\
+ & \quad\text{naturality law of }\text{zip}_{F}:\quad\\
+ & =\big(\text{zip}_{F}(p\times q)\times r\big)\triangleright\text{zip}_{F}\bef\big(k^{:G^{A}\times G^{B}}\!\times j\rightarrow\gunderline{\text{zip}_{G}(k)\times j\big)^{\uparrow F}\bef\text{zip}_{G}^{\uparrow F}\bef\varepsilon_{12,3}^{\uparrow G\uparrow F}}\\
+ & \quad\text{composition under }^{\uparrow F}:\quad\\
+ & =\text{zip}_{F}\big(\text{zip}_{F}(p\times q)\times r\big)\triangleright\big((g\times h)\times j\rightarrow\text{zip}_{G}(\text{zip}_{G}(g\times h)\times j)\triangleright\varepsilon_{12,3}^{\uparrow G}\big)^{\uparrow F}\quad.
+\end{align*}
+
+\end_inset
+
+The two sides become equal after using the associativity laws of
+\begin_inset Formula $\text{zip}_{F}$
+\end_inset
+
+ and
+\begin_inset Formula $\text{zip}_{G}$
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align*}
+ & \text{zip}_{F}\big(p\times\text{zip}_{F}(q\times r)\big)\triangleright\varepsilon_{1,23}^{\uparrow F}=\text{zip}_{F}\big(\text{zip}_{F}(p\times q)\times r\big)\triangleright\varepsilon_{12,3}^{\uparrow F}\quad,\\
+ & \text{zip}_{G}(g\times\text{zip}_{G}(h\times j))\triangleright\varepsilon_{1,23}^{\uparrow G}=\text{zip}_{G}(\text{zip}_{G}(g\times h)\times j)\triangleright\varepsilon_{12,3}^{\uparrow G}\quad.
+\end{align*}
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+To verify the commutativity law
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:commutativity-law-of-zip"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) for
+\begin_inset Formula $L$
+\end_inset
+
+, we assume that the law holds for
+\begin_inset Formula $F$
+\end_inset
+
+ and
+\begin_inset Formula $G$
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align*}
+\text{expect to equal }(\text{zip}_{L}\bef\text{swap}^{\uparrow L}):\quad & \text{swap}\bef\text{zip}_{L}=\gunderline{\text{swap}\bef\text{zip}_{F}}\bef\text{zip}_{G}^{\uparrow F}\\
+\text{commutativity law of }F:\quad & =\text{zip}_{F}\bef\gunderline{\text{swap}^{\uparrow F}\bef\text{zip}_{G}^{\uparrow F}}=\text{zip}_{F}\bef(\gunderline{\text{swap}\bef\text{zip}_{G}})^{\uparrow F}\\
+\text{commutativity law of }G\text{ under }^{\uparrow F}:\quad & =\gunderline{\text{zip}_{F}\bef\text{zip}_{G}^{\uparrow F}}\bef\text{swap}^{\gunderline{\uparrow G\uparrow F}}=\text{zip}_{L}\bef\text{swap}^{\uparrow L}\quad.
+\end{align*}
+
+\end_inset
+
+
+\begin_inset Formula $\square$
+\end_inset
+
+
+\end_layout
+
+\begin_layout Paragraph
+Products
+\end_layout
+
+\begin_layout Standard
+Similarly to most other typeclasses, the product of applicative functors
+ is applicative:
+\end_layout
+
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-applicative-product"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-applicative-product"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+For any applicative functors
+\begin_inset Formula $F$
+\end_inset
+
+ and
+\begin_inset Formula $G$
+\end_inset
+
+, the functor
+\begin_inset Formula $L^{A}\triangleq F^{A}\times G^{A}$
+\end_inset
+
+ is also applicative.
+ Its
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+wu
+\end_layout
+
+\end_inset
+
+ methods are defined by:
+\begin_inset Formula
+\begin{align*}
+ & \text{zip}_{L}:(F^{A}\times G^{A})\times(F^{B}\times G^{B})\rightarrow F^{A\times B}\times G^{A\times B}\quad,\\
+ & \text{zip}_{L}\big((m^{:F^{A}}\times n^{:G^{A}})\times(p^{:F^{B}}\times q^{:G^{B}})\big)\triangleq\text{zip}_{F}(m\times p)\times\text{zip}_{G}(n\times q)\quad,\\
+ & \text{wu}_{L}:F^{\bbnum 1}\times G^{\bbnum 1}\quad,\quad\quad\text{wu}_{L}\triangleq\text{wu}_{F}\times\text{wu}_{G}\quad.
+\end{align*}
+
+\end_inset
+
+If
+\begin_inset Formula $F$
+\end_inset
+
+ and
+\begin_inset Formula $G$
+\end_inset
+
+ are commutative applicative functors, then so is
+\begin_inset Formula $L$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Subparagraph
+Proof
+\end_layout
+
+\begin_layout Standard
+We note that the lifting to
+\begin_inset Formula $L$
+\end_inset
+
+ is defined by
+\begin_inset Formula $f^{\uparrow L}\triangleq f^{\uparrow F}\boxtimes f^{\uparrow G}$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+To verify the left identity law of
+\begin_inset Formula $\text{zip}_{L}$
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align*}
+\text{expect to equal }(p\times q)\triangleright\text{ilu}^{\uparrow L}:\quad & \text{zip}_{L}\big(\gunderline{\text{wu}_{L}}\times(p^{:F^{A}}\times q^{:G^{A}})\big)\\
+ & =\gunderline{\text{zip}_{L}}((\text{wu}_{F}\times\text{wu}_{G})\times(p\times q))\\
+\text{definition of }\text{zip}_{L}:\quad & =\text{zip}_{F}(\text{wu}_{F}\times p)\times\text{zip}_{G}(\text{wu}_{G}\times q)\\
+\text{left identity laws of }\text{zip}_{F}\text{ and }\text{zip}_{G}:\quad & =(p\triangleright\text{ilu}^{\uparrow F})\times(q\triangleright\text{ilu}^{\uparrow G})\\
+ & =(p\times q)\triangleright(\text{ilu}^{\uparrow F}\boxtimes\text{ilu}^{\uparrow G})\\
+\text{definition of }^{\uparrow L}:\quad & =(p\times q)\triangleright\text{ilu}^{\uparrow L}\quad.
+\end{align*}
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+To verify the right identity law of
+\begin_inset Formula $\text{zip}_{L}$
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align*}
+\text{expect to equal }(p\times q)\triangleright\text{iru}^{\uparrow L}:\quad & \text{zip}_{L}\big((p^{:F^{A}}\times q^{:G^{A}})\times\gunderline{\text{wu}_{L}}\big)\\
+ & =\gunderline{\text{zip}_{L}}((p\times q)\times(\text{wu}_{F}\times\text{wu}_{G}))\\
+\text{definition of }\text{zip}_{L}:\quad & =\text{zip}_{F}(p\times\text{wu}_{F})\times\text{zip}_{G}(q\times\text{wu}_{G})\\
+\text{right identity laws of }\text{zip}_{F}\text{ and }\text{zip}_{G}:\quad & =(p\triangleright\text{iru}^{\uparrow F})\times(q\triangleright\text{iru}^{\uparrow G})\\
+ & =(p\times q)\triangleright(\text{iru}^{\uparrow F}\boxtimes\text{iru}^{\uparrow G})\\
+\text{definition of }^{\uparrow L}:\quad & =(p\times q)\triangleright\text{iru}^{\uparrow L}\quad.
+\end{align*}
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+To verify the associativity law, begin with its left-hand side and use the
+ definition of
+\begin_inset Formula $\text{zip}_{L}$
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align*}
+ & \text{zip}_{L}\big((p_{1}^{:F^{A}}\times p_{2}^{:G^{A}})\times\text{zip}_{L}\big((q_{1}^{:F^{B}}\times q_{2}^{:G^{B}})\times(r_{1}^{:F^{C}}\times r_{2}^{:G^{C}})\big)\big)\triangleright\gunderline{\varepsilon_{1,23}^{\uparrow L}}\\
+ & =\text{zip}_{L}\big((p_{1}\times p_{2})\times\big(\text{zip}_{F}(q_{1}\times r_{1})\times\text{zip}_{G}(q_{2}\times r_{2})\big)\big)\triangleright\big(\varepsilon_{1,23}^{\uparrow F}\boxtimes\varepsilon_{1,23}^{\uparrow G}\big)\\
+ & =\big(\gunderline{\text{zip}_{F}\big(p_{1}\times\text{zip}_{F}(q_{1}\times r_{1})\big)\triangleright\varepsilon_{1,23}^{\uparrow F}}\big)\times\big(\gunderline{\text{zip}_{G}\big(p_{2}\times\text{zip}_{G}(q_{2}\times r_{2})\big)\triangleright\varepsilon_{1,23}^{\uparrow G}}\big)\quad.
+\end{align*}
+
+\end_inset
+
+The right-hand side is rewritten in a similar way:
+\begin_inset Formula
+\begin{align*}
+ & \text{zip}_{L}\big(\text{zip}_{L}\big((p_{1}^{:F^{A}}\times p_{2}^{:G^{A}})\times(q_{1}^{:F^{B}}\times q_{2}^{:G^{B}})\big)\times(r_{1}^{:F^{C}}\times r_{2}^{:G^{C}})\big)\triangleright\gunderline{\varepsilon_{12,3}^{\uparrow L}}\\
+ & =\text{zip}_{L}\big(\big(\text{zip}_{F}(p_{1}\times q_{1})\times\text{zip}_{G}(p_{2}\times q_{2})\big)\times(r_{1}\times r_{2})\big)\big)\triangleright\big(\varepsilon_{12,3}^{\uparrow F}\boxtimes\varepsilon_{12,3}^{\uparrow G}\big)\\
+ & =\big(\gunderline{\text{zip}_{F}\big(\text{zip}_{F}(p_{1}\times q_{1})\times r_{1}\big)\triangleright\varepsilon_{12,3}^{\uparrow F}}\big)\times\big(\gunderline{\text{zip}_{G}\big(\text{zip}_{G}(p_{2}\times q_{2})\times r_{2}\big)\triangleright\varepsilon_{12,3}^{\uparrow G}}\big)\quad.
+\end{align*}
+
+\end_inset
+
+The underlined expressions in both sides are equal due to associativity
+ laws of
+\begin_inset Formula $\text{zip}_{F}$
+\end_inset
+
+ and
+\begin_inset Formula $\text{zip}_{G}$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+To verify the commutativity law of
+\begin_inset Formula $L$
+\end_inset
+
+ when it holds for
+\begin_inset Formula $F$
+\end_inset
+
+ and
+\begin_inset Formula $G$
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align*}
+ & \quad\text{expect to equal }\text{zip}_{L}\big((p\times q)\times(m\times n)\big):\quad\\
+ & \text{zip}_{L}\big((m\times n)\times(p\times q)\big)\triangleright\text{swap}^{\uparrow L}\\
+ & \quad\text{definitions of }\text{zip}_{L}\text{ and }^{\uparrow L}:\quad\\
+ & =\big(\text{zip}_{F}(m\times p)\times\text{zip}_{G}(n\times q)\big)\triangleright(\text{swap}^{\uparrow F}\boxtimes\text{swap}^{\uparrow G})\\
+ & \quad\text{definition of }\boxtimes:\quad\\
+ & =\big(\text{zip}_{F}(m\times p)\triangleright\text{swap}^{\uparrow F}\big)\times\big(\text{zip}_{G}(n\times q)\triangleright\text{swap}^{\uparrow G}\big)\\
+ & \quad\text{commutativity laws of }F\text{ and }G:\quad\\
+ & =\text{zip}_{F}(p\times m)\times\text{zip}_{G}(q\times n)=\text{zip}_{L}\big((p\times q)\times(m\times n)\big)\quad.
+\end{align*}
+
+\end_inset
+
+
+\begin_inset Formula $\square$
+\end_inset
+
+
+\end_layout
+
+\begin_layout Paragraph
+Co-products
+\end_layout
+
+\begin_layout Standard
+The co-product
+\begin_inset Formula $F+G$
+\end_inset
+
+ of two arbitrary applicative functors
+\begin_inset Formula $F$
+\end_inset
+
+ and
+\begin_inset Formula $G$
+\end_inset
+
+ is not always applicative (just as with monads).
+ One case where the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ method cannot be implemented for
+\begin_inset Formula $F+G$
+\end_inset
+
+ was given in Example
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:tc-Example-10"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+(b).
+ However, the following statements show that the co-product
+\begin_inset Formula $F+G$
+\end_inset
+
+
+\emph on
+can
+\emph default
+ be applicative under certain restrictions on
+\begin_inset Formula $F$
+\end_inset
+
+ and
+\begin_inset Formula $G$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-co-product-with-constant-functor-applicative"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-co-product-with-constant-functor-applicative"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+If
+\begin_inset Formula $F$
+\end_inset
+
+ is applicative and
+\begin_inset Formula $Z$
+\end_inset
+
+ is a fixed monoid type then
+\begin_inset Formula $L^{A}\triangleq Z+F^{A}$
+\end_inset
+
+ is applicative:
+\begin_inset Formula
+\begin{align*}
+ & \text{zip}_{L}:(Z+F^{A})\times(Z+F^{B})\rightarrow Z+F^{A\times B}\quad,\\
+ & \text{zip}_{L}\triangleq\,\begin{array}{|c||cc|}
+ & Z & F^{A\times B}\\
+\hline Z\times Z & z_{1}\times z_{2}\rightarrow z_{1}\oplus z_{2} & \bbnum 0\\
+F^{A}\times Z & \_^{:F^{A}}\times z\rightarrow z & \bbnum 0\\
+Z\times F^{B} & z\times\_^{:F^{B}}\rightarrow z & \bbnum 0\\
+F^{A}\times F^{B} & \bbnum 0 & \text{zip}_{F}
+\end{array}\quad.
+\end{align*}
+
+\end_inset
+
+The
+\begin_inset Quotes eld
+\end_inset
+
+wrapped unit
+\begin_inset Quotes erd
+\end_inset
+
+ (
+\begin_inset Formula $\text{wu}_{L}:Z+F^{\bbnum 1}$
+\end_inset
+
+) is defined as
+\begin_inset Formula $\text{wu}_{L}\triangleq\bbnum 0^{:Z}+\text{wu}_{F}$
+\end_inset
+
+.
+ If
+\begin_inset Formula $Z$
+\end_inset
+
+ is a commutative monoid and
+\begin_inset Formula $F$
+\end_inset
+
+ is commutative then
+\begin_inset Formula $L$
+\end_inset
+
+ is also commutative.
+\end_layout
+
+\begin_layout Subparagraph
+Proof
+\end_layout
+
+\begin_layout Standard
+We will verify the laws of
+\begin_inset Formula $\text{zip}_{L}$
+\end_inset
+
+ and
+\begin_inset Formula $\text{wu}_{L}$
+\end_inset
+
+, assuming that
+\begin_inset Formula $F$
+\end_inset
+
+ is a lawful applicative functor.
+\end_layout
+
+\begin_layout Standard
+The lifting to
+\begin_inset Formula $L$
+\end_inset
+
+ is defined in the standard way:
+\begin_inset Formula
+\[
+(f^{:A\rightarrow B})^{\uparrow L}\triangleq\,\begin{array}{|c||cc|}
+ & Z & F^{B}\\
+\hline Z & \text{id} & \bbnum 0\\
+F^{A} & \bbnum 0 & f^{\uparrow F}
+\end{array}\quad.
+\]
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+To verify the left identity law, we use the left identity law of
+\begin_inset Formula $\text{zip}_{F}$
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align*}
+ & \text{zip}_{L}(\text{wu}_{L}\times p^{:Z+F^{B}})=\text{zip}_{L}((\bbnum 0+\text{wu}_{F})\times p)\\
+ & =(\text{wu}_{F}\times p)\triangleright\,\begin{array}{|c||cc|}
+ & Z & F^{\bbnum 1\times B}\\
+\hline F^{\bbnum 1}\times Z & \_^{:F^{\bbnum 1}}\times z\rightarrow z & \bbnum 0\\
+F^{\bbnum 1}\times F^{B} & \bbnum 0 & \text{zip}_{F}
+\end{array}\\
+ & =p\triangleright\,\begin{array}{|c||cc|}
+ & Z & F^{\bbnum 1\times B}\\
+\hline Z & \text{id} & \bbnum 0\\
+F^{B} & \bbnum 0 & k^{:F^{B}}\rightarrow\gunderline{\text{zip}_{F}(\text{wu}_{F}\times k)}
+\end{array}\,=p\triangleright\,\begin{array}{|c||cc|}
+ & Z & F^{\bbnum 1\times B}\\
+\hline Z & \text{id} & \bbnum 0\\
+F^{B} & \bbnum 0 & k\rightarrow k\triangleright\text{ilu}^{\uparrow F}
+\end{array}\\
+ & =p\triangleright\text{ilu}^{\uparrow L}\quad.
+\end{align*}
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+To verify the right identity law, we write a similar calculation:
+\begin_inset Formula
+\begin{align*}
& \text{zip}_{L}(p^{:Z+F^{A}}\times\text{wu}_{L})=\text{zip}_{L}(p\times(\bbnum 0+\text{wu}_{F}))\\
& =(p\times\text{wu}_{F})\triangleright\,\begin{array}{|c||cc|}
& Z & F^{A\times\bbnum 1}\\
@@ -21859,27 +22383,221 @@ noprefix "false"
\begin_inset Formula $G$
\end_inset
- and
-\begin_inset Formula $H\times(F\circ L)$
+ and
+\begin_inset Formula $H\times(F\circ L)$
+\end_inset
+
+.
+ The functor
+\begin_inset Formula $H\times(F\circ L)$
+\end_inset
+
+ is co-pointed because
+\begin_inset Formula $H$
+\end_inset
+
+ is (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Co-pointed-functors"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ The compatibility law holds for
+\begin_inset Formula $H\times(F\circ L)$
+\end_inset
+
+ due to Exercise
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Exercise-applicative-II-4-1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+ The functor
+\begin_inset Formula $F\circ L$
+\end_inset
+
+ is applicative because it is a composition of
+\begin_inset Formula $F$
+\end_inset
+
+ and the recursively used
+\begin_inset Formula $L$
+\end_inset
+
+.
+ (As usual, we assume that recursive uses of
+\begin_inset Formula $L$
+\end_inset
+
+'s methods will satisfy all required laws.)
+\end_layout
+
+\begin_layout Standard
+The constructions give us the code of
+\begin_inset Formula $L$
+\end_inset
+
+'s methods
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+wu
+\end_layout
+
+\end_inset
+
+.
+ Define
+\begin_inset Formula $N^{A}\triangleq H^{A}\times F^{L^{A}}$
+\end_inset
+
+ and write:
+\begin_inset Formula
+\begin{align*}
+ & \text{ex}_{N}\triangleq\pi_{1}\bef\text{ex}_{H}=\big(h^{:H^{A}}\times k^{:F^{L^{A}}}\rightarrow\text{ex}_{H}(h)\big)\quad,\\
+ & \overline{\text{zip}_{N}}\triangleq(h_{1}^{:H^{A}}\times k_{1}^{:F^{L^{A}}})\times(h_{2}^{:H^{B}}\times k_{2}^{:F^{L^{B}}})\rightarrow\text{zip}_{H}(h_{1}\times h_{2})\times\big(\text{zip}_{F}(k_{1}\times k_{2})\triangleright\overline{\text{zip}_{L}}^{\uparrow F}\big)\quad.
+\end{align*}
+
+\end_inset
+
+The function
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+toG
+\end_layout
+
+\end_inset
+
+ converts values of type
+\begin_inset Formula $N^{A}$
+\end_inset
+
+ to values of type
+\begin_inset Formula $G^{A}$
+\end_inset
+
+:
+\begin_inset Formula
+\[
+\text{toG}:N^{A}\rightarrow G^{A}\quad,\quad\quad\text{toG}\triangleq\text{ex}_{N}\bef\text{pu}_{G}\quad.
+\]
+
+\end_inset
+
+Then we have the following code:
+\begin_inset Formula
+\begin{align*}
+ & \text{zip}_{L}:(G^{A}+N^{A})\times(G^{B}+N^{B})\rightarrow G^{A\times B}+N^{A\times B}\quad,\\
+ & \text{zip}_{L}\triangleq\,\begin{array}{|c||cc|}
+ & G^{A\times B} & N^{A\times B}\\
+\hline G^{A}\times G^{B} & \text{zip}_{G} & \bbnum 0\\
+N^{A}\times G^{B} & (\text{toG}\boxtimes\text{id})\bef\text{zip}_{G} & \bbnum 0\\
+G^{A}\times N^{B} & (\text{id}\boxtimes\text{toG})\bef\text{zip}_{G} & \bbnum 0\\
+N^{A}\times N^{B} & \bbnum 0 & \overline{\text{zip}_{N}}
+\end{array}\quad,\\
+ & \text{wu}_{L}:G^{\bbnum 1}+H^{\bbnum 1}\times F^{L^{\bbnum 1}}\quad,\quad\quad\text{wu}_{L}\triangleq\bbnum 0^{:G^{\bbnum 1}}+\text{wu}_{H}\times\text{pu}_{F}(\text{wu}_{L})\quad.
+\end{align*}
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(b)
+\series default
+ Let us use the
+\begin_inset Index idx
+status collapsed
+
+\begin_layout Plain Layout
+recursive types!unrolling trick
+\end_layout
+
+\end_inset
+
+
+\begin_inset Index idx
+status collapsed
+
+\begin_layout Plain Layout
+unrolling trick for recursive types
+\end_layout
+
+\end_inset
+
+unrolling trick to compare the recursive types
+\begin_inset Formula $L$
+\end_inset
+
+ and
+\begin_inset Formula $P$
+\end_inset
+
+:
+\begin_inset Formula
+\[
+L^{A}=G^{A}+H^{A}\times F^{G^{A}+H^{A}\times F^{G^{A}+...}}\quad,\quad\quad P^{A}=F^{G^{A}+H^{A}\times F^{G^{A}+H^{A}\times F^{G^{A}+...}}}\quad.
+\]
+
\end_inset
-.
- The functor
-\begin_inset Formula $H\times(F\circ L)$
+It suggests that
+\begin_inset Formula $P^{A}\cong F^{L^{A}}$
\end_inset
- is co-pointed because
-\begin_inset Formula $H$
+.
+ Then the required properties hold for
+\begin_inset Formula $P$
\end_inset
- is (Section
+ due to the functor composition construction (Statement
\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Co-pointed-functors"
+reference "subsec:Statement-applicative-composition"
plural "false"
caps "false"
noprefix "false"
@@ -21887,51 +22605,68 @@ noprefix "false"
\end_inset
).
- The compatibility law holds for
-\begin_inset Formula $H\times(F\circ L)$
+ To establish a type equivalence
+\begin_inset Formula $P^{A}\cong F^{L^{A}}$
\end_inset
- due to Exercise
+ rigorously, we use Statement
\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Exercise-applicative-II-4-1"
+reference "subsec:Statement-unrolling-trick"
plural "false"
caps "false"
noprefix "false"
\end_inset
-.
- The functor
-\begin_inset Formula $F\circ L$
+ below, where we need to set
+\begin_inset Formula $R\triangleq F$
\end_inset
- is applicative because it is a composition of
-\begin_inset Formula $F$
+,
+\begin_inset Formula $S^{T}\triangleq G^{A}+H^{A}\times T$
\end_inset
- and the recursively used
-\begin_inset Formula $L$
+,
+\begin_inset Formula $U\triangleq P^{A}$
+\end_inset
+
+, and
+\begin_inset Formula $V\triangleq L^{A}$
\end_inset
.
- (As usual, we assume that recursive uses of
-\begin_inset Formula $L$
+
+\begin_inset Formula $\square$
\end_inset
-'s methods will satisfy all required laws.)
+
\end_layout
\begin_layout Standard
-The constructions give us the code of
-\begin_inset Formula $L$
+Note that the construction shown in Statement
+\begin_inset space ~
\end_inset
-'s methods
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-applicative-recursive-type-1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ needs to define
+\emph on
+both
+\emph default
+
\begin_inset listings
inline true
status open
@@ -21955,194 +22690,261 @@ wu
\end_inset
-.
- Define
-\begin_inset Formula $N^{A}\triangleq H^{A}\times F^{L^{A}}$
-\end_inset
+ recursively.
+ This leads to a problem in case
+\begin_inset listings
+inline true
+status open
- and write:
-\begin_inset Formula
-\begin{align*}
- & \text{ex}_{N}\triangleq\pi_{1}\bef\text{ex}_{H}=\big(h^{:H^{A}}\times k^{:F^{L^{A}}}\rightarrow\text{ex}_{H}(h)\big)\quad,\\
- & \overline{\text{zip}_{N}}\triangleq(h_{1}^{:H^{A}}\times k_{1}^{:F^{L^{A}}})\times(h_{2}^{:H^{B}}\times k_{2}^{:F^{L^{B}}})\rightarrow\text{zip}_{H}(h_{1}\times h_{2})\times\big(\text{zip}_{F}(k_{1}\times k_{2})\triangleright\overline{\text{zip}_{L}}^{\uparrow F}\big)\quad.
-\end{align*}
+\begin_layout Plain Layout
+
+wu
+\end_layout
\end_inset
-The function
+ does not have the type of a function.
+ A simple example when this problem occurs is with the
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-toG
+List
\end_layout
\end_inset
- converts values of type
-\begin_inset Formula $N^{A}$
-\end_inset
-
- to values of type
-\begin_inset Formula $G^{A}$
+ functor.
+ The value
+\begin_inset Formula $\text{wu}_{\text{List}}$
\end_inset
-:
+ is then defined as:
\begin_inset Formula
\[
-\text{toG}:N^{A}\rightarrow G^{A}\quad,\quad\quad\text{toG}\triangleq\text{ex}_{N}\bef\text{pu}_{G}\quad.
+\text{wu}_{\text{List}}:\text{List}^{\bbnum 1}\cong\bbnum 1+\bbnum 1\times\text{List}^{\bbnum 1}\quad,\quad\quad\text{wu}_{\text{List}}\triangleq\bbnum 0+1^{:\bbnum 1}\times\text{wu}_{\text{List}}\quad.
\]
\end_inset
-Then we have the following code:
+This value apparently represents an
+\emph on
+infinite
+\emph default
+ list of unit values:
\begin_inset Formula
-\begin{align*}
- & \text{zip}_{L}:(G^{A}+N^{A})\times(G^{B}+N^{B})\rightarrow G^{A\times B}+N^{A\times B}\quad,\\
- & \text{zip}_{L}\triangleq\,\begin{array}{|c||cc|}
- & G^{A\times B} & N^{A\times B}\\
-\hline G^{A}\times G^{B} & \text{zip}_{G} & \bbnum 0\\
-N^{A}\times G^{B} & (\text{toG}\boxtimes\text{id})\bef\text{zip}_{G} & \bbnum 0\\
-G^{A}\times N^{B} & (\text{id}\boxtimes\text{toG})\bef\text{zip}_{G} & \bbnum 0\\
-N^{A}\times N^{B} & \bbnum 0 & \overline{\text{zip}_{N}}
-\end{array}\quad,\\
- & \text{wu}_{L}:G^{\bbnum 1}+H^{\bbnum 1}\times F^{L^{\bbnum 1}}\quad,\quad\quad\text{wu}_{L}\triangleq\bbnum 0^{:G^{\bbnum 1}}+\text{wu}_{H}\times\text{pu}_{F}(\text{wu}_{L})\quad.
-\end{align*}
+\[
+\text{wu}_{L}=\bbnum 0+1\times\left(\bbnum 0+1\times\left(\bbnum 0+1\times\left(...\right)\right)\right)\quad\quad???
+\]
+
+\end_inset
+We need a
+\begin_inset Quotes eld
\end_inset
+lazy list
+\begin_inset Index idx
+status open
+\begin_layout Plain Layout
+lazy collection
\end_layout
-\begin_layout Standard
+\end_inset
-\series bold
-(b)
-\series default
- Let us use the
-\begin_inset Index idx
-status collapsed
+
+\begin_inset Quotes erd
+\end_inset
+
+ (or another non-eager collection) if we want to define
+\begin_inset listings
+inline true
+status open
\begin_layout Plain Layout
-recursive types!unrolling trick
+
+wu
\end_layout
\end_inset
+ recursively by the code shown above.
+ However, the data structure
+\begin_inset Formula $\text{List}^{A}$
+\end_inset
-\begin_inset Index idx
-status collapsed
+ is eagerly evaluated and can only hold a finite number of values.
+ So, we must conclude that
+\begin_inset listings
+inline true
+status open
\begin_layout Plain Layout
-unrolling trick for recursive types
+
+wu
\end_layout
\end_inset
-unrolling trick to compare the recursive types
-\begin_inset Formula $L$
-\end_inset
+ is undefined for the eager functor
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+List
+\end_layout
- and
-\begin_inset Formula $P$
\end_inset
-:
-\begin_inset Formula
-\[
-L^{A}=G^{A}+H^{A}\times F^{G^{A}+H^{A}\times F^{G^{A}+...}}\quad,\quad\quad P^{A}=F^{G^{A}+H^{A}\times F^{G^{A}+H^{A}\times F^{G^{A}+...}}}\quad.
-\]
+, which then cannot be considered a lawful applicative functor if the standard
+ definition of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
\end_inset
-It suggests that
-\begin_inset Formula $P^{A}\cong F^{L^{A}}$
+ is used.
+ Nevertheless, the associativity and the commutativity laws hold for
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
\end_inset
.
- Then the required properties hold for
-\begin_inset Formula $P$
+ The absence of a well-defined value
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+wu
+\end_layout
+
\end_inset
- due to the functor composition construction (Statement
-\begin_inset space ~
+ does not lead to practical disadvantages when working with lists.
+ (To make
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+List
+\end_layout
+
\end_inset
+ a lawful applicative functor, one can use a
+\begin_inset Quotes eld
+\end_inset
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-applicative-composition"
-plural "false"
-caps "false"
-noprefix "false"
+padding
+\begin_inset Quotes erd
+\end_inset
+
+ version of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
\end_inset
-).
- To establish a type equivalence
-\begin_inset Formula $P^{A}\cong F^{L^{A}}$
+
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+padding
+\family typewriter
+zip
+\end_layout
+
\end_inset
- rigorously, we use Statement
+ as shown in Exercise
\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-unrolling-trick"
+reference "subsec:Exercise-applicative-I-1-1-1"
plural "false"
caps "false"
noprefix "false"
\end_inset
- below, where we need to set
-\begin_inset Formula $R\triangleq F$
-\end_inset
+.)
+\end_layout
-,
-\begin_inset Formula $S^{T}\triangleq G^{A}+H^{A}\times T$
+\begin_layout Standard
+For certain choices of
+\begin_inset Formula $F$
\end_inset
,
-\begin_inset Formula $U\triangleq P^{A}$
+\begin_inset Formula $G$
\end_inset
, and
-\begin_inset Formula $V\triangleq L^{A}$
+\begin_inset Formula $H$
\end_inset
-.
-
-\begin_inset Formula $\square$
+, the functor
+\begin_inset Formula $L$
\end_inset
+ will be a monad.
+ It is important that the implementation of applicative methods
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+pure
\end_layout
-\begin_layout Standard
-Note that the construction shown in Statement
-\begin_inset space ~
\end_inset
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Statement-applicative-recursive-type-1"
-plural "false"
-caps "false"
-noprefix "false"
+map2
+\end_layout
\end_inset
- needs to define
-\emph on
-both
-\emph default
-
+, and
\begin_inset listings
inline true
status open
@@ -22154,33 +22956,34 @@ zip
\end_inset
- and
+ for this functor will be, in general, incompatible with its monad methods.
+ The
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-wu
+List
\end_layout
\end_inset
- recursively.
- This leads to a problem in case
+ functor again gives an example where the monad is not commutative while
+ the applicative functor is.
+ So, the commutative
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-wu
+zip
\end_layout
\end_inset
- does not have the type of a function.
- A simple example when this problem occurs is with the
+ method of
\begin_inset listings
inline true
status open
@@ -22192,378 +22995,441 @@ List
\end_inset
- functor.
- The value
-\begin_inset Formula $\text{wu}_{\text{List}}$
-\end_inset
-
- is then defined as:
-\begin_inset Formula
-\[
-\text{wu}_{\text{List}}:\text{List}^{\bbnum 1}\cong\bbnum 1+\bbnum 1\times\text{List}^{\bbnum 1}\quad,\quad\quad\text{wu}_{\text{List}}\triangleq\bbnum 0+1^{:\bbnum 1}\times\text{wu}_{\text{List}}\quad.
-\]
-
-\end_inset
+ cannot be defined via its
+\begin_inset listings
+inline true
+status open
-This value apparently represents an
-\emph on
-infinite
-\emph default
- list of unit values:
-\begin_inset Formula
-\[
-\text{wu}_{L}=\bbnum 0+1\times\left(\bbnum 0+1\times\left(\bbnum 0+1\times\left(...\right)\right)\right)\quad\quad???
-\]
+\begin_layout Plain Layout
-\end_inset
+map
+\end_layout
-We need a
-\begin_inset Quotes eld
\end_inset
-lazy list
-\begin_inset Index idx
+ and
+\begin_inset listings
+inline true
status open
\begin_layout Plain Layout
-lazy collection
-\end_layout
-
-\end_inset
+flatMap
+\end_layout
-\begin_inset Quotes erd
\end_inset
- (or another non-eager collection) if we want to define
+ methods.
+ Also, the
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-wu
+List
\end_layout
\end_inset
- recursively by the code shown above.
- However, the data structure
-\begin_inset Formula $\text{List}^{A}$
-\end_inset
-
- is eagerly evaluated and can only hold a finite number of values.
- So, we must conclude that
+ monad's
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-wu
+pure
\end_layout
\end_inset
- is undefined for the eager functor
+ method (returning a list with a single value) differs from the applicative
+
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-List
+pure
\end_layout
\end_inset
-, which then cannot be considered a lawful applicative functor if the standard
- definition of
+ method (returning an infinite list of values, as we just saw).
+\end_layout
+
+\begin_layout Standard
+There exist other recursive constructions that produce lawful applicative
+ functors.
+ For instance, assume a
+\begin_inset Quotes eld
+\end_inset
+
+biapplicative bifunctor
+\begin_inset Quotes erd
+\end_inset
+
+
+\begin_inset Formula $P$
+\end_inset
+
+ having a
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-zip
+bizip
\end_layout
\end_inset
- is used.
- Nevertheless, the associativity and the commutativity laws hold for
+ method with this type signature:
+\begin_inset Formula
+\[
+\text{bizip}_{P}^{A,B,F}:P^{A,F^{A}}\times P^{B,F^{B}}\rightarrow P^{A\times B,F^{A}\times F^{B}}\quad(\text{for all functors }F)\quad.
+\]
+
+\end_inset
+
+The bifunctor
+\begin_inset Formula $P$
+\end_inset
+
+ should also have a designated
+\begin_inset Quotes eld
+\end_inset
+
+wrapped unit
+\begin_inset Quotes erd
+\end_inset
+
+ value,
+\begin_inset Formula $\text{wu}_{P}:P^{\bbnum 1,\bbnum 1}$
+\end_inset
+
+.
+ Then the functor
+\begin_inset Formula $L$
+\end_inset
+
+ defined via the recursive type equation
+\begin_inset Formula $L^{A}\triangleq P^{A,L^{A}}$
+\end_inset
+
+ will be applicative when suitable laws are imposed on
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-zip
+bizip
+\end_layout
+
+\end_inset
+
+.
+ The methods
+\begin_inset Formula $\text{wu}_{L}$
+\end_inset
+
+ and
+\begin_inset Formula $\text{zip}_{L}$
+\end_inset
+
+ will be defined recursively by:
+\begin_inset Formula
+\begin{align*}
+\text{wu}_{L}:L^{\bbnum 1}\cong P^{\bbnum 1,L^{\bbnum 1}}\quad, & \quad\quad\text{wu}_{L}\triangleq\text{wu}_{P}\triangleright(\_\rightarrow\overline{\text{wu}_{L}})^{\uparrow P^{\bbnum 1,\bullet}}\quad,\\
+\text{zip}_{L}:P^{A,L^{A}}\times P^{B,L^{B}}\rightarrow P^{A\times B,L^{A\times B}}\quad, & \quad\quad\text{zip}_{L}=\text{bizip}_{P}^{A,B,L^{\bullet}}\bef\overline{\text{zip}_{L}}^{\uparrow P^{A\times B,\bullet}}\quad.
+\end{align*}
+
+\end_inset
+
+
\end_layout
+\begin_layout Standard
+To find what biapplicative bifunctors
+\begin_inset Formula $P$
+\end_inset
+
+ exist, one could continue with structural analysis (considering products
+
+\begin_inset Formula $P_{1}\times P_{2}$
+\end_inset
+
+, co-products
+\begin_inset Formula $P_{1}+P_{2}$
+\end_inset
+
+, and so on).
+ This book will not pursue that analysis further, because we already found
+ sufficiently many type constructions required for practical applications.
+\begin_inset Note Note
+status collapsed
+
+\begin_layout Plain Layout
+Note that any functor defined via a recursive type equation
+\begin_inset Formula $L^{A}\triangleq S^{A,L^{\bullet}}$
+\end_inset
+
+ will be applicative if
+\begin_inset Formula $S^{A,R^{\bullet}}$
+\end_inset
+
+ produces an applicative functor whenever
+\begin_inset Formula $R^{\bullet}$
\end_inset
-.
- The absence of a well-defined value
-\begin_inset listings
-inline true
-status open
+ is applicative.
+ Statements
+\begin_inset space ~
+\end_inset
-\begin_layout Plain Layout
-wu
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-applicative-recursive-type"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
- does not lead to practical disadvantages when working with finite lists.
-
-\end_layout
+–
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-applicative-recursive-type-1"
+plural "false"
+caps "false"
+noprefix "false"
-\begin_layout Standard
-For certain choices of
-\begin_inset Formula $F$
\end_inset
-,
-\begin_inset Formula $G$
+ are obtained with
+\begin_inset Formula $S^{A,R^{\bullet}}\triangleq A+H^{A}\times F^{R^{A}}$
\end_inset
-, and
-\begin_inset Formula $H$
+ and
+\begin_inset Formula $S^{A,R^{\bullet}}\triangleq G^{A}+H^{A}\times F^{R^{A}}$
\end_inset
-, the functor
-\begin_inset Formula $L$
+.
+ Other examples of such
+\begin_inset Formula $S^{\bullet,\bullet}$
\end_inset
- will be a monad.
- It is important that the implementation of applicative methods
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-
-pure
+ can be found by combining some type constructions that are known to produce
+ applicative functors.
\end_layout
\end_inset
-,
-\begin_inset listings
-inline true
-status open
-\begin_layout Plain Layout
-
-map2
\end_layout
+\begin_layout Standard
+We conclude this section with a proof of one version of the
+\begin_inset Quotes eld
+\end_inset
+
+unrolling trick
+\begin_inset Quotes erd
\end_inset
-, and
-\begin_inset listings
-inline true
-status open
+ for recursive types:
+\begin_inset Index idx
+status collapsed
\begin_layout Plain Layout
-
-zip
+unrolling trick for recursive types!proof
\end_layout
\end_inset
- for this functor will be, in general, incompatible with its monad methods.
- The
-\begin_inset listings
-inline true
-status open
-\begin_layout Plain Layout
+\begin_inset Index idx
+status collapsed
-List
+\begin_layout Plain Layout
+recursive types!unrolling trick!proof
\end_layout
\end_inset
- functor again gives an example where the monad is not commutative while
- the applicative functor is.
- So, the commutative
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-zip
\end_layout
-\end_inset
+\begin_layout Subsubsection
+Statement
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Statement-unrolling-trick"
- method of
-\begin_inset listings
-inline true
-status open
+\end_inset
-\begin_layout Plain Layout
-List
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-unrolling-trick"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
- cannot be defined via its
-\begin_inset listings
-inline true
-status open
-\begin_layout Plain Layout
-
-map
\end_layout
+\begin_layout Standard
+Given two functors
+\begin_inset Formula $R$
\end_inset
and
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
+\begin_inset Formula $S$
+\end_inset
-flatMap
-\end_layout
+, define two recursive types
+\begin_inset Formula $U$
+\end_inset
+ and
+\begin_inset Formula $V$
\end_inset
- methods.
- Also, the
-\begin_inset listings
-inline true
-status open
+ by
+\begin_inset Formula $U\triangleq R^{S^{U}}$
+\end_inset
-\begin_layout Plain Layout
+ and
+\begin_inset Formula $V\triangleq S^{R^{V}}$
+\end_inset
-List
-\end_layout
+.
+ The
+\begin_inset Quotes eld
+\end_inset
+unrolling trick
+\begin_inset Quotes erd
\end_inset
- monad's
-\begin_inset listings
-inline true
-status open
+ writes (non-rigorously)
+\begin_inset Formula $U=R^{S^{R^{S^{\iddots}}}}\!$
+\end_inset
-\begin_layout Plain Layout
+ and
+\begin_inset Formula $V=S^{R^{S^{R^{\iddots}}}}\!$
+\end_inset
-pure
-\end_layout
+, which suggests that
+\begin_inset Formula $U$
+\end_inset
+ and
+\begin_inset Formula $R^{V}$
\end_inset
- method (returning a list with a single value) differs from the applicative
-
-\begin_inset listings
-inline true
-status open
+ are the same type.
+ In fact, the type
+\begin_inset Formula $U$
+\end_inset
-\begin_layout Plain Layout
+ is rigorously equivalent to the type
+\begin_inset Formula $R^{V}$
+\end_inset
-pure
+.
\end_layout
-\end_inset
-
- method (returning an infinite list of values, as we just saw).
+\begin_layout Subparagraph
+Proof
\end_layout
\begin_layout Standard
-There exist other recursive constructions that produce lawful applicative
- functors.
- For instance, one could assume an
-\begin_inset Quotes eld
-\end_inset
-
-biapplicative bifunctor
-\begin_inset Quotes erd
+We will show that
+\begin_inset Formula $U\cong R^{V}$
\end_inset
+ by implementing the isomorphisms in two directions.
-\begin_inset Formula $P$
-\end_inset
-
- having a
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-
-bizip
\end_layout
+\begin_layout Standard
+By definition of the type
+\begin_inset Formula $U$
\end_inset
- method with this type signature:
-\begin_inset Formula
-\[
-\text{bizip}_{P}^{A,B,F}:P^{A,F^{A}}\times P^{B,F^{B}}\rightarrow P^{A\times B,F^{A}\times F^{B}}\quad(\text{for all functors }F)\quad.
-\]
+, we must have some isomorphisms (called
+\begin_inset Formula $\text{fix}_{U}$
+\end_inset
+ and
+\begin_inset Formula $\text{unfix}_{U}$
\end_inset
-The bifunctor
-\begin_inset Formula $P$
+) between types
+\begin_inset Formula $U$
\end_inset
- should also have a designated
-\begin_inset Quotes eld
+ and
+\begin_inset Formula $R^{S^{U}}$
\end_inset
-wrapped unit
-\begin_inset Quotes erd
+, and similarly for the type
+\begin_inset Formula $V$
\end_inset
- value,
-\begin_inset Formula $\text{wu}_{P}:P^{\bbnum 1,\bbnum 1}$
+.
+ So, we assume that the following functions are known and satisfy the properties
+ of isomorphisms:
+\begin_inset Formula
+\begin{align*}
+ & \text{fix}_{U}:R^{S^{U}}\rightarrow U\quad,\quad\text{unfix}_{U}:U\rightarrow R^{S^{U}}\quad,\quad\text{fix}_{U}\bef\text{unfix}_{U}=\text{id}\quad,\quad\text{unfix}_{U}\bef\text{fix}_{U}=\text{id}\quad;\\
+ & \text{fix}_{V}:S^{R^{V}}\rightarrow V\quad,\quad\text{unfix}_{V}:V\rightarrow S^{R^{V}}\quad,\quad\text{fix}_{V}\bef\text{unfix}_{V}=\text{id}\quad,\quad\text{unfix}_{V}\bef\text{fix}_{V}=\text{id}\quad.
+\end{align*}
+
\end_inset
-.
- Then the functor
-\begin_inset Formula $L$
-\end_inset
- defined via the recursive type equation
-\begin_inset Formula $L^{A}\triangleq P^{A,L^{A}}$
-\end_inset
+\end_layout
- will be applicative when suitable laws are imposed on
+\begin_layout Standard
+We implement the isomorphism functions (called
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-bizip
+toU
\end_layout
-\end_inset
-
-.
- The methods
-\begin_inset Formula $\text{wu}_{L}$
\end_inset
and
-\begin_inset Formula $\text{zip}_{L}$
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+toRV
+\end_layout
+
\end_inset
- will be defined recursively by:
+) recursively:
\begin_inset Formula
\begin{align*}
-\text{wu}_{L}:L^{\bbnum 1}\cong P^{\bbnum 1,L^{\bbnum 1}}\quad, & \quad\quad\text{wu}_{L}\triangleq\text{wu}_{P}\triangleright(\_\rightarrow\overline{\text{wu}_{L}})^{\uparrow P^{\bbnum 1,\bullet}}\quad,\\
-\text{zip}_{L}:P^{A,L^{A}}\times P^{B,L^{B}}\rightarrow P^{A\times B,L^{A\times B}}\quad, & \quad\quad\text{zip}_{L}=\text{bizip}_{P}^{A,B,L^{\bullet}}\bef\overline{\text{zip}_{L}}^{\uparrow P^{A\times B,\bullet}}\quad.
+ & \text{toU}:R^{V}\rightarrow U\quad,\quad\quad\text{toU}\triangleq\text{unfix}_{V}^{\uparrow R}\bef\overline{\text{toU}}^{\uparrow S\uparrow R}\bef\text{fix}_{U}\quad;\\
+ & \text{toRV}:U\rightarrow R^{V}\quad,\quad\quad\text{toRV}\triangleq\text{unfix}_{U}\bef\overline{\text{toRV}}^{\uparrow S\uparrow R}\bef\text{fix}_{V}^{\uparrow R}\quad.
\end{align*}
\end_inset
@@ -22572,129 +23438,205 @@ bizip
\end_layout
\begin_layout Standard
-To find what biapplicative bifunctors
-\begin_inset Formula $P$
+To verify the isomorphism properties (
+\begin_inset Formula $\text{toU}\bef\text{toRV}=\text{id}$
\end_inset
- exist, one could continue with structural analysis (considering products
-
-\begin_inset Formula $P_{1}\times P_{2}$
+ and
+\begin_inset Formula $\text{toRV}\bef\text{toU}=\text{id}$
\end_inset
-, co-products
-\begin_inset Formula $P_{1}+P_{2}$
+), we use the inductive assumption that those properties already hold for
+ any recursive calls of these functions:
+\begin_inset Formula
+\begin{align*}
+ & \text{toU}\bef\text{toRV}=\text{unfix}_{V}^{\uparrow R}\bef\overline{\text{toU}}^{\uparrow S\uparrow R}\bef\gunderline{\text{fix}_{U}\bef\text{unfix}_{U}}\bef\overline{\text{toRV}}^{\uparrow S\uparrow R}\bef\text{fix}_{V}^{\uparrow R}\\
+ & \quad=\text{unfix}_{V}^{\uparrow R}\bef\gunderline{\overline{\text{toU}}^{\uparrow S\uparrow R}\bef\overline{\text{toRV}}^{\uparrow S\uparrow R}}\bef\text{fix}_{V}^{\uparrow R}=\text{unfix}_{V}^{\uparrow R}\bef\text{fix}_{V}^{\uparrow R}=\text{id}\quad,\\
+ & \text{toRV}\bef\text{toU}=\text{unfix}_{U}\bef\overline{\text{toRV}}^{\uparrow S\uparrow R}\bef\gunderline{\text{fix}_{V}^{\uparrow R}\bef\text{unfix}_{V}^{\uparrow R}}\bef\overline{\text{toU}}^{\uparrow S\uparrow R}\bef\text{fix}_{U}\\
+ & \quad=\text{unfix}_{U}\bef\gunderline{\overline{\text{toRV}}^{\uparrow S\uparrow R}\bef\overline{\text{toU}}^{\uparrow S\uparrow R}}\bef\text{fix}_{U}=\text{unfix}_{U}\bef\text{fix}_{U}=\text{id}\quad.
+\end{align*}
+
\end_inset
-, and so on).
- This book will not pursue that analysis further, because we already found
- sufficiently many type constructions required for practical applications.
-\begin_inset Note Note
-status open
-\begin_layout Plain Layout
-Note that any functor defined via a recursive type equation
-\begin_inset Formula $L^{A}\triangleq S^{A,L^{\bullet}}$
-\end_inset
+\end_layout
- will be applicative if
-\begin_inset Formula $S^{A,R^{\bullet}}$
-\end_inset
+\begin_layout Section
+Applicative contrafunctors and profunctors
+\begin_inset CommandInset label
+LatexCommand label
+name "sec:Applicative-contrafunctors-and-profunctors"
- produces an applicative functor whenever
-\begin_inset Formula $R^{\bullet}$
\end_inset
- is applicative.
- Statements
+
+\end_layout
+
+\begin_layout Standard
+We have seen in Example
\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-applicative-recursive-type"
+reference "subsec:Example-applicative-profunctor"
plural "false"
caps "false"
noprefix "false"
\end_inset
-–
+ that a
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ method can be implemented for some type constructors that are not covariant.
+ In this section, we will apply structural analysis systematically to discover
+ the non-covariant type constructors (contrafunctors and profunctors) that
+ admit a lawful
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ method.
+\end_layout
+
+\begin_layout Subsection
+Applicative contrafunctors: Laws and constructions
+\end_layout
+
+\begin_layout Standard
+Contrafunctors (see Section
+\begin_inset space ~
+\end_inset
+
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-applicative-recursive-type-1"
+reference "subsec:Contrafunctors"
plural "false"
caps "false"
noprefix "false"
\end_inset
- are obtained with
-\begin_inset Formula $S^{A,R^{\bullet}}\triangleq A+H^{A}\times F^{R^{A}}$
+) support a
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+contramap
+\end_layout
+
\end_inset
- and
-\begin_inset Formula $S^{A,R^{\bullet}}\triangleq G^{A}+H^{A}\times F^{R^{A}}$
+ method instead of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map
+\end_layout
+
\end_inset
.
- Other examples of such
-\begin_inset Formula $S^{\bullet,\bullet}$
-\end_inset
+ So, contrafunctors cannot have the
+\begin_inset listings
+inline true
+status open
- can be found by combining some type constructions that are known to produce
- applicative functors.
+\begin_layout Plain Layout
+
+map2
\end_layout
\end_inset
+ or
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+ap
\end_layout
-\begin_layout Standard
-We conclude this section with a proof of one version of the
-\begin_inset Quotes eld
\end_inset
-unrolling trick
-\begin_inset Quotes erd
+ methods.
+ Nevertheless, the applicative laws can be formulated via
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
\end_inset
- for recursive types:
-\begin_inset Index idx
-status collapsed
+ and
+\begin_inset listings
+inline true
+status open
\begin_layout Plain Layout
-unrolling trick for recursive types!proof
+
+wu
\end_layout
\end_inset
-
-\begin_inset Index idx
-status collapsed
+ methods using
+\begin_inset listings
+inline true
+status open
\begin_layout Plain Layout
-recursive types!unrolling trick!proof
+
+contramap
\end_layout
\end_inset
-
+:
\end_layout
\begin_layout Subsubsection
-Statement
+Definition
\begin_inset CommandInset label
LatexCommand label
-name "subsec:Statement-unrolling-trick"
+name "subsec:Definition-applicative-contrafunctor"
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-unrolling-trick"
+reference "subsec:Definition-applicative-contrafunctor"
plural "false"
caps "false"
noprefix "false"
@@ -22705,776 +23647,881 @@ noprefix "false"
\end_layout
\begin_layout Standard
-Given two functors
-\begin_inset Formula $R$
+A contrafunctor
+\begin_inset Formula $C$
+\end_inset
+
+ is
+\series bold
+applicative
+\series default
+ if there exist methods
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
\end_inset
and
-\begin_inset Formula $S$
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+wu
+\end_layout
+
\end_inset
-, define two recursive types
-\begin_inset Formula $U$
+ such that:
+\begin_inset Formula
+\begin{align}
+ & \text{zip}_{C}:C^{A}\times C^{B}\rightarrow C^{A\times B}\quad,\quad\quad\text{wu}_{C}:C^{\bbnum 1}\quad,\nonumber \\
+ & \quad\text{associativity law}:\quad\nonumber \\
+ & \text{zip}_{C}(p\times\text{zip}_{C}(q\times r))\triangleright\tilde{\varepsilon}_{1,23}^{\downarrow C}=\text{zip}_{C}(\text{zip}_{C}(p\times q)\times r)\triangleright\tilde{\varepsilon}_{12,3}^{\downarrow C}\quad,\label{eq:applicative-contrafunctor-associativity-law}\\
+ & \quad\text{left and right identity laws}:\quad\nonumber \\
+ & \text{zip}_{C}(\text{wu}_{C}\times p)\triangleright\text{ilu}^{\downarrow C}=p\quad,\quad\quad\text{zip}_{C}(p\times\text{wu}_{C})\triangleright\text{iru}^{\downarrow C}=p\quad.\label{eq:applicative-contrafunctor-identity-laws}
+\end{align}
+
\end_inset
- and
-\begin_inset Formula $V$
+Here the tuple-rearranging isomorphisms
+\begin_inset Formula $\tilde{\varepsilon}_{1,23}$
\end_inset
- by
-\begin_inset Formula $U\triangleq R^{S^{U}}$
+,
+\begin_inset Formula $\tilde{\varepsilon}_{12,3}$
\end_inset
- and
-\begin_inset Formula $V\triangleq S^{R^{V}}$
-\end_inset
+,
+\begin_inset listings
+inline true
+status open
-.
- The
-\begin_inset Quotes eld
-\end_inset
+\begin_layout Plain Layout
-unrolling trick
-\begin_inset Quotes erd
-\end_inset
+ilu
+\end_layout
- writes (non-rigorously)
-\begin_inset Formula $U=R^{S^{R^{S^{\iddots}}}}\!$
\end_inset
- and
-\begin_inset Formula $V=S^{R^{S^{R^{\iddots}}}}\!$
-\end_inset
+, and
+\begin_inset listings
+inline true
+status open
-, which suggests that
-\begin_inset Formula $U$
-\end_inset
+\begin_layout Plain Layout
+
+iru
+\end_layout
- and
-\begin_inset Formula $R^{V}$
\end_inset
- are the same type.
- In fact, the type
-\begin_inset Formula $U$
+ are defined by:
+\begin_inset Formula
+\begin{align*}
+ & \tilde{\varepsilon}_{1,23}\triangleq a\times b\times c\rightarrow a\times\left(b\times c\right)\quad,\quad\quad\tilde{\varepsilon}_{12,3}\triangleq a\times b\times c\rightarrow\left(a\times b\right)\times c\quad,\\
+ & \text{ilu}\triangleq a\rightarrow1\times a\quad,\quad\quad\text{iru}=a\rightarrow a\times1\quad.
+\end{align*}
+
\end_inset
- is rigorously equivalent to the type
-\begin_inset Formula $R^{V}$
+
+\begin_inset Formula $\square$
\end_inset
-.
-\end_layout
-\begin_layout Subparagraph
-Proof
\end_layout
\begin_layout Standard
-We will show that
-\begin_inset Formula $U\cong R^{V}$
-\end_inset
+An example of an applicative contrafunctor is the equality comparison typeclass
+ (
+\begin_inset listings
+inline true
+status open
- by implementing the isomorphisms in two directions.
-
+\begin_layout Plain Layout
+
+Eq
\end_layout
-\begin_layout Standard
-By definition of the type
-\begin_inset Formula $U$
\end_inset
-, we must have some isomorphisms (called
-\begin_inset Formula $\text{fix}_{U}$
+, defined in Section
+\begin_inset space ~
\end_inset
- and
-\begin_inset Formula $\text{unfix}_{U}$
-\end_inset
-) between types
-\begin_inset Formula $U$
-\end_inset
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:The-Eq-typeclass"
+plural "false"
+caps "false"
+noprefix "false"
- and
-\begin_inset Formula $R^{S^{U}}$
\end_inset
-, and similarly for the type
-\begin_inset Formula $V$
+) viewed as a type constructor
+\begin_inset Formula $\text{Eq}^{A}\triangleq A\times A\rightarrow\bbnum 2$
\end_inset
.
- So, we assume that the following functions are known and satisfy the properties
- of isomorphisms:
+ This type constructor supports a
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ method:
\begin_inset Formula
\begin{align*}
- & \text{fix}_{U}:R^{S^{U}}\rightarrow U\quad,\quad\text{unfix}_{U}:U\rightarrow R^{S^{U}}\quad,\quad\text{fix}_{U}\bef\text{unfix}_{U}=\text{id}\quad,\quad\text{unfix}_{U}\bef\text{fix}_{U}=\text{id}\quad;\\
- & \text{fix}_{V}:S^{R^{V}}\rightarrow V\quad,\quad\text{unfix}_{V}:V\rightarrow S^{R^{V}}\quad,\quad\text{fix}_{V}\bef\text{unfix}_{V}=\text{id}\quad,\quad\text{unfix}_{V}\bef\text{fix}_{V}=\text{id}\quad.
+ & \text{zip}:\text{Eq}^{A}\times\text{Eq}^{B}\rightarrow\text{Eq}^{A\times B}\quad,\\
+ & \text{zip}\,(p^{:\text{Eq}^{A}}\times q^{:\text{Eq}^{B}})\triangleq(a_{1}^{:A}\times b_{1}^{:B})\times(a_{2}^{:A}\times b_{2}^{:B})\rightarrow p(a_{1}\times a_{2})\,\wedge\,q(b_{1}\times b_{2})\quad.
\end{align*}
\end_inset
+Note that we are using the Boolean
+\begin_inset Quotes eld
+\end_inset
-\end_layout
+and
+\begin_inset Quotes erd
+\end_inset
-\begin_layout Standard
-We implement the isomorphism functions (called
+ operation (
+\begin_inset Formula $\wedge$
+\end_inset
+
+) because two pairs are equal when both the first parts and the second parts
+ are equal separately.
+ This
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-toU
+zip
\end_layout
\end_inset
- and
+ method allows us to derive
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-toRV
+Eq
\end_layout
\end_inset
-) recursively:
-\begin_inset Formula
-\begin{align*}
- & \text{toU}:R^{V}\rightarrow U\quad,\quad\quad\text{toU}\triangleq\text{unfix}_{V}^{\uparrow R}\bef\overline{\text{toU}}^{\uparrow S\uparrow R}\bef\text{fix}_{U}\quad;\\
- & \text{toRV}:U\rightarrow R^{V}\quad,\quad\quad\text{toRV}\triangleq\text{unfix}_{U}\bef\overline{\text{toRV}}^{\uparrow S\uparrow R}\bef\text{fix}_{V}^{\uparrow R}\quad.
-\end{align*}
+ typeclass instances for product types (e.g., for case classes) automatically.
+\end_layout
-\end_inset
+\begin_layout Standard
+It is important to require the laws to hold for
+\begin_inset listings
+inline true
+status open
+\begin_layout Plain Layout
+zip
\end_layout
-\begin_layout Standard
-To verify the isomorphism properties (
-\begin_inset Formula $\text{toU}\bef\text{toRV}=\text{id}$
\end_inset
- and
-\begin_inset Formula $\text{toRV}\bef\text{toU}=\text{id}$
-\end_inset
+.
+ Otherwise, a function with the type signature of
+\begin_inset listings
+inline true
+status open
-), we use the inductive assumption that those properties already hold for
- any recursive calls of these functions:
-\begin_inset Formula
-\begin{align*}
- & \text{toU}\bef\text{toRV}=\text{unfix}_{V}^{\uparrow R}\bef\overline{\text{toU}}^{\uparrow S\uparrow R}\bef\gunderline{\text{fix}_{U}\bef\text{unfix}_{U}}\bef\overline{\text{toRV}}^{\uparrow S\uparrow R}\bef\text{fix}_{V}^{\uparrow R}\\
- & \quad=\text{unfix}_{V}^{\uparrow R}\bef\gunderline{\overline{\text{toU}}^{\uparrow S\uparrow R}\bef\overline{\text{toRV}}^{\uparrow S\uparrow R}}\bef\text{fix}_{V}^{\uparrow R}=\text{unfix}_{V}^{\uparrow R}\bef\text{fix}_{V}^{\uparrow R}=\text{id}\quad,\\
- & \text{toRV}\bef\text{toU}=\text{unfix}_{U}\bef\overline{\text{toRV}}^{\uparrow S\uparrow R}\bef\gunderline{\text{fix}_{V}^{\uparrow R}\bef\text{unfix}_{V}^{\uparrow R}}\bef\overline{\text{toU}}^{\uparrow S\uparrow R}\bef\text{fix}_{U}\\
- & \quad=\text{unfix}_{U}\bef\gunderline{\overline{\text{toRV}}^{\uparrow S\uparrow R}\bef\overline{\text{toU}}^{\uparrow S\uparrow R}}\bef\text{fix}_{U}=\text{unfix}_{U}\bef\text{fix}_{U}=\text{id}\quad.
-\end{align*}
+\begin_layout Plain Layout
-\end_inset
+zip
+\end_layout
+\end_inset
-\end_layout
+ could be implemented for any contrafunctor
+\begin_inset Formula $C$
+\end_inset
-\begin_layout Section
-Applicative contrafunctors and profunctors
-\begin_inset CommandInset label
-LatexCommand label
-name "sec:Applicative-contrafunctors-and-profunctors"
+:
+\begin_inset Formula
+\[
+\text{badZip}:C^{A}\times C^{B}\rightarrow C^{A\times B}\quad,\quad\quad\text{badZip}\triangleq(p^{:C^{A}}\times\_^{:C^{B}})\rightarrow p\triangleright(a\times b\rightarrow a)^{\downarrow C}\quad.
+\]
\end_inset
+This function loses information because it ignores one of its arguments.
+ Intuitively, we expect that some laws will fail for this function.
+ Indeed, the left identity law cannot hold:
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+badZip(wu, p)
\end_layout
-\begin_layout Standard
-We have seen in Example
-\begin_inset space ~
\end_inset
+ ignores
+\begin_inset listings
+inline true
+status open
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Example-applicative-profunctor"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Plain Layout
+
+p
+\end_layout
\end_inset
- that a
+, so
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-zip
+badZip(wu, p).contramap(ilu)
\end_layout
\end_inset
- method can be implemented for some type constructors that are not covariant.
- In this section, we will apply structural analysis systematically to discover
- the non-covariant type constructors (contrafunctors and profunctors) that
- admit a lawful
+ cannot be equal to
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-zip
+p
\end_layout
\end_inset
- method.
-\end_layout
-
-\begin_layout Subsection
-Applicative contrafunctors: Laws and constructions
+.
\end_layout
\begin_layout Standard
-Contrafunctors (see Section
-\begin_inset space ~
-\end_inset
-
+The laws of
+\begin_inset listings
+inline true
+status open
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Contrafunctors"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Plain Layout
+
+zip
+\end_layout
\end_inset
-) support a
+ describe a programmer's expectations about how a function should be distributed
+ over pairs of arguments.
+ In the example of the
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-contramap
+zip
\end_layout
\end_inset
- method instead of
+ method for
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-map
+Eq
\end_layout
\end_inset
-.
- So, contrafunctors cannot have the
+, a violation of the laws of
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-map2
+zip
\end_layout
\end_inset
- or
+ would mean that comparisons of pairs give wrong results.
+\end_layout
+
+\begin_layout Standard
+Once the
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-ap
+zip
\end_layout
\end_inset
- methods.
- Nevertheless, the applicative laws can be formulated via
+ and
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-zip
+wu
\end_layout
\end_inset
- and
+ methods are known, we can define
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-wu
+cpure
\end_layout
\end_inset
- methods using
+ and
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-contramap
+cmap2
\end_layout
\end_inset
:
+\begin_inset Formula
+\begin{align*}
+ & \text{cpu}_{C}:\forall A.\,C^{A}\quad,\quad\quad\text{cpu}_{C}\triangleq\text{wu}_{C}\triangleright(\_^{:A}\rightarrow1)^{\downarrow C}\quad,\\
+ & \text{cmap}_{2}:(D\rightarrow A\times B)\rightarrow C^{A}\times C^{B}\rightarrow C^{D}\quad,\quad\quad\text{cmap}_{2}(f^{:D\rightarrow A\times B})\triangleq\text{zip}_{C}\bef f^{\downarrow C}\quad.
+\end{align*}
+
+\end_inset
+
+
\end_layout
-\begin_layout Subsubsection
-Definition
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Definition-applicative-contrafunctor"
+\begin_layout Standard
+The commutativity law is formulated for applicative contrafunctors like
+ this:
+\begin_inset Formula
+\begin{align*}
+ & \text{zip}_{C}(q\times p)=\text{zip}_{C}(p\times q)\triangleright\text{swap}^{\downarrow C}\quad,\\
+\text{or equivalently}:\quad & \text{swap}\bef\text{zip}_{C}=\text{zip}_{C}\bef\text{swap}^{\downarrow C}\quad.
+\end{align*}
+
+\end_inset
+
+\end_layout
+
+\begin_layout Standard
+The rest of this section proves some constructions that produce lawful applicati
+ve contrafunctors.
+ The results are summarized in Table
+\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Definition-applicative-contrafunctor"
+reference "tab:Constructions-of-applicative-contrafunctors"
plural "false"
caps "false"
noprefix "false"
\end_inset
-
+.
\end_layout
\begin_layout Standard
-A contrafunctor
-\begin_inset Formula $C$
-\end_inset
+\begin_inset Float table
+wide false
+sideways false
+status open
+
+\begin_layout Plain Layout
+\align center
+\begin_inset Tabular
+
+
+
+
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
- is
\series bold
-applicative
-\series default
- if there exist methods
-\begin_inset listings
-inline true
-status open
+\size small
+Construction
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-zip
+\series bold
+\size small
+Type notation
\end_layout
\end_inset
+ |
+
+\begin_inset Text
- and
-\begin_inset listings
-inline true
-status open
+\begin_layout Plain Layout
+
+\series bold
+\size small
+Assumptions
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-wu
+\size footnotesize
+fixed type
\end_layout
\end_inset
+ |
+
+\begin_inset Text
- such that:
-\begin_inset Formula
-\begin{align}
- & \text{zip}_{C}:C^{A}\times C^{B}\rightarrow C^{A\times B}\quad,\quad\quad\text{wu}_{C}:C^{\bbnum 1}\quad,\nonumber \\
- & \quad\text{associativity law}:\quad\nonumber \\
- & \text{zip}_{C}(p\times\text{zip}_{C}(q\times r))\triangleright\tilde{\varepsilon}_{1,23}^{\downarrow C}=\text{zip}_{C}(\text{zip}_{C}(p\times q)\times r)\triangleright\tilde{\varepsilon}_{12,3}^{\downarrow C}\quad,\label{eq:applicative-contrafunctor-associativity-law}\\
- & \quad\text{left and right identity laws}:\quad\nonumber \\
- & \text{zip}_{C}(\text{wu}_{C}\times p)\triangleright\text{ilu}^{\downarrow C}=p\quad,\quad\quad\text{zip}_{C}(p\times\text{wu}_{C})\triangleright\text{iru}^{\downarrow C}=p\quad.\label{eq:applicative-contrafunctor-identity-laws}
-\end{align}
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq Z$
\end_inset
-Here the tuple-rearranging isomorphisms
-\begin_inset Formula $\tilde{\varepsilon}_{1,23}$
+
+\end_layout
+
\end_inset
+ |
+
+\begin_inset Text
-,
-\begin_inset Formula $\tilde{\varepsilon}_{12,3}$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $Z$
\end_inset
-,
-\begin_inset listings
-inline true
-status open
+ is a monoid
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-ilu
+\size footnotesize
+identity
\end_layout
\end_inset
-
-, and
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-iru
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq A$
+\end_inset
+
+
\end_layout
\end_inset
+ |
+
+\begin_inset Text
- are defined by:
-\begin_inset Formula
-\begin{align*}
- & \tilde{\varepsilon}_{1,23}\triangleq a\times b\times c\rightarrow a\times\left(b\times c\right)\quad,\quad\quad\tilde{\varepsilon}_{12,3}\triangleq a\times b\times c\rightarrow\left(a\times b\right)\times c\quad,\\
- & \text{ilu}\triangleq a\rightarrow1\times a\quad,\quad\quad\text{iru}=a\rightarrow a\times1\quad.
-\end{align*}
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $F$
\end_inset
+ is commutative
+\end_layout
-\begin_inset Formula $\square$
\end_inset
+ |
+
+
+|
+\begin_inset Text
+\begin_layout Plain Layout
+\size footnotesize
+composition
\end_layout
-\begin_layout Standard
-An example of an applicative contrafunctor is the equality comparison typeclass
- (
-\begin_inset listings
-inline true
-status open
+\end_inset
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-Eq
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq G^{H^{A}}$
+\end_inset
+
+
\end_layout
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $G$
\end_inset
-, defined in Section
+ is an appl.
\begin_inset space ~
\end_inset
-
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:The-Eq-typeclass"
-plural "false"
-caps "false"
-noprefix "false"
-
+functor,
+\begin_inset Formula $H$
\end_inset
-) viewed as a type constructor
-\begin_inset Formula $\text{Eq}^{A}\triangleq A\times A\rightarrow\bbnum 2$
+ is an appl.
+\begin_inset space ~
\end_inset
-.
- This type constructor supports a
-\begin_inset listings
-inline true
-status open
+contrafunctor
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-zip
+\size footnotesize
+product
\end_layout
\end_inset
+ |
+
+\begin_inset Text
- method:
-\begin_inset Formula
-\begin{align*}
- & \text{zip}:\text{Eq}^{A}\times\text{Eq}^{B}\rightarrow\text{Eq}^{A\times B}\quad,\\
- & \text{zip}\,(p^{:\text{Eq}^{A}}\times q^{:\text{Eq}^{B}})\triangleq(a_{1}^{:A}\times b_{1}^{:B})\times(a_{2}^{:A}\times b_{2}^{:B})\rightarrow p(a_{1}\times a_{2})\,\wedge\,q(b_{1}\times b_{2})\quad.
-\end{align*}
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq P^{A}\times Q^{A}$
\end_inset
-Note that we are using the Boolean
-\begin_inset Quotes eld
-\end_inset
-and
-\begin_inset Quotes erd
-\end_inset
+\end_layout
- operation (
-\begin_inset Formula $\wedge$
\end_inset
-
-) because two pairs are equal when both the first parts and the second parts
- are equal separately.
- This
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-zip
-\end_layout
+\size footnotesize
+\begin_inset Formula $P$
+\end_inset
+ and
+\begin_inset Formula $Q$
\end_inset
- method allows us to derive
-\begin_inset listings
-inline true
-status open
+ are applicative contrafunctors
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-Eq
+\size footnotesize
+co-product
\end_layout
\end_inset
+ |
+
+\begin_inset Text
- typeclass instances for product types (e.g., for case classes) automatically.
-\end_layout
+\begin_layout Plain Layout
-\begin_layout Standard
-It is important to require the laws to hold for
-\begin_inset listings
-inline true
-status open
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq P^{A}+Q^{A}$
+\end_inset
-\begin_layout Plain Layout
-zip
\end_layout
\end_inset
-
-.
- Otherwise, a function with the type signature of
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-zip
-\end_layout
-
+\size footnotesize
+\begin_inset Formula $P$
\end_inset
- could be implemented for any contrafunctor
-\begin_inset Formula $C$
+ and
+\begin_inset Formula $Q$
\end_inset
-:
-\begin_inset Formula
-\[
-\text{badZip}:C^{A}\times C^{B}\rightarrow C^{A\times B}\quad,\quad\quad\text{badZip}\triangleq(p^{:C^{A}}\times\_^{:C^{B}})\rightarrow p\triangleright(a\times b\rightarrow a)^{\downarrow C}\quad.
-\]
+ are applicative contrafunctors
+\end_layout
\end_inset
-
-This function loses information because it ignores one of its arguments.
- Intuitively, we expect that some laws will fail for this function.
- Indeed, the left identity law cannot hold:
-\begin_inset listings
-inline true
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-badZip(wu, p)
+\size footnotesize
+function type
\end_layout
\end_inset
-
- ignores
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-p
-\end_layout
-
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq P^{A}\rightarrow Q^{A}$
\end_inset
-, so
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-badZip(wu, p).contramap(ilu)
\end_layout
\end_inset
-
- cannot be equal to
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-p
-\end_layout
+\size footnotesize
+\begin_inset Formula $P$
+\end_inset
+ is any functor,
+\begin_inset Formula $Q$
\end_inset
-.
+ is an applicative contrafunctor
\end_layout
-\begin_layout Standard
-The laws of
-\begin_inset listings
-inline true
-status open
+\end_inset
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-zip
+\size footnotesize
+recursive type
\end_layout
\end_inset
-
- describe a programmer's expectations about how a function should be distributed
- over pairs of arguments.
- In the example of the
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-zip
-\end_layout
-
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq S^{A,F^{P^{A}}}$
\end_inset
- method for
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-Eq
\end_layout
\end_inset
-
-, a violation of the laws of
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-zip
-\end_layout
+\size footnotesize
+\begin_inset Formula $S$
+\end_inset
+ and
+\begin_inset Formula $P$
\end_inset
- would mean that comparisons of pairs give wrong results.
+ are polynomial
\end_layout
-\begin_layout Standard
-Once the
-\begin_inset listings
-inline true
-status open
+\end_inset
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-zip
+\size footnotesize
+recursive type
\end_layout
\end_inset
-
- and
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-wu
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq P^{A}+Q^{A}\times R^{F^{A}}$
+\end_inset
+
+
\end_layout
\end_inset
-
- methods are known, we can define
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-cpure
-\end_layout
-
+\size footnotesize
+conditions in Statement
+\begin_inset space ~
\end_inset
- and
-\begin_inset listings
-inline true
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-applicative-recursive-type-1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
-cmap2
\end_layout
\end_inset
-
-:
-\begin_inset Formula
-\begin{align*}
- & \text{cpu}_{C}:\forall A.\,C^{A}\quad,\quad\quad\text{cpu}_{C}\triangleq\text{wu}_{C}\triangleright(\_^{:A}\rightarrow1)^{\downarrow C}\quad,\\
- & \text{cmap}_{2}:(D\rightarrow A\times B)\rightarrow C^{A}\times C^{B}\rightarrow C^{D}\quad,\quad\quad\text{cmap}_{2}(f^{:D\rightarrow A\times B})\triangleq\text{zip}_{C}\bef f^{\downarrow C}\quad.
-\end{align*}
+ |
+
+
\end_inset
\end_layout
-\begin_layout Standard
-The commutativity law is formulated for applicative contrafunctors like
- this:
-\begin_inset Formula
-\begin{align*}
- & \text{zip}_{C}(q\times p)=\text{zip}_{C}(p\times q)\triangleright\text{swap}^{\downarrow C}\quad,\\
-\text{or equivalently}:\quad & \text{swap}\bef\text{zip}_{C}=\text{zip}_{C}\bef\text{swap}^{\downarrow C}\quad.
-\end{align*}
+\begin_layout Plain Layout
+\begin_inset Caption Standard
+
+\begin_layout Plain Layout
+Constructions of applicative contrafunctors.
+\begin_inset CommandInset label
+LatexCommand label
+name "tab:Constructions-of-applicative-contrafunctors"
\end_inset
\end_layout
-\begin_layout Standard
-The rest of this section proves some constructions that produce lawful applicati
-ve contrafunctors.
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
\end_layout
\begin_layout Paragraph
@@ -25135,72 +26182,297 @@ map
.
\end_layout
-\begin_layout Standard
-Profunctors have an
-\begin_inset listings
-inline true
-status open
+\begin_layout Standard
+Profunctors have an
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+xmap
+\end_layout
+
+\end_inset
+
+ method instead of a
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map
+\end_layout
+
+\end_inset
+
+ method:
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+def xmap[A, B](f: A => B, g: B => A): P[A] => P[B]
+\end_layout
+
+\end_inset
+
+ For brevity, in this section we will denote Scala code such as
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+xmap(f, g)(p)
+\end_layout
+
+\end_inset
+
+ or
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+p.xmap(f, g)
+\end_layout
+
+\end_inset
+
+ by:
+\begin_inset Formula
+\[
+p\triangleright f^{\uparrow P}g^{\downarrow P}\quad,\quad\text{or equivalently}:\quad p\triangleright g^{\downarrow P}f^{\uparrow P}\quad.
+\]
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+The applicative laws for profunctors are formulated via
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+wu
+\end_layout
+
+\end_inset
+
+ methods using
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+xmap
+\end_layout
+
+\end_inset
+
+:
+\end_layout
+
+\begin_layout Subsubsection
+Definition
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Definition-applicative-profunctor"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Definition-applicative-profunctor"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+A profunctor
+\begin_inset Formula $P$
+\end_inset
+
+ is
+\series bold
+applicative
+\series default
+ if there exist methods
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+wu
+\end_layout
+
+\end_inset
+
+ such that:
+\begin_inset Formula
+\begin{align*}
+ & \text{zip}_{P}:P^{A}\times P^{B}\rightarrow P^{A\times B}\quad,\quad\quad\text{zip}_{P}(p\times\text{zip}_{P}(q\times r))\cong\text{zip}_{P}(\text{zip}_{P}(p\times q)\times r)\quad,\\
+ & \text{wu}_{P}:P^{\bbnum 1}\quad,\quad\text{zip}_{P}(\text{wu}_{P}\times p)\cong p\quad,\quad\quad\text{zip}_{P}(p\times\text{wu}_{P})\cong p\quad.
+\end{align*}
+
+\end_inset
+
+Here we imply tuple-rearranging isomorphisms
+\begin_inset Formula $P^{(A\times B)\times C}\cong P^{A\times(B\times C)}$
+\end_inset
+
+ and
+\begin_inset Formula $P^{\bbnum 1\times A}\cong P^{A}\cong P^{A\times\bbnum 1}$
+\end_inset
+
+, which are implemented via the functions
+\begin_inset Formula $\varepsilon_{1,23}$
+\end_inset
+
+,
+\begin_inset Formula $\varepsilon_{12,3}$
+\end_inset
+
+,
+\begin_inset Formula $\tilde{\varepsilon}_{1,23}$
+\end_inset
+
+,
+\begin_inset Formula $\tilde{\varepsilon}_{12,3}$
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+ilu
+\end_layout
+
+\end_inset
+
+, and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+iru
+\end_layout
+
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align*}
+ & \text{zip}_{P}(p\times\text{zip}_{P}(q\times r))\triangleright\varepsilon_{1,23}^{\uparrow P}\tilde{\varepsilon}_{1,23}^{\downarrow P}=\text{zip}_{P}(\text{zip}_{P}(p\times q)\times r)\triangleright\varepsilon_{12,3}^{\uparrow P}\tilde{\varepsilon}_{12,3}^{\downarrow P}\quad,\\
+ & \text{zip}_{P}(\text{wu}_{P}\times p)=p\triangleright\text{ilu}^{\uparrow P}\pi_{2}^{\downarrow P}\quad,\quad\quad\text{zip}_{P}(p\times\text{wu}_{P})=p\triangleright\text{iru}^{\uparrow P}\pi_{1}^{\downarrow P}\quad.
+\end{align*}
+
+\end_inset
-\begin_layout Plain Layout
-xmap
\end_layout
-\end_inset
-
- method instead of a
+\begin_layout Standard
+Once the
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-map
+zip
\end_layout
\end_inset
- method:
+ and
\begin_inset listings
-inline false
+inline true
status open
\begin_layout Plain Layout
-def xmap[A, B](f: A => B, g: B => A): P[A] => P[B]
+wu
\end_layout
\end_inset
- For brevity, in this section we will denote Scala code such as
+ methods are known, we can define
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-xmap(f, g)(p)
+pure
\end_layout
\end_inset
- or
+ and
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-p.xmap(f, g)
+xmap2
\end_layout
\end_inset
- by:
+:
\begin_inset Formula
-\[
-p\triangleright f^{\uparrow P}g^{\downarrow P}\quad,\quad\text{or equivalently}:\quad p\triangleright g^{\downarrow P}f^{\uparrow P}\quad.
-\]
+\begin{align*}
+ & \text{pu}_{P}:A\rightarrow P^{A}\quad,\quad\quad\text{pu}_{P}(a^{:A})\triangleq\text{wu}_{P}\triangleright(\_^{:A}\rightarrow1)^{\downarrow P}(\_^{:\bbnum 1}\rightarrow a)^{\uparrow P}\quad,\\
+ & \text{xmap}_{2}:(A\times B\rightarrow D)\times(D\rightarrow A\times B)\rightarrow P^{A}\times P^{B}\rightarrow P^{D}\quad,\\
+ & \text{xmap}_{2}(f^{:A\times B\rightarrow D}\times g^{:D\rightarrow A\times B})\triangleq\text{zip}_{P}\bef(g^{\downarrow P}f^{\uparrow P})\quad.
+\end{align*}
\end_inset
@@ -25208,83 +26480,80 @@ p\triangleright f^{\uparrow P}g^{\downarrow P}\quad,\quad\text{or equivalently}:
\end_layout
\begin_layout Standard
-The applicative laws for profunctors are formulated via
+It is important that the
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-zip
+pure
\end_layout
\end_inset
- and
-\begin_inset listings
-inline true
-status open
+ method (
+\begin_inset Formula $\text{pu}_{P}$
+\end_inset
-\begin_layout Plain Layout
+) for profunctors is defined via the wrapped unit (
+\begin_inset Formula $\text{wu}_{P}$
+\end_inset
-wu
-\end_layout
+).
+ The presence of a value
+\begin_inset Formula $\text{wu}_{P}:P^{\bbnum 1}$
+\end_inset
+ means that the profunctor
+\begin_inset Formula $P$
\end_inset
- methods using
-\begin_inset listings
-inline true
+ is pointed
+\begin_inset Index idx
status open
\begin_layout Plain Layout
-
-xmap
+profunctor!pointed
\end_layout
\end_inset
-:
-\end_layout
-
-\begin_layout Subsubsection
-Definition
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Definition-applicative-profunctor"
-
+ (see Section
+\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Definition-applicative-profunctor"
+reference "subsec:Pointed-functors-motivation-equivalence"
plural "false"
caps "false"
noprefix "false"
\end_inset
+).
+ For functors and contrafunctors, the naturality law of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+pure
\end_layout
-\begin_layout Standard
-A profunctor
-\begin_inset Formula $P$
\end_inset
- is
-\series bold
-applicative
-\series default
- if there exist methods
+ is enough to enforce the equivalence of
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-zip
+pure
\end_layout
\end_inset
@@ -25301,139 +26570,206 @@ wu
\end_inset
- such that:
-\begin_inset Formula
-\begin{align*}
- & \text{zip}_{P}:P^{A}\times P^{B}\rightarrow P^{A\times B}\quad,\quad\quad\text{zip}_{P}(p\times\text{zip}_{P}(q\times r))\cong\text{zip}_{P}(\text{zip}_{P}(p\times q)\times r)\quad,\\
- & \text{wu}_{P}:P^{\bbnum 1}\quad,\quad\text{zip}_{P}(\text{wu}_{P}\times p)\cong p\quad,\quad\quad\text{zip}_{P}(p\times\text{wu}_{P})\cong p\quad.
-\end{align*}
-
+.
+ For profunctors, however, the value
+\begin_inset Formula $\text{wu}_{P}:P^{\bbnum 1}$
\end_inset
-Here we imply tuple-rearranging isomorphisms
-\begin_inset Formula $P^{(A\times B)\times C}\cong P^{A\times(B\times C)}$
-\end_inset
+ is
+\emph on
+not
+\emph default
+ equivalent to the type of fully parametric functions with the type signature
+ of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pure
+\end_layout
- and
-\begin_inset Formula $P^{\bbnum 1\times A}\cong P^{A}\cong P^{A\times\bbnum 1}$
\end_inset
-, which are implemented via the functions
-\begin_inset Formula $\varepsilon_{1,23}$
+.
+ The following example illustrates this (see also Exercise
+\begin_inset space ~
\end_inset
-,
-\begin_inset Formula $\varepsilon_{12,3}$
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Exercise-profunctor-pure-not-equivalent-1"
+plural "false"
+caps "false"
+noprefix "false"
+
\end_inset
-,
-\begin_inset Formula $\tilde{\varepsilon}_{1,23}$
+).
+\end_layout
+
+\begin_layout Subsubsection
+Example
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Example-profunctor-pure-not-equivalent"
+
\end_inset
-,
-\begin_inset Formula $\tilde{\varepsilon}_{12,3}$
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-profunctor-pure-not-equivalent"
+plural "false"
+caps "false"
+noprefix "false"
+
\end_inset
-,
-\begin_inset listings
-inline true
+
+\begin_inset Index idx
status open
\begin_layout Plain Layout
-
-ilu
+examples
\end_layout
\end_inset
-, and
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-iru
\end_layout
+\begin_layout Standard
+For the profunctor
+\begin_inset Formula $P^{A}\triangleq\left(A\rightarrow A\right)\rightarrow A$
\end_inset
-:
-\begin_inset Formula
-\begin{align*}
- & \text{zip}_{P}(p\times\text{zip}_{P}(q\times r))\triangleright\varepsilon_{1,23}^{\uparrow P}\tilde{\varepsilon}_{1,23}^{\downarrow P}=\text{zip}_{P}(\text{zip}_{P}(p\times q)\times r)\triangleright\varepsilon_{12,3}^{\uparrow P}\tilde{\varepsilon}_{12,3}^{\downarrow P}\quad,\\
- & \text{zip}_{P}(\text{wu}_{P}\times p)=p\triangleright\text{ilu}^{\uparrow P}\pi_{2}^{\downarrow P}\quad,\quad\quad\text{zip}_{P}(p\times\text{wu}_{P})=p\triangleright\text{iru}^{\uparrow P}\pi_{1}^{\downarrow P}\quad.
-\end{align*}
+, show that the type
+\begin_inset Formula $P^{\bbnum 1}$
+\end_inset
+ is
+\emph on
+not
+\emph default
+ equivalent to the type of fully parametric functions
+\begin_inset Formula $\text{pu}_{P}:A\rightarrow P^{A}$
\end_inset
+.
+\end_layout
+\begin_layout Subparagraph
+Solution
\end_layout
\begin_layout Standard
-Once the
+We can rewrite the type of
+\begin_inset Formula $\text{wu}_{P}$
+\end_inset
+
+ equivalently as
+\begin_inset Formula $P^{\bbnum 1}=\left(\bbnum 1\rightarrow\bbnum 1\right)\rightarrow\bbnum 1\cong\bbnum 1$
+\end_inset
+
+.
+ So, there is only one value of this type (a function that ignores its argument
+ and always returns the unit value
+\begin_inset Formula $1$
+\end_inset
+
+).
+ The corresponding
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-zip
+pure
\end_layout
\end_inset
- and
-\begin_inset listings
-inline true
-status open
+ method is a function that ignores its argument and always returns the given
+ value:
+\begin_inset Formula
+\[
+\text{pu}_{P}\triangleq a^{:A}\rightarrow\_^{:A\rightarrow A}\rightarrow a\quad.
+\]
-\begin_layout Plain Layout
+\end_inset
-wu
-\end_layout
+But there are many more functions with the same type signature as
+\begin_inset Formula $\text{pu}_{P}$
+\end_inset
+
+.
+ To see this, we swap the curried arguments of
+\begin_inset Formula $\text{pu}_{P}$
+\end_inset
+
+ and obtain an equivalent type:
+\begin_inset Formula
+\[
+A\rightarrow P^{A}=A\rightarrow\left(A\rightarrow A\right)\rightarrow A\cong\left(A\rightarrow A\right)\rightarrow A\rightarrow A\quad.
+\]
+
+\end_inset
+
+Examples of functions of this type are:
+\begin_inset Formula
+\[
+f_{1}\triangleq k^{:A\rightarrow A}\rightarrow k\quad,\quad\quad f_{2}\triangleq k^{:A\rightarrow A}\rightarrow(k\bef k)\quad,
+\]
\end_inset
- methods are known, we can define
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
+and so on.
+ For any non-negative integer
+\begin_inset Formula $n=0,1,2,...$
+\end_inset
-pure
-\end_layout
+, we can define the function
+\begin_inset Formula $f_{n}$
+\end_inset
+ that applies its argument
+\begin_inset Formula $n$
\end_inset
- and
-\begin_inset listings
-inline true
-status open
+ times (similar functions were defined in Example
+\begin_inset space ~
+\end_inset
-\begin_layout Plain Layout
-xmap2
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-hof-derive-types-2"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
-:
-\begin_inset Formula
-\begin{align*}
- & \text{pu}_{P}:A\rightarrow P^{A}\quad,\quad\quad\text{pu}_{P}(a^{:A})\triangleq\text{wu}_{P}\triangleright(\_^{:A}\rightarrow1)^{\downarrow P}(\_^{:\bbnum 1}\rightarrow a)^{\uparrow P}\quad,\\
- & \text{xmap}_{2}:(A\times B\rightarrow D)\times(D\rightarrow A\times B)\rightarrow P^{A}\times P^{B}\rightarrow P^{D}\quad,\\
- & \text{xmap}_{2}(f^{:A\times B\rightarrow D}\times g^{:D\rightarrow A\times B})\triangleq\text{zip}_{P}\bef(g^{\downarrow P}f^{\uparrow P})\quad.
-\end{align*}
-
+ and Exercise
+\begin_inset space ~
\end_inset
-\end_layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Exercise-hof-simple-4"
+plural "false"
+caps "false"
+noprefix "false"
-\begin_layout Standard
-It is important that the
+\end_inset
+
+).
+ The function
\begin_inset listings
inline true
status open
@@ -25445,336 +26781,374 @@ pure
\end_inset
- method (
-\begin_inset Formula $\text{pu}_{P}$
+ defined above is the same as
+\begin_inset Formula $f_{0}$
\end_inset
-) for profunctors is defined via the wrapped unit (
-\begin_inset Formula $\text{wu}_{P}$
+.
+ All functions
+\begin_inset Formula $f_{n}$
\end_inset
-).
- The presence of a value
-\begin_inset Formula $\text{wu}_{P}:P^{\bbnum 1}$
+ are fully parametric.
+ So, the type of fully parametric functions with type signature
+\begin_inset Formula $A\rightarrow P^{A}$
\end_inset
- means that the profunctor
-\begin_inset Formula $P$
+ contains many more values than the type
+\begin_inset Formula $P^{\bbnum 1}$
+\end_inset
+
+.
+
+\begin_inset Formula $\square$
\end_inset
- is pointed
-\begin_inset Index idx
-status open
-\begin_layout Plain Layout
-profunctor!pointed
\end_layout
+\begin_layout Standard
+The commutativity law of applicative profunctors is written like this:
+\begin_inset Formula
+\[
+\text{zip}_{P}(q\times p)\triangleright\text{swap}^{\downarrow P}\text{swap}^{\uparrow P}=\text{zip}_{P}(p\times q)\quad.
+\]
+
\end_inset
- (see Section
+
+\end_layout
+
+\begin_layout Standard
+The rest of this section proves some constructions that produce lawful applicati
+ve profunctors and are not equivalent to previously shown constructions
+ of applicative functors or contrafunctors.
+ The results are summarized in Table
\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Pointed-functors-motivation-equivalence"
+reference "tab:Constructions-of-applicative-profunctors"
plural "false"
caps "false"
noprefix "false"
\end_inset
-).
- For functors and contrafunctors, the naturality law of
-\begin_inset listings
-inline true
+.
+\end_layout
+
+\begin_layout Standard
+\begin_inset Float table
+wide false
+sideways false
status open
+\begin_layout Plain Layout
+\align center
+\begin_inset Tabular
+
+
+
+
+
+
+|
+\begin_inset Text
+
\begin_layout Plain Layout
-pure
+\series bold
+\size small
+Construction
\end_layout
\end_inset
-
- is enough to enforce the equivalence of
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-pure
+\series bold
+\size small
+Type notation
\end_layout
\end_inset
-
- and
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-wu
+\series bold
+\size small
+Assumptions
\end_layout
\end_inset
-
-.
- For profunctors, however, the value
-\begin_inset Formula $\text{wu}_{P}:P^{\bbnum 1}$
-\end_inset
-
- is
-\emph on
-not
-\emph default
- equivalent to the type of fully parametric functions with the type signature
- of
-\begin_inset listings
-inline true
-status open
+ |
+
+
+|
+\begin_inset Text
\begin_layout Plain Layout
-pure
+\size footnotesize
+composition
\end_layout
\end_inset
+ |
+
+\begin_inset Text
-.
- The following example illustrates this (see also Exercise
-\begin_inset space ~
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq G^{H^{A}}$
\end_inset
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Exercise-profunctor-pure-not-equivalent-1"
-plural "false"
-caps "false"
-noprefix "false"
+\end_layout
\end_inset
+ |
+
+\begin_inset Text
-).
-\end_layout
-
-\begin_layout Subsubsection
-Example
-\begin_inset CommandInset label
-LatexCommand label
-name "subsec:Example-profunctor-pure-not-equivalent"
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $G$
\end_inset
+ is an applicative functor,
+\begin_inset Formula $H$
+\end_inset
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Example-profunctor-pure-not-equivalent"
-plural "false"
-caps "false"
-noprefix "false"
+ is an applicative profunctor
+\end_layout
\end_inset
+ |
+
+
+|
+\begin_inset Text
+\begin_layout Plain Layout
-\begin_inset Index idx
-status open
+\size footnotesize
+product
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-examples
-\end_layout
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq P^{A}\times Q^{A}$
\end_inset
\end_layout
-\begin_layout Standard
-For the profunctor
-\begin_inset Formula $P^{A}\triangleq\left(A\rightarrow A\right)\rightarrow A$
\end_inset
+ |
+
+\begin_inset Text
-, show that the type
-\begin_inset Formula $P^{\bbnum 1}$
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $P$
\end_inset
- is
-\emph on
-not
-\emph default
- equivalent to the type of fully parametric functions
-\begin_inset Formula $\text{pu}_{P}:A\rightarrow P^{A}$
+ and
+\begin_inset Formula $Q$
\end_inset
-.
+ are applicative profunctors
\end_layout
-\begin_layout Subparagraph
-Solution
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+co-product
\end_layout
-\begin_layout Standard
-We can rewrite the type of
-\begin_inset Formula $\text{wu}_{P}$
\end_inset
+ |
+
+\begin_inset Text
- equivalently as
-\begin_inset Formula $P^{\bbnum 1}=\left(\bbnum 1\rightarrow\bbnum 1\right)\rightarrow\bbnum 1\cong\bbnum 1$
-\end_inset
+\begin_layout Plain Layout
-.
- So, there is only one value of this type (a function that ignores its argument
- and always returns the unit value
-\begin_inset Formula $1$
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq Z+Q^{A}$
\end_inset
-).
- The corresponding
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-pure
\end_layout
\end_inset
+ |
+
+\begin_inset Text
- method is a function that ignores its argument and always returns the given
- value:
-\begin_inset Formula
-\[
-\text{pu}_{P}\triangleq a^{:A}\rightarrow\_^{:A\rightarrow A}\rightarrow a\quad.
-\]
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $Z$
\end_inset
-But there are many more functions with the same type signature as
-\begin_inset Formula $\text{pu}_{P}$
-\end_inset
+ is a monoid type
+\end_layout
-.
- To see this, we swap the curried arguments of
-\begin_inset Formula $\text{pu}_{P}$
\end_inset
+ |
+
+
+|
+\begin_inset Text
- and obtain an equivalent type:
-\begin_inset Formula
-\[
-A\rightarrow P^{A}=A\rightarrow\left(A\rightarrow A\right)\rightarrow A\cong\left(A\rightarrow A\right)\rightarrow A\rightarrow A\quad.
-\]
+\begin_layout Plain Layout
+
+\size footnotesize
+co-product
+\end_layout
\end_inset
+ |
+
+\begin_inset Text
-Examples of functions of this type are:
-\begin_inset Formula
-\[
-f_{1}\triangleq k^{:A\rightarrow A}\rightarrow k\quad,\quad\quad f_{2}\triangleq k^{:A\rightarrow A}\rightarrow(k\bef k)\quad,
-\]
+\begin_layout Plain Layout
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq P^{A}+Q^{A}$
\end_inset
-and so on.
- For any non-negative integer
-\begin_inset Formula $n=0,1,2,...$
-\end_inset
-, we can define the function
-\begin_inset Formula $f_{n}$
-\end_inset
+\end_layout
- that applies its argument
-\begin_inset Formula $n$
\end_inset
+ |
+
+\begin_inset Text
- times (similar functions were defined in Example
+\begin_layout Plain Layout
+
+\size footnotesize
+conditions of Statement
\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Example-hof-derive-types-2"
+reference "subsec:Statement-applicative-profunctor-co-product-2"
plural "false"
caps "false"
noprefix "false"
\end_inset
- and Exercise
-\begin_inset space ~
+
+\end_layout
+
\end_inset
+ |
+
+
+|
+\begin_inset Text
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Exercise-hof-simple-4"
-plural "false"
-caps "false"
-noprefix "false"
+\size footnotesize
+function type
+\end_layout
\end_inset
-
-).
- The function
-\begin_inset listings
-inline true
-status open
+ |
+
+\begin_inset Text
\begin_layout Plain Layout
-pure
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq P^{A}\rightarrow Q^{A}$
+\end_inset
+
+
\end_layout
\end_inset
+ |
+
+\begin_inset Text
- defined above is the same as
-\begin_inset Formula $f_{0}$
-\end_inset
+\begin_layout Plain Layout
-.
- All functions
-\begin_inset Formula $f_{n}$
+\size footnotesize
+\begin_inset Formula $P$
\end_inset
- are fully parametric.
- So, the type of fully parametric functions with type signature
-\begin_inset Formula $A\rightarrow P^{A}$
+ is any functor,
+\begin_inset Formula $Q$
\end_inset
- contains many more values than the type
-\begin_inset Formula $P^{\bbnum 1}$
+ is an applicative profunctor
+\end_layout
+
\end_inset
+ |
+
+
-.
-
-\begin_inset Formula $\square$
\end_inset
\end_layout
-\begin_layout Standard
-The commutativity law of applicative profunctors is written like this:
-\begin_inset Formula
-\[
-\text{zip}_{P}(q\times p)\triangleright\text{swap}^{\downarrow P}\text{swap}^{\uparrow P}=\text{zip}_{P}(p\times q)\quad.
-\]
+\begin_layout Plain Layout
+\begin_inset Caption Standard
+
+\begin_layout Plain Layout
+Constructions of applicative profunctors.
+\begin_inset CommandInset label
+LatexCommand label
+name "tab:Constructions-of-applicative-profunctors"
\end_inset
\end_layout
-\begin_layout Standard
-The rest of this section proves some constructions that produce lawful applicati
-ve profunctors.
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
\end_layout
\begin_layout Subsubsection
@@ -27582,7 +28956,7 @@ covariant
\begin_inset Formula $P$
\end_inset
- will not be applicative even in simple cases such as
+ is not guaranteed to be applicative even in simple cases such as
\begin_inset Formula $P^{A}\triangleq H^{A}\rightarrow A$
\end_inset
@@ -27595,7 +28969,7 @@ Discussion and further developments
\end_layout
\begin_layout Subsection
-Equivalence of typeclass methods with laws
+Equivalence of lawful typeclass methods
\end_layout
\begin_layout Standard
@@ -27837,8 +29211,16 @@ noprefix "false"
\end_layout
\begin_layout Standard
-After seeing those detailed proofs, we can now clarify the meaning of equivalenc
-e of typeclass methods when we require some laws to hold.
+After seeing those detailed proofs, we can now clarify what it means for
+ two typeclass methods to be
+\begin_inset Quotes eld
+\end_inset
+
+equivalent
+\begin_inset Quotes erd
+\end_inset
+
+ when we require some laws to hold.
The goal of this subsection is to find a rigorous formulation of that equivalen
ce.
\end_layout
@@ -27904,7 +29286,15 @@ pure[A]: A => F[A]
\end_inset
.
- In Scala code, this law is written as
+ In Scala code, this law is written as the
+\begin_inset Quotes eld
+\end_inset
+
+code equation
+\begin_inset Quotes erd
+\end_inset
+
+
\begin_inset listings
inline true
status open
@@ -31873,14 +33263,14 @@ comonad
\begin_layout Plain Layout
Some typeclasses that follow the functorial pattern.
-\end_layout
+\begin_inset CommandInset label
+LatexCommand label
+name "tab:functorial-typeclasses"
\end_inset
-\begin_inset CommandInset label
-LatexCommand label
-name "tab:functorial-typeclasses"
+\end_layout
\end_inset
@@ -31922,16 +33312,16 @@ functorial
the typeclass via the following steps:
\end_layout
-\begin_layout Enumerate
-Define each category's composition operation and identity morphism.
+\begin_layout Standard
+1) Define each category's composition operation and identity morphism.
\end_layout
-\begin_layout Enumerate
-Verify that the category laws hold.
+\begin_layout Standard
+2) Verify that the category laws hold.
\end_layout
-\begin_layout Enumerate
-Write the type signature of the
+\begin_layout Standard
+3) Write the type signature of the
\begin_inset Quotes eld
\end_inset
@@ -31942,101 +33332,37 @@ lifting
method corresponding to the functor.
\end_layout
-\begin_layout Enumerate
-Impose the naturality laws and the functor laws on the
-\begin_inset Quotes eld
-\end_inset
-
-lifting
-\begin_inset Quotes erd
-\end_inset
-
- method.
-\end_layout
-
-\begin_layout Enumerate
-Derive other typeclass methods (and their laws) from the
-\begin_inset Quotes eld
-\end_inset
-
-lifting
-\begin_inset Quotes erd
-\end_inset
-
- method and its laws.
-\end_layout
-
\begin_layout Standard
-Let us go through this pattern for the applicative functor typeclass studied
- in this chapter.
- Following the functorial pattern, we say that a covariant type constructor
-
-\begin_inset Formula $F$
-\end_inset
-
- is applicative if there exists a (categorical) functor between the
-\begin_inset Formula $F$
-\end_inset
-
--ap and
-\begin_inset Formula $F$
-\end_inset
-
--lifted categories.
- The morphisms of the
-\begin_inset Formula $F$
-\end_inset
-
--ap category are values of type
-\begin_inset Formula $F^{A\rightarrow B}$
-\end_inset
-
-; the morphisms of the
-\begin_inset Formula $F$
-\end_inset
-
--lifted category are values of type
-\begin_inset Formula $F^{A}\rightarrow F^{B}$
-\end_inset
-
-.
- This is all we need to start with.
- All other properties of applicative functors are then derived in a systematic
- way.
- With this approach, we do not need to memorize the complicated type signatures
- and laws of the methods
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-
-map2
-\end_layout
-
+4) Impose the naturality laws and the functor laws on the
+\begin_inset Quotes eld
\end_inset
- and
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
+lifting
+\begin_inset Quotes erd
+\end_inset
-ap
+ method.
\end_layout
+\begin_layout Standard
+5) Derive other typeclass methods (and their laws) from the
+\begin_inset Quotes eld
\end_inset
-.
+lifting
+\begin_inset Quotes erd
+\end_inset
+
+ method and its laws.
\end_layout
\begin_layout Standard
-The first step is to define the
+Let us go through this pattern for the applicative functor typeclass.
+ The first step is to define the
\begin_inset Formula $F$
\end_inset
--ap category's morphisms.
+-ap category.
We define identity morphisms (
\begin_inset listings
inline true
@@ -32221,9 +33547,36 @@ noprefix "false"
\end_layout
\begin_layout Standard
-In this way, we derive the applicative typeclass by following the functorial
+In this way, we rediscover the applicative typeclass by following the functorial
typeclass pattern.
-
+ All other properties of applicative functors are derived in a systematic
+ way.
+ With this approach, we do not need to memorize the complicated type signatures
+ and laws of the methods
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map2
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+ap
+\end_layout
+
+\end_inset
+
+.
\end_layout
\begin_layout Standard
@@ -32398,7 +33751,19 @@ zip
\end_inset
- method for lists such that the shorter list is padded with the
+ method
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+padding
+\family typewriter
+zip
+\end_layout
+
+\end_inset
+
+ for lists such that the shorter list is padded with its
\emph on
last
\emph default
@@ -32547,6 +33912,225 @@ wu
.
\end_layout
+\begin_layout Subsubsection
+Exercise
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Exercise-applicative-I-concatenating-zip"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Exercise-applicative-I-concatenating-zip"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Implement a
+\begin_inset Quotes eld
+\end_inset
+
+concatenating
+\begin_inset Quotes erd
+\end_inset
+
+
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ method
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+concatenating
+\family typewriter
+zip
+\end_layout
+
+\end_inset
+
+ for lists.
+ The first value in the first list is repeated until the second list is
+ finished; then the last value in the second list is repeated until the
+ first list is finished.
+ Zipping with an empty list returns again an empty list.
+ A sample test:
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+def concatenatingZip[A, B](left: List[A], right: List[B]): List[(A, B)]
+ = ???
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+scala> concatenatingZip(List(1, 2, 3), List(
+\begin_inset Quotes eld
+\end_inset
+
+a
+\begin_inset Quotes erd
+\end_inset
+
+,
+\begin_inset Quotes eld
+\end_inset
+
+b
+\begin_inset Quotes erd
+\end_inset
+
+,
+\begin_inset Quotes eld
+\end_inset
+
+c
+\begin_inset Quotes erd
+\end_inset
+
+,
+\begin_inset Quotes eld
+\end_inset
+
+d
+\begin_inset Quotes erd
+\end_inset
+
+))
+\end_layout
+
+\begin_layout Plain Layout
+
+res0: List[(Int, String)] = List((1,
+\begin_inset Quotes eld
+\end_inset
+
+a
+\begin_inset Quotes erd
+\end_inset
+
+), (1,
+\begin_inset Quotes eld
+\end_inset
+
+b
+\begin_inset Quotes erd
+\end_inset
+
+), (1,
+\begin_inset Quotes eld
+\end_inset
+
+c
+\begin_inset Quotes erd
+\end_inset
+
+), (1,
+\begin_inset Quotes eld
+\end_inset
+
+d
+\begin_inset Quotes erd
+\end_inset
+
+), (2,
+\begin_inset Quotes eld
+\end_inset
+
+d
+\begin_inset Quotes erd
+\end_inset
+
+), (3,
+\begin_inset Quotes eld
+\end_inset
+
+d
+\begin_inset Quotes erd
+\end_inset
+
+))
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+scala> concatenatingZip(List(), List(1, 2, 3))
+\end_layout
+
+\begin_layout Plain Layout
+
+res1: List[(Unit, Int)] = List()
+\end_layout
+
+\end_inset
+
+Prove that the laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ hold for
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+concatenatingZip
+\end_layout
+
+\end_inset
+
+ with a suitable
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+wu
+\end_layout
+
+\end_inset
+
+.
+\end_layout
+
\begin_layout Subsubsection
Exercise
\begin_inset CommandInset label
@@ -33594,7 +35178,7 @@ pure
(b)
\series default
Show that the type of fully parametric functions
-\begin_inset Formula $\text{pu}_{P}:A\rightarrow P^{A}$
+\begin_inset Formula $\text{pu}_{P}:\forall A.\,A\rightarrow P^{A}$
\end_inset
is
diff --git a/sofp-src/lyx/sofp-disjunctions.lyx b/sofp-src/lyx/sofp-disjunctions.lyx
index 6bfb8170b..b8fa6497a 100644
--- a/sofp-src/lyx/sofp-disjunctions.lyx
+++ b/sofp-src/lyx/sofp-disjunctions.lyx
@@ -1321,7 +1321,7 @@ Int
\end_inset
-, the type parameter
+, the compiler has automatically set the type parameter
\begin_inset listings
inline true
status open
@@ -1345,7 +1345,7 @@ MySockX[A]
\end_inset
- was automatically set to the type
+ to the type
\begin_inset listings
inline true
status open
@@ -1372,7 +1372,6 @@ MySockX[Int]
\end_inset
.
- The programmer does not need to specify that type explicitly.
\end_layout
\begin_layout Standard
@@ -1519,7 +1518,47 @@ A
\end_inset
is.
- Scala will set the type parameter
+ (In this simple example,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+fits
+\end_layout
+
+\end_inset
+
+ does not actually use the value of type
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+A
+\end_layout
+
+\end_inset
+
+ stored inside
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+MySockX
+\end_layout
+
+\end_inset
+
+; but another function might.)
+\end_layout
+
+\begin_layout Standard
+The type parameter
\begin_inset listings
inline true
status open
@@ -1531,7 +1570,7 @@ A
\end_inset
- automatically when we apply
+ is set automatically when we apply
\begin_inset listings
inline true
status open
diff --git a/sofp-src/lyx/sofp-essay3.lyx b/sofp-src/lyx/sofp-essay3.lyx
index 12dc299ad..8bbb2c67a 100644
--- a/sofp-src/lyx/sofp-essay3.lyx
+++ b/sofp-src/lyx/sofp-essay3.lyx
@@ -672,7 +672,15 @@ target "https://www.amazon.com/dp/0262660717"
\family default
- or
+ or the manuscript
+\begin_inset Quotes eld
+\end_inset
+
+Basic category theory for computing science
+\begin_inset Quotes erd
+\end_inset
+
+:
\family typewriter
\begin_inset CommandInset href
@@ -719,7 +727,7 @@ monoidal
\begin_inset Quotes erd
\end_inset
-:
+: for example, see
\family typewriter
\begin_inset CommandInset href
@@ -2563,7 +2571,7 @@ Academically minded computer scientists say that this definition of a
\begin_inset Quotes eld
\end_inset
-types/functions
+types and functions
\begin_inset Quotes erd
\end_inset
@@ -2584,15 +2592,15 @@ literal "false"
\end_inset
- a
+ a category of
\begin_inset Quotes eld
\end_inset
-types/functions
+types and functions
\begin_inset Quotes erd
\end_inset
- category:
+:
\end_layout
\begin_layout Itemize
@@ -4511,7 +4519,7 @@ flatMap
\end_inset
.
- An example of usage is:
+ An example of usage:
\begin_inset listings
inline false
status open
diff --git a/sofp-src/lyx/sofp-filterable.lyx b/sofp-src/lyx/sofp-filterable.lyx
index 982741725..c9bde4ed1 100644
--- a/sofp-src/lyx/sofp-filterable.lyx
+++ b/sofp-src/lyx/sofp-filterable.lyx
@@ -23689,8 +23689,8 @@ Filterable
\end_inset
- typeclass is a
-\begin_inset Formula $P$
+ typeclass is an
+\begin_inset Formula $FM$
\end_inset
-typeclass (see Section
diff --git a/sofp-src/lyx/sofp-free-type.lyx b/sofp-src/lyx/sofp-free-type.lyx
index 6d793155a..07fc81190 100644
--- a/sofp-src/lyx/sofp-free-type.lyx
+++ b/sofp-src/lyx/sofp-free-type.lyx
@@ -1103,17 +1103,16 @@ Stage 2: implementing type safety in the DSLs
\end_layout
\begin_layout Standard
-The two DSLs defined in the previous section are not fully type-checked
+The two DSLs defined in the previous section are not type-safe.
\begin_inset Index idx
status open
\begin_layout Plain Layout
-type checking
+type safety
\end_layout
\end_inset
- at compile time.
This becomes clear by looking at the DSL program
\begin_inset listings
inline true
@@ -1246,7 +1245,7 @@ file
\end_inset
failed to compile.
- To achieve that, it would help to have different Scala types for DSL programs
+ To achieve that, we need to have different Scala types for DSL programs
returning a
\begin_inset listings
inline true
@@ -1259,7 +1258,7 @@ String
\end_inset
- and a
+ or a
\begin_inset listings
inline true
status open
@@ -1272,7 +1271,7 @@ Path
\end_inset
.
- So, let us replace the type
+ So, we replace the type
\begin_inset listings
inline true
status open
@@ -1296,7 +1295,7 @@ PrgFile[A]
\end_inset
-, representing a DSL program that will return a value of type
+, which means a DSL program that will return a value of type
\begin_inset listings
inline true
status open
@@ -1525,7 +1524,19 @@ PrgComplex
, and so the Scala compiler is unable to verify that the DSL is being used
correctly.
- If the programmer uses a plain complex number (
+ If the programmer uses
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Rotate
+\end_layout
+
+\end_inset
+
+ with a
\begin_inset listings
inline true
status open
@@ -1537,7 +1548,7 @@ Val
\end_inset
-) instead of a
+ instead of a
\begin_inset listings
inline true
status open
@@ -1549,7 +1560,7 @@ Phase
\end_inset
- value, the program will return an incorrect result
+, the program will return an incorrect result
\emph on
without
\emph default
@@ -1560,8 +1571,7 @@ status open
\begin_layout Plain Layout
-val prgComplex3: PrgComplex = Rotate(prgComplex1, Val(Complex(0, 1)))
- // Forgot Phase()!
+val prgComplex3: PrgComplex = Rotate(prgComplex1, Val(Complex(0, 1)))
\end_layout
\begin_layout Plain Layout
@@ -1648,8 +1658,7 @@ sealed trait PrgComplex[A]
\begin_layout Plain Layout
-final case class Val(c: Complex) extends
- PrgComplex[Complex]
+final case class Val(c: Complex) extends PrgComplex[Complex]
\end_layout
\begin_layout Plain Layout
@@ -1666,14 +1675,12 @@ final case class Mul(p1: PrgComplex[Complex], p2: PrgComplex[Complex]) extends
\begin_layout Plain Layout
-final case class Conj(p: PrgComplex[Complex]) extends
- PrgComplex[Complex]
+final case class Conj(p: PrgComplex[Complex]) extends PrgComplex[Complex]
\end_layout
\begin_layout Plain Layout
-final case class Phase(p: PrgComplex[Complex]) extends
- PrgComplex[Double]
+final case class Phase(p: PrgComplex[Complex]) extends PrgComplex[Double]
\end_layout
\begin_layout Plain Layout
@@ -1755,7 +1762,7 @@ def runComplex[A]: PrgComplex[A] => A = {
\end_inset
-The example programs,
+The example programs (
\begin_inset listings
inline true
status open
@@ -1779,7 +1786,7 @@ prgComplex2
\end_inset
-, do not change except for their type:
+) remain unchanged except for their types:
\begin_inset listings
inline false
status open
@@ -1849,7 +1856,7 @@ status open
\begin_layout Plain Layout
-PrgComplex[Double]
+Phase
\end_layout
\end_inset
@@ -1866,7 +1873,7 @@ Phase
\end_inset
- will cause a type error:
+ will be a type error:
\begin_inset listings
inline false
status open
@@ -1888,8 +1895,8 @@ scala> val prgComplex3 = Rotate(prgComplex1, Val(Complex(0, 1)))
\begin_layout Plain Layout
- required: PrgComplex[Double]
-
+ required: Phase
+
\end_layout
\begin_layout Plain Layout
@@ -1984,7 +1991,7 @@ PrgFile
\end_inset
- DSL, we find that we need to set the Scala variable
+ DSL, we find that we need to set the variable
\begin_inset listings
inline true
status open
@@ -1997,7 +2004,7 @@ p
\end_inset
to the path computed by a previous operation.
- Here is a first attempt:
+ A first attempt is:
\begin_inset listings
inline false
status open
@@ -2031,7 +2038,7 @@ No file.
\end_inset
There are two problems with this code.
- The first problem is that
+ First,
\begin_inset listings
inline true
status open
@@ -2043,7 +2050,7 @@ Read(p)
\end_inset
- does not compile because the argument of
+ does not compile: the argument of
\begin_inset listings
inline true
status open
@@ -2080,7 +2087,7 @@ JPath
\end_inset
.
- To solve this problem, we generalize the
+ To fix this, we add a type parameter to the
\begin_inset listings
inline true
status open
@@ -2092,7 +2099,7 @@ Val
\end_inset
- class to hold values of arbitrary type:
+ case class, now supporting values of any type:
\begin_inset listings
inline false
status open
@@ -2177,8 +2184,8 @@ bound variable
\end_inset
-bound variables is by using those variables as arguments of nameless functions.
- So, let us consider the nameless function:
+bound variables is by using arguments of nameless functions.
+ So, let us consider the following nameless function:
\begin_inset listings
inline false
status open
@@ -2490,7 +2497,7 @@ Bind
\end_inset
--handling code to the runner, the implementation of the DSL is:
+-handling code to the runner, we get:
\begin_inset listings
inline false
status open
@@ -2668,7 +2675,7 @@ status open
\begin_layout Plain Layout
-p:JPath
+p: JPath
\end_layout
\end_inset
@@ -2848,7 +2855,7 @@ B => PrgFile[A]
\end_inset
), that function may run arbitrary Scala code, not limited to DSL operations,
- in order to compute a result of type
+ as it computes its result value of type
\begin_inset listings
inline true
status open
@@ -2910,7 +2917,7 @@ PrgFile[A]
\end_inset
- describes a computation but does not execute it.
+ describes a computation but does not run it.
\end_layout
\begin_layout Subsection
@@ -3006,8 +3013,7 @@ sealed trait PrgFile[A] {
\begin_layout Plain Layout
-final case class Val[A](a: A) extends
- PrgFile[A]
+final case class Val[A](a: A) extends PrgFile[A]
\end_layout
\begin_layout Plain Layout
@@ -3018,14 +3024,12 @@ final case class Bind[A, B](pa: PrgFile[B])(val f: B => PrgFile[A]) extends
\begin_layout Plain Layout
-final case class Path(p: PrgFile[String]) extends
- PrgFile[JPath]
+final case class Path(p: PrgFile[String]) extends PrgFile[JPath]
\end_layout
\begin_layout Plain Layout
-final case class Read(p: PrgFile[JPath]) extends
- PrgFile[String]
+final case class Read(p: PrgFile[JPath]) extends PrgFile[String]
\end_layout
\begin_layout Plain Layout
@@ -3526,9 +3530,8 @@ B => PrgFile[A]
\end_layout
\begin_layout Standard
-Typically, a monadic DSL program is a nested case class containing some
- function that, when called, will return further nested case classes and
- functions, etc.
+Typically, a monadic DSL program is a case class containing some functions
+ that, when called, will return further nested case classes or functions.
All those functions are waiting to be called; no side effects have been
run yet.
The actual business logic and side effects will be executed only when the
@@ -3545,7 +3548,7 @@ run
\end_inset
method is applied.
- At that time, the entire DSL program will be converted into a result value.
+ After that, we will get the result value of the entire DSL program.
\end_layout
\begin_layout Subsection
@@ -3607,8 +3610,7 @@ object PrgComplex {
\begin_layout Plain Layout
-final case class Val[A](a: A)
- extends PrgComplex[A]
+final case class Val[A](a: A) extends PrgComplex[A]
\end_layout
\begin_layout Plain Layout
@@ -3619,32 +3621,27 @@ final case class Bind[A, B](pa: PrgComplex[B])(val f: B => PrgComplex[A])
\begin_layout Plain Layout
-final case class Add(x: Complex, y: Complex)
- extends PrgComplex[Complex]
+final case class Add(x: Complex, y: Complex) extends PrgComplex[Complex]
\end_layout
\begin_layout Plain Layout
-final case class Mul(x: Complex, y: Complex)
- extends PrgComplex[Complex]
+final case class Mul(x: Complex, y: Complex) extends PrgComplex[Complex]
\end_layout
\begin_layout Plain Layout
-final case class Conj(x: Complex)
- extends PrgComplex[Complex]
+final case class Conj(x: Complex) extends PrgComplex[Complex]
\end_layout
\begin_layout Plain Layout
-final case class Phase(p: Complex)
- extends PrgComplex[Double]
+final case class Phase(p: Complex) extends PrgComplex[Double]
\end_layout
\begin_layout Plain Layout
-final case class Rotate(p: Complex, p: Phase)
- extends PrgComplex[Complex]
+final case class Rotate(p: Complex, p: Phase) extends PrgComplex[Complex]
\end_layout
\begin_layout Plain Layout
@@ -3952,8 +3949,7 @@ final case class Bind[A, B](pa: PrgFile[B])(val f: B => PrgFile[A]) extends
\begin_layout Plain Layout
-final case class Op[A](op: PrgFileC[A]) extends PrgFile[A] // Wrap custom
- operations.
+final case class Op[A](op: PrgFileC[A]) extends PrgFile[A] // Custom operation.
\end_layout
\begin_layout Plain Layout
@@ -3977,8 +3973,7 @@ def runFile[A]: PrgFile[A] => A = {
\begin_layout Plain Layout
- case Op(op) => runFileC(op) // Run the custom operation and get
- the result.
+ case Op(op) => runFileC(op) // Run a custom operation.
\end_layout
\begin_layout Plain Layout
@@ -4032,8 +4027,8 @@ final case class Bind[A, B](pa: PrgComplex[B])(val f: B => PrgComplex[A])
\begin_layout Plain Layout
-final case class Op[A](op: PrgComplexC[A]) extends PrgComplex[A] //
- Wrap custom operations.
+final case class Op[A](op: PrgComplexC[A]) extends PrgComplex[A] // Custom
+ operation.
\end_layout
\begin_layout Plain Layout
@@ -4057,8 +4052,7 @@ def runComplex[A]: PrgComplex[A] => A = {
\begin_layout Plain Layout
- case Op(op) => runComplexC(op) // Run the custom operation
- and get the result.
+ case Op(op) => runComplexC(op) // Run a custom operation.
\end_layout
\begin_layout Plain Layout
@@ -4073,22 +4067,22 @@ sealed trait PrgComplexC[A]
\begin_layout Plain Layout
-final case class Add(x: Complex, y: Complex) extends PrgComplexC[Complex]
+final case class Add(x: Complex, y: Complex) extends PrgComplexC[Complex]
\end_layout
\begin_layout Plain Layout
-final case class Mul(x: Complex, y: Complex) extends PrgComplexC[Complex]
+final case class Mul(x: Complex, y: Complex) extends PrgComplexC[Complex]
\end_layout
\begin_layout Plain Layout
-final case class Conj(x: Complex) extends PrgComplexC[Complex]
+final case class Conj(x: Complex) extends PrgComplexC[Complex]
\end_layout
\begin_layout Plain Layout
-final case class Phase(p: Complex) extends PrgComplexC[Double]
+final case class Phase(p: Complex) extends PrgComplexC[Double]
\end_layout
\begin_layout Plain Layout
@@ -4242,7 +4236,7 @@ PrgFile
\end_inset
is only concerned with providing the monadic functionality to the DSL.
- We can replace those two classes by a single class (called, say,
+ We can replace those two classes by a single class (called
\begin_inset listings
inline true
status open
@@ -5086,7 +5080,7 @@ name "subsec:A-first-recipe-monadic-dsl"
\end_layout
\begin_layout Standard
-The previous section gave motivation for defining the type constructor
+The previous section motivated defining the type constructor
\begin_inset listings
inline true
status open
@@ -5099,7 +5093,7 @@ MonadDSL[F[_], A]
\end_inset
.
- That type constructor is called the
+ That type constructor is known as the
\begin_inset Quotes eld
\end_inset
@@ -5656,7 +5650,7 @@ String
\end_inset
).
- However, in some cases the effect constructor
+ However, in other cases the effect constructor
\begin_inset listings
inline true
status open
@@ -5668,7 +5662,7 @@ F
\end_inset
- could be itself a lawful functor.
+ could be a lawful functor.
\end_layout
\begin_layout Standard
@@ -6614,7 +6608,7 @@ The resulting code creates fewer nested case classes in memory.
\end_layout
\begin_layout Standard
-Unlike other laws, the right identity law already holds for any value
+The right identity law already holds for any value
\begin_inset listings
inline true
status open
@@ -7539,6 +7533,13 @@ The use of universal runners (with an arbitrary monad
\begin_layout Section
Different encodings of the free monad
+\begin_inset CommandInset label
+LatexCommand label
+name "sec:Different-encodings-of-free-monad"
+
+\end_inset
+
+
\end_layout
\begin_layout Subsection
@@ -7592,15 +7593,7 @@ F
\end_inset
.
- The word
-\begin_inset Quotes eld
-\end_inset
-
-free
-\begin_inset Quotes erd
-\end_inset
-
- indicates that
+ For intuition, one may say that
\begin_inset listings
inline true
status open
@@ -7612,8 +7605,16 @@ MonadDSL
\end_inset
- is free of any domain-specific code.
- We may view
+ is
+\begin_inset Quotes eld
+\end_inset
+
+free of
+\begin_inset Quotes erd
+\end_inset
+
+ any domain-specific code.
+ The wrapper type
\begin_inset listings
inline true
status open
@@ -7625,8 +7626,7 @@ MonadDSL[F, A]
\end_inset
- as a wrapper that adds the monad's functionality to any type constructor
-
+ adds the functionality of a monad to any type constructor
\begin_inset listings
inline true
status open
@@ -7663,7 +7663,11 @@ F
\end_inset
- as a type parameter, and so it works equally well with every
+ as a
+\emph on
+type parameter
+\emph default
+, and so it works equally well with every
\begin_inset listings
inline true
status open
@@ -8007,8 +8011,8 @@ abstract class Free1[F[_]: Functor, T] {
\begin_layout Plain Layout
- case Flatten(p) => Flatten(p.map(g => g.flatMap(f))) // Use F's Functor
- instance.
+ case Flatten(p) => Flatten(p.map(g => g.flatMap(f))) // Use the Functor
+ instance for F.
\end_layout
\begin_layout Plain Layout
@@ -8173,7 +8177,7 @@ literal "false"
\end_inset
- where the code for the free monad looked like this:
+ showing the following code for the free monad:
\begin_inset listings
inline false
status open
@@ -8414,8 +8418,7 @@ free monad!encodings
\end_inset
of the free monad.
- The different codes implement the same idea (turning a type constructor
-
+ The different codes implement the same idea: turn a type constructor
\begin_inset listings
inline true
status open
@@ -8427,7 +8430,7 @@ F
\end_inset
- into a monad) in different ways.
+ formally into a monad by adding some case classes.
\end_layout
\begin_layout Standard
@@ -8436,7 +8439,7 @@ To figure out how to use those codes in practice, a programmer might ask:
\end_layout
\begin_layout Itemize
-Are these encodings equivalent (given that
+Are these encodings equivalent (even though
\begin_inset listings
inline true
status open
@@ -8448,7 +8451,7 @@ Free2
\end_inset
- has 2 case classes and
+ has 2 case classes while
\begin_inset listings
inline true
status open
@@ -8460,7 +8463,7 @@ Free3
\end_inset
- has 3)?
+ has 3)? What are the differences?
\end_layout
\begin_layout Itemize
@@ -8539,7 +8542,7 @@ name "subsec:The-raw-tree-encoding-of-the-free-monad"
\end_layout
\begin_layout Standard
-To understand the relationships between the encodings of the free monad,
+To understand the relationship between the encodings of the free monad,
let us first examine how the code of
\begin_inset listings
inline true
@@ -8626,7 +8629,11 @@ map
\end_inset
- method is not similar to the code of the two other monadic methods (
+ method is
+\emph on
+
+\emph default
+not exactly similar to the code of the two other monadic methods (
\begin_inset listings
inline true
status open
@@ -8650,7 +8657,7 @@ flatMap
\end_inset
-) that merely create new values of the case classes
+) that merely wrap their arguments in new case classes (
\begin_inset listings
inline true
status open
@@ -8674,7 +8681,7 @@ Bind
\end_inset
- without performing any computations.
+) without performing any computations.
\end_layout
\begin_layout Standard
@@ -8715,7 +8722,7 @@ MonadDSL
\end_inset
.
- The result is a new encoding that we will call
+ The result is a new encoding called
\begin_inset listings
inline true
status open
@@ -8727,7 +8734,7 @@ Free4
\end_inset
- (since it uses
+ (as it uses
\begin_inset Formula $4$
\end_inset
@@ -8773,26 +8780,24 @@ object Free4 {
\begin_layout Plain Layout
-final case class Val[F[_], A](a: A)
- extends Free4[F, A]
+final case class Val[F[_], A](a: A) extends Free4[F, A]
\end_layout
\begin_layout Plain Layout
final case class Bind4[F[_], A, B](pa: Free4[F, B], f: B => Free4[F, A])
- extends Free4[F, A]
+ extends Free4[F, A]
\end_layout
\begin_layout Plain Layout
-final case class FMap[F[_], A, B](pa: Free4[F, B], f: B => A)
- extends Free4[F, A]
+final case class FMap[F[_], A, B](pa: Free4[F, B], f: B => A) extends Free4[F,
+ A]
\end_layout
\begin_layout Plain Layout
-final case class Op[F[_], A](op: F[A]) extends Free4[F, A] // Wrap domain-specif
-ic operations.
+final case class Op[F[_], A](op: F[A]) extends Free4[F, A]
\end_layout
\end_inset
@@ -8918,7 +8923,7 @@ pure
\end_inset
- merely wraps the arguments of each method into a case class without performing
+ simply wraps the arguments of each method into a case class without performing
any computations with those arguments.
We call
\begin_inset listings
@@ -8955,8 +8960,8 @@ raw tree
\begin_inset Quotes erd
\end_inset
- means that a DSL program is a completely unevaluated expression tree that
- uses a new nested case class for each step of a computation.
+ means that a DSL program is a completely unevaluated expression tree where
+ each DSL operation is represented by a new nested case class.
\end_layout
\begin_layout Subsection
@@ -10414,8 +10419,8 @@ FlatMap
\end_inset
-, we find that the type of their data are not the same: the first part of
-
+, we find that the types of their data are not the same: the first part
+ of
\begin_inset listings
inline true
status open
@@ -10501,7 +10506,7 @@ Free3[F, A]
\end_inset
.
- So, we write the code of
+ So, the code of
\begin_inset listings
inline true
status open
@@ -10513,7 +10518,7 @@ free2toFree3
\end_inset
- like this:
+ becomes:
\begin_inset listings
inline false
status open
@@ -10556,7 +10561,7 @@ free3toFree2
\end_inset
-) is more complicated because
+) is more complicated because the case classes
\begin_inset listings
inline true
status open
@@ -10580,7 +10585,7 @@ FlatMap
\end_inset
- are not straightforwardly mapped into
+ are not directly mapped into
\begin_inset listings
inline true
status open
@@ -11138,6 +11143,13 @@ We will find later in this chapter that a similar situation occurs in many
\begin_layout Subsection
Types with existential quantifiers
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Types-with-existential-quantifiers"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -13067,9 +13079,9 @@ We will use the existential quantifier notation for reasoning about properties
are written as:
\begin_inset Formula
\begin{align*}
-\text{free monad on }F\text{ in a reduced encoding}:\quad & \text{Free}_{2}^{F,T}\triangleq T+\exists A.\,F^{A}\times(A\rightarrow\text{Free}_{2}^{F,T})\quad,\\
-\text{free monad on }F\text{ in a reduced encoding}:\quad & \text{Free}_{3}^{F,T}\triangleq T+F^{T}+\exists A.\,\text{Free}_{3}^{F,A}\times(A\rightarrow\text{Free}_{3}^{F,T})\quad,\\
-\text{free monad on }F\text{ in a raw tree encoding}:\quad & \text{Free}_{4}^{F,A}\triangleq A+F^{A}+\exists B.\,\text{Free}_{4}^{F,B}\times(B\rightarrow A)\\
+\text{reduced encoding, 2 case classes}:\quad & \text{Free}_{2}^{F,T}\triangleq T+\exists A.\,F^{A}\times(A\rightarrow\text{Free}_{2}^{F,T})\quad,\\
+\text{reduced encoding, 3 case classes}:\quad & \text{Free}_{3}^{F,T}\triangleq T+F^{T}+\exists A.\,\text{Free}_{3}^{F,A}\times(A\rightarrow\text{Free}_{3}^{F,T})\quad,\\
+\text{raw tree encoding}:\quad & \text{Free}_{4}^{F,A}\triangleq A+F^{A}+\exists B.\,\text{Free}_{4}^{F,B}\times(B\rightarrow A)\\
& \quad\quad+\exists B.\,\text{Free}_{4}^{F,B}\times(B\rightarrow\text{Free}_{4}^{F,A})\quad.
\end{align*}
@@ -13166,9 +13178,10 @@ toInt
is written in the type notation as:
\begin_inset Formula
-\[
-\text{toInt}:\left(\exists C.\,\text{Int}\times C\times(C\rightarrow\text{Int})\right)\rightarrow\text{Int}\quad,\quad\quad\text{toInt}\triangleq(\exists C.\,a^{:\text{Int}}\times c^{:C}\times p^{:C\rightarrow\text{Int}})\rightarrow a+p(c)\quad.
-\]
+\begin{align*}
+ & \text{toInt}:\left(\exists C.\,\text{Int}\times C\times(C\rightarrow\text{Int})\right)\rightarrow\text{Int}\quad,\\
+ & \text{toInt}\triangleq(\exists C.\,a^{:\text{Int}}\times c^{:C}\times p^{:C\rightarrow\text{Int}})\rightarrow a+p(c)\quad.
+\end{align*}
\end_inset
@@ -14194,7 +14207,7 @@ covariant co-Yoneda identity
\begin_inset Quotes erd
\end_inset
- (Statement
+ (which we will prove as Statement
\begin_inset space ~
\end_inset
@@ -14275,7 +14288,7 @@ Free1
\begin_inset Formula $F$
\end_inset
- is a functor) is equivalent to
+ is a functor) is equivalent at the level of types to
\begin_inset listings
inline true
status open
@@ -14287,8 +14300,8 @@ Free2
\end_inset
- as type constructors.
- (Recall that the equivalence of
+.
+ Recall that the equivalence of
\begin_inset listings
inline true
status open
@@ -14365,7 +14378,7 @@ Free4
\emph on
not
\emph default
- equivalent as type constructors.)
+ equivalent as type constructors.
\end_layout
\begin_layout Section
@@ -15488,7 +15501,7 @@ noprefix "false"
, we get the type equivalence:
\begin_inset Formula
\begin{align*}
- & \forall F^{\bullet}.\,\forall A.\,(\forall T.\,F^{T}\rightarrow M^{T})\rightarrow\text{Free}_{4}^{F,A}\rightarrow M^{A}\\
+ & \forall F.\,\forall A.\,(\forall T.\,F^{T}\rightarrow M^{T})\rightarrow\text{Free}_{4}^{F,A}\rightarrow M^{A}\\
& \quad\quad\cong\forall A.\,\text{Free}_{4}^{M,A}\rightarrow M^{A}\quad.
\end{align*}
@@ -15815,7 +15828,7 @@ not
\begin_inset Formula $\text{Free}_{4}^{F,A}$
\end_inset
- fails to obey the monad laws.)
+ violates the monad laws.)
\end_layout
\begin_layout Standard
@@ -16130,8 +16143,8 @@ Free4
\end_layout
\begin_layout Standard
-It turns out that the monad morphism laws of the runner and the free evaluator
- have far-reaching consequences for the theory of typeclasses with laws.
+It turns out that the laws of the runner and the free evaluator have far-reachin
+g consequences for the theory of typeclasses with laws.
For now, let us list the properties that are relevant for practical programming
with free monads:
\end_layout
@@ -16979,8 +16992,7 @@ We can now generalize the properties 1–4 to an arbitrary typeclass.
\begin_inset Formula $T$
\end_inset
- be a type that does not belong to the typeclass, and denote the free typeclass
- instance constructed on
+ be any type and denote a free typeclass instance constructed on
\begin_inset Formula $T$
\end_inset
@@ -16988,9 +17000,8 @@ We can now generalize the properties 1–4 to an arbitrary typeclass.
\begin_inset Formula $\text{Free}^{T}$
\end_inset
-.
- We will formulate the expected properties in terms of the free evaluator
- (
+ (in any encoding).
+ We formulate the expected properties in terms of the free evaluator (
\begin_inset listings
inline true
status open
@@ -17005,6 +17016,53 @@ eval
) as its type signature is simpler than that of the universal runner:
\end_layout
+\begin_layout Enumerate
+The type
+\begin_inset Formula $\text{Free}^{T}$
+\end_inset
+
+ is covariant with respect to
+\begin_inset Formula $T$
+\end_inset
+
+.
+ For any
+\begin_inset Formula $T$
+\end_inset
+
+, the type
+\begin_inset Formula $\text{Free}^{T}$
+\end_inset
+
+ supports the typeclass operations (but may violate some typeclass laws).
+ There exists a natural transformation
+\begin_inset Formula $T\rightarrow\text{Free}^{T}$
+\end_inset
+
+.
+ For any
+\begin_inset Formula $T$
+\end_inset
+
+,
+\begin_inset Formula $U$
+\end_inset
+
+ and any
+\begin_inset Formula $f:T\rightarrow U$
+\end_inset
+
+, the function
+\begin_inset Formula $f^{\uparrow\text{Free}}$
+\end_inset
+
+ of type
+\begin_inset Formula $\text{Free}^{T}\rightarrow\text{Free}^{U}$
+\end_inset
+
+ preserves the typeclass operations.
+\end_layout
+
\begin_layout Enumerate
For a given type
\begin_inset Formula $M$
@@ -17054,31 +17112,36 @@ only
\end_layout
\begin_layout Enumerate
-The constructor
-\begin_inset Formula $\text{Free}^{T}$
-\end_inset
+The universal runner is defined through
+\begin_inset listings
+inline true
+status open
- is covariant with respect to
-\begin_inset Formula $T$
-\end_inset
+\begin_layout Plain Layout
+
+eval
+\end_layout
-: For any two types constructors
-\begin_inset Formula $T$
\end_inset
- and
-\begin_inset Formula $U$
+ as:
+\begin_inset Formula
+\begin{align*}
+ & \text{run}:(T\rightarrow M)\rightarrow\text{Free}^{T}\rightarrow M\quad,\\
+ & \text{run}\,(f^{:T\rightarrow M})\triangleq f^{\uparrow\text{Free}}\bef\text{eval}\quad.
+\end{align*}
+
\end_inset
- and a map
-\begin_inset Formula $f:T\rightarrow U$
+For any
+\begin_inset Formula $f$
\end_inset
- between them, there is a unique function of type
-\begin_inset Formula $\text{Free}^{T}\rightarrow\text{Free}^{U}$
+, the function
+\begin_inset Formula $\text{run}\left(f\right)$
\end_inset
- that preserves the typeclass operations.
+ preserves the typeclass operations.
\end_layout
\begin_layout Enumerate
@@ -17115,15 +17178,19 @@ noprefix "false"
\end_inset
- will show general proofs that apply to all
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses and to all possible laws.
+ will show general proofs that apply to all FM-typeclasses and to all possible
+ choices of typeclass laws.
\end_layout
\begin_layout Subsection
Free pointed type
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Free-pointed-type"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -17322,7 +17389,7 @@ Option[T]
\end_inset
-, so we will define it that way:
+, so we may write a simpler definition like this:
\begin_inset listings
inline false
status open
@@ -17382,6 +17449,11 @@ free pointed type
\end_inset
.
+
+\begin_inset Formula $\square$
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -19263,7 +19335,11 @@ fromNEL
\end_inset
- does not!).
+ does
+\emph on
+not
+\emph default
+).
It is a general property of free typeclass constructions that there is
only one typeclass-preserving function of type
\begin_inset listings
@@ -19310,8 +19386,22 @@ noprefix "false"
operations.
\end_layout
+\begin_layout Standard
+*** There are also alternative implementations of the universal runner that
+ correspond to those functions.
+ When the universal runner is applied with a lawful semigroup, the results
+ are the same.
+ But when we use SFR instead of a lawful semigroup, the results are
+\emph on
+not
+\emph default
+ the same.
+ We see that it is important to take into account which laws hold when using
+ the universal runner.***
+\end_layout
+
\begin_layout Subsection
-Free monoid and its partially lawful encodings
+Free monoid and its reduced encodings
\begin_inset CommandInset label
LatexCommand label
name "subsec:Free-monoids"
@@ -19509,7 +19599,7 @@ FMR
lines 0
placement l
overhang 0in
-width "60col%"
+width "70col%"
status open
\begin_layout Plain Layout
@@ -19625,7 +19715,7 @@ status open
\end_inset
- as in the previous section.
+ as before.
\end_layout
\begin_layout Standard
@@ -20345,11 +20435,6 @@ type F3[T] = Option[Tree2[T]]
\begin_layout Plain Layout
-def wrapF3[T](t: T): F3[T] = Some(Leaf(t))
-\end_layout
-
-\begin_layout Plain Layout
-
def concatF3[T]: (F3[T], F3[T]) => F3[T] = {
\end_layout
@@ -20407,7 +20492,7 @@ ght)
\begin_layout Plain Layout
-def runnerF3[M: Monoid, T](runT: T => M)(fmr: F3[T]): M = fmr match {
+def runnerF3[M: Monoid, T](runT: T => M): F3[T] => M = {
\end_layout
\begin_layout Plain Layout
@@ -21135,427 +21220,1675 @@ noprefix "false"
only a subset of the laws of a given typeclass.
\end_layout
-\begin_layout Subsection
-Free functors
+\begin_layout Standard
+Are there any other encodings of the free monoid? Heuristically, we expect
+ to find a reduced encoding satisfying any given subset of the monoid laws.
+ The four encodings shown above correspond to four specific subsets of the
+ laws; as there are three laws, one has 8 different encodings corresponding
+ to all different subsets of the 3 laws that could be chosen.
+ The following examples show how to implement the remaining encodings.
\end_layout
-\begin_layout Standard
-Consider the
-\begin_inset listings
-inline true
-status open
+\begin_layout Subsubsection
+Example
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Example-reduced-monoid-encoding-one-law"
-\begin_layout Plain Layout
+\end_inset
-Functor
-\end_layout
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-reduced-monoid-encoding-one-law"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
- typeclass whose only method is
-\begin_inset listings
-inline true
+
+\begin_inset Index idx
status open
\begin_layout Plain Layout
-
-fmap
+examples
\end_layout
\end_inset
-:
-\begin_inset Formula
-\[
-\text{fmap}:\left(A\rightarrow B\right)\rightarrow F^{A}\rightarrow F^{B}\quad.
-\]
-\end_inset
+\end_layout
-The
+\begin_layout Standard
+Find a reduced encoding of the free monoid that satisfies the left identity
+ law and the associativity law, but
+\emph on
+not
+\emph default
+ the right identity law.
+\end_layout
+
+\begin_layout Subparagraph
+Solution
+\end_layout
+
+\begin_layout Standard
+We start with the encoding
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-fmap
+F2
\end_layout
\end_inset
- method is not available for some type constructors
-\begin_inset Formula $F$
+, which satisfies the associativity law.
+ This encoding represents expressions built up from values of type
+\begin_inset Formula $T$
\end_inset
-, such as contrafunctors or GADTs.
- (See Section
-\begin_inset space ~
+ and the special empty value
+\begin_inset Formula $e$
\end_inset
+ via the operation
+\begin_inset Formula $\oplus$
+\end_inset
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Examples-of-non-functors"
-plural "false"
-caps "false"
-noprefix "false"
+.
+ An example expression is:
+\begin_inset Formula
+\[
+t_{1}\oplus t_{2}\oplus e\oplus t_{3}\oplus e\oplus e\quad.
+\]
\end_inset
- for more examples.) Let us now apply the raw tree encoding recipe to the
-
-\begin_inset listings
-inline true
-status open
+Here, we do not need parentheses since the operation
+\begin_inset Formula $\oplus$
+\end_inset
-\begin_layout Plain Layout
+ is associative and our encoding obeys the associativity law.
+ This expression is represented by the non-empty list
+\begin_inset Formula $\left[t_{1},t_{2},e,t_{3},e,e\right]$
+\end_inset
-Functor
+.
\end_layout
+\begin_layout Standard
+To make the left identity law hold, we replace any expression of the form
+
+\begin_inset Formula $e\oplus x$
\end_inset
- typeclass.
- The result will be a new type constructor that we call a
-\series bold
-free functor on
-\series default
-
-\begin_inset Formula $F$
+ by just
+\begin_inset Formula $x$
\end_inset
.
-\begin_inset Index idx
-status open
+ This will eliminate
+\begin_inset Quotes eld
+\end_inset
-\begin_layout Plain Layout
-free functor
-\end_layout
+empty
+\begin_inset Quotes erd
+\end_inset
+ list elements (
+\begin_inset Formula $e$
\end_inset
-
+) to the left of any other elements (empty or not).
+ For the example just shown, the result will be:
+\begin_inset Formula
+\[
+t_{1}\oplus t_{2}\oplus t_{3}\oplus e\quad.
+\]
+
+\end_inset
+
+This corresponds to a non-empty list of the form
+\begin_inset Formula $\left[t_{1},t_{2},t_{3},e\right]$
+\end_inset
+
+ where all non-empty values appear before the empty one.
+ The last empty element cannot be removed, since we do not impose the right
+ identity law.
\end_layout
\begin_layout Standard
-The recipe tells us to define a case class for the
+What type can represent this data? A simple attempt would be a pair
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-fmap
+(List[T], Boolean)
\end_layout
\end_inset
- method and another case class to wrap the given type constructor
-\begin_inset Formula $F$
-\end_inset
-
-.
- So, the raw tree encoding of the free functor on
-\begin_inset Formula $F$
-\end_inset
-
- looks like this:
+, where the boolean value is
\begin_inset listings
-inline false
+inline true
status open
\begin_layout Plain Layout
-sealed trait FFR[F[_], A] {
+true
\end_layout
-\begin_layout Plain Layout
+\end_inset
- def map[B](f: A => B): FFR[F, B] = FMap(f, this)
-\end_layout
+ when an empty value is present at the end.
+ However, this type cannot guarantee that either the list of type
+\begin_inset listings
+inline true
+status open
\begin_layout Plain Layout
-}
+List[T]
\end_layout
-\begin_layout Plain Layout
+\end_inset
-final case class FMap[F[_], X, Y](f: X => Y, p: FFR[F, X]) extends FFR[F,
- Y]
-\end_layout
+ is non-empty or the boolean value is
+\begin_inset listings
+inline true
+status open
\begin_layout Plain Layout
-final case class Op[F[_], A](op: F[A]) extends FFR[F, A]
+true
\end_layout
\end_inset
-
+.
\end_layout
\begin_layout Standard
-This code corresponds to the following notation for the lifting
-\begin_inset Formula $f^{\uparrow\text{FFR}}$
-\end_inset
-
-:
-\begin_inset Formula
-\begin{align}
- & \text{FFR}^{F^{\bullet},A}\triangleq F^{A}+\exists X.\,(X\rightarrow A)\times\text{FFR}^{F^{\bullet},X}\quad,\label{eq:definition-FFR-existential-type}\\
- & p^{:\text{FFR}^{F^{\bullet},A}}\triangleright(f^{:A\rightarrow B})^{\uparrow\text{FFR}^{F^{\bullet},\bullet}}\triangleq\bbnum 0^{:F^{B}}+\exists^{A}.\,f^{:A\rightarrow B}\times p^{:\text{FFR}^{F^{\bullet},A}}\quad.\nonumber
-\end{align}
+To derive a correct data type, we begin by first defining the required structure
+ by induction:
+\end_layout
-\end_inset
+\begin_layout Itemize
+Base cases:
+\end_layout
-The notation
-\begin_inset Formula $\exists^{A}$
+\begin_deeper
+\begin_layout Enumerate
+We may have a single value of type
+\begin_inset Formula $T$
\end_inset
- means that we bind the type
-\begin_inset Formula $A$
-\end_inset
+.
+\end_layout
- to the existentially quantified type
-\begin_inset Formula $X$
+\begin_layout Enumerate
+We may have a single empty value (
+\begin_inset Formula $e$
\end_inset
- in the definition
-\begin_inset space ~
-\end_inset
+).
+
+\end_layout
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:definition-FFR-existential-type"
-plural "false"
-caps "false"
-noprefix "false"
+\end_deeper
+\begin_layout Itemize
+Inductive steps:
+\end_layout
+\begin_deeper
+\begin_layout Itemize
+If a sequence begins with a
+\begin_inset Formula $t:T$
\end_inset
-) of
-\begin_inset Formula $\text{FFR}^{F^{\bullet},B}$
+ then it may continue to any other sequence of the same type (beginning
+ either with another
+\begin_inset Formula $t':T$
\end_inset
-.
- This notation expresses the requirement that the existentially quantified
- type must be assigned to a specific type every time we create a specific
- value.
+ or with the empty value).
+
\end_layout
+\end_deeper
\begin_layout Standard
-A
-\begin_inset Quotes eld
+If a sequence begins with an
+\begin_inset Formula $e$
\end_inset
-free functor program
-\begin_inset Quotes erd
-\end_inset
+, it must end at that point.
+ So, there is no induction step following the second base case.
+\end_layout
- is a value of type
+\begin_layout Standard
+To describe this logic, we need two case classes for the base cases and
+ two more case classes to describe the two different types of induction
+ steps.
+ The empty value will be represented by a named
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-FFR[F, A]
+Unit
\end_layout
\end_inset
-.
- To construct such values, we must begin with a wrapped
+ type (
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-F
+OneE
\end_layout
\end_inset
--operation and then apply zero or more
+):
\begin_inset listings
-inline true
+inline false
status open
\begin_layout Plain Layout
-map
+sealed trait F5[T]
\end_layout
-\end_inset
+\begin_layout Plain Layout
- methods.
-
+final case class OneT[T](single: T) extends F5[T] // Base case 1.
\end_layout
-\begin_layout Standard
-To use a free functor program in practice, we need to apply a runner to
- it.
- A simple runner is a function of type
-\begin_inset Formula $\forall A.\,\text{FFR}^{F,A}\rightarrow A$
-\end_inset
+\begin_layout Plain Layout
- that extracts a value of type
-\begin_inset Formula $A$
-\end_inset
+final case class OneE[T]() extends F5[T] // Base case 2.
+\end_layout
+
+\begin_layout Plain Layout
+
+final case class NELT[T](head: T, tail: F5[T]) extends F5[T]
+\end_layout
- from a free functor program.
- To obtain a runner, we need to know how to extract values from the effect
- constructor
-\begin_inset Formula $F$
\end_inset
-.
- That information is given by a function of type
-\begin_inset Formula $\forall C.\,F^{C}\rightarrow C$
+In the type notation, we may write the recursive definition of
+\begin_inset Formula $F_{5}$
\end_inset
- (an
-\begin_inset Index idx
-status open
+ as:
+\begin_inset Formula
+\[
+F_{5}^{T}\triangleq\bbnum 1+T+T\times F_{5}^{T}\quad.
+\]
-\begin_layout Plain Layout
-effect runner
-\end_layout
+\end_inset
+The
+\begin_inset Quotes eld
\end_inset
-effect runner for
-\begin_inset Formula $F$
+unrolling trick
+\begin_inset Quotes erd
\end_inset
-).
- To implement such functions, we use the trait
-\begin_inset listings
-inline true
+
+\begin_inset Index idx
status open
\begin_layout Plain Layout
-
-Runner
+unrolling trick for recursive types
\end_layout
\end_inset
- defined in Section
+(Statement
\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:A-first-recipe-monadic-dsl"
+reference "Statement-unrolling-trick"
plural "false"
caps "false"
noprefix "false"
\end_inset
-.
- Now we can write the code of the runner for
-\begin_inset Formula $\text{FFR}^{F,A}$
+) simplifies this recursive definition to:
+\begin_inset Formula
+\[
+F_{5}^{T}\cong\text{List}^{T}\times(\bbnum 1+T)\quad.
+\]
+
\end_inset
-:
+
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
-def runFFR[F[_], A](runner: Runner[F]): FFR[F, A] => A = {
+final case class F5[T](start: List[T], end: Option[T])
\end_layout
-\begin_layout Plain Layout
+\end_inset
- case FMap(f, p) => f(runFFR(runner)(p))
-\end_layout
+The
+\begin_inset listings
+inline true
+status open
\begin_layout Plain Layout
- case Op(op) => runner.apply(op)
+Monoid
\end_layout
+\end_inset
+
+ typeclass instance and the runner code for
+\begin_inset listings
+inline true
+status open
+
\begin_layout Plain Layout
-}*** check if this works
+F5
\end_layout
\end_inset
-The code notation for this function is:
-\begin_inset Formula
-\begin{align*}
- & \text{runFFR}^{F^{\bullet},A}:(\forall C.\,F^{C}\rightarrow C)\rightarrow\text{FFR}^{F^{\bullet},A}\rightarrow A\quad,\\
- & \text{runFFR}(\text{run}:\forall C.\,F^{C}\rightarrow C)\triangleq\forall B.\,\,\begin{array}{|c||c|}
- & A\\
-\hline F^{A} & \text{run}\\
-(B\rightarrow A)\times\text{FFR}^{F^{\bullet},B} & f^{:B\rightarrow A}\times p^{:FFR^{F^{\bullet},B}}\rightarrow p\triangleright\big(\overline{\text{runFFR}}(\text{run})\big)\triangleright f
-\end{array}\quad.
-\end{align*}
-
-\end_inset
+ are written as:
+\begin_inset listings
+inline false
+status open
-The outside universal quantifier
-\begin_inset Formula $\forall B$
-\end_inset
+\begin_layout Plain Layout
- replaces
-\begin_inset Formula $\exists B$
-\end_inset
+def wrapF5[T](t: T): F5[T] = F5(Nil, Some(t))
+\end_layout
- in the function argument, according to Eq.
-\begin_inset space ~
-\end_inset
+\begin_layout Plain Layout
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:existential-via-universal"
-plural "false"
-caps "false"
-noprefix "false"
+def concatF5[T]: (F5[T], F5[T]) => F5[T] = {
+\end_layout
-\end_inset
+\begin_layout Plain Layout
-).
+ case (F5(start1, Some(t)), F5(start2, end)) => F5(start1 ++ List(t) ++
+ start2, end)
\end_layout
-\begin_layout Standard
-More generally, we may want to run the effects of
-\begin_inset Formula $F$
-\end_inset
+\begin_layout Plain Layout
- into the effects of a given functor
-\begin_inset Formula $G$
-\end_inset
+ case (F5(start1, None), F5(start2, end)) => F5(start1 ++ start2, end)
+\end_layout
-.
- (The functor
-\begin_inset Formula $G$
-\end_inset
+\begin_layout Plain Layout
+
+}
+\end_layout
+
+\begin_layout Plain Layout
+
+def emptyF5[T]: F5[T] = F5(Nil, None)
+\end_layout
+
+\begin_layout Plain Layout
+
+implicit def monoidF5[T]: Monoid[F5[T]] = Monoid(concatF5[T], emptyF5[T])
+\end_layout
+
+\begin_layout Plain Layout
+
+def runnerF5[M: Monoid, T](runT: T => M)(fm: F5[T]): M = {
+\end_layout
+
+\begin_layout Plain Layout
+
+ val last: M = fm.end match {
+\end_layout
+
+\begin_layout Plain Layout
+
+ case Some(t) => runT(t)
+\end_layout
+
+\begin_layout Plain Layout
+
+ case None => Monoid[M].empty
+\end_layout
+
+\begin_layout Plain Layout
+
+ }
+\end_layout
+
+\begin_layout Plain Layout
+
+ fm.start.map(runT).reduce(Monoid[M].combine) |+| last
+\end_layout
+
+\begin_layout Plain Layout
+
+}
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+To test this code, let us set
+\begin_inset Formula $T=\text{Int}$
+\end_inset
+
+ and create a free monoid value of type
+\begin_inset Formula $F_{5}^{\text{Int}}$
+\end_inset
+
+ corresponding to the expression
+\begin_inset Formula $e\oplus1\oplus e\oplus2\oplus e$
+\end_inset
+
+:
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+scala> val testF5 = emptyF5[Int] |+| wrapF5(1) |+| emptyF5 |+| wrapF5(2)
+ |+| emptyF5
+\end_layout
+
+\begin_layout Plain Layout
+
+val testF5: F5[Int] = F5(List(1, 2),None)
+\end_layout
+
+\end_inset
+
+We see that the free monoid
+\begin_inset Formula $F_{5}$
+\end_inset
+
+ simplifies this expression to
+\begin_inset Formula $1\oplus2\oplus e$
+\end_inset
+
+, although the expression should be equivalent to just
+\begin_inset Formula $1\oplus2$
+\end_inset
+
+ if we were able to use all the monoid laws.
+\end_layout
+
+\begin_layout Standard
+To evaluate the
+\begin_inset Quotes eld
+\end_inset
+
+free monoid program
+\begin_inset Quotes erd
+\end_inset
+
+
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+testF5
+\end_layout
+
+\end_inset
+
+, choose the target monoid
+\begin_inset Formula $M=\text{String}$
+\end_inset
+
+ (with the monoidal operation being the concatenation of strings).
+ For the purposes of this example, define the function
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+runT
+\end_layout
+
+\end_inset
+
+ that prints integers with up to 5 leading zeros.
+ Then run the program and expect the concatenation of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+\begin_inset Quotes eld
+\end_inset
+
+00001
+\begin_inset Quotes erd
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+\begin_inset Quotes eld
+\end_inset
+
+00002
+\begin_inset Quotes erd
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+:
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+implicit val monoidString: Monoid[String] = Monoid(_ + _, "")
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+val runT: Int => String = (x: Int) => f
+\begin_inset Quotes erd
+\end_inset
+
+${x}%05d
+\begin_inset Quotes erd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+scala> runT(123)
+\end_layout
+
+\begin_layout Plain Layout
+
+val res0: String = 00123
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+scala> runnerF5(runT)(testF5)
+\end_layout
+
+\begin_layout Plain Layout
+
+val res1: String = 0000100002
+\end_layout
+
+\end_inset
+
+The result of the evaluation is the same as if the monoid program were just
+
+\begin_inset Formula $1\oplus2$
+\end_inset
+
+.
+ The monoid laws appear to hold after applying the runner.
+\end_layout
+
+\begin_layout Subsubsection
+Example
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Example-reduced-monoid-encoding-one-law-1"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-reduced-monoid-encoding-one-law-1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Find a reduced encoding of the free monoid that satisfies the left identity
+ law but
+\emph on
+no
+\emph default
+ other laws of monoids.
+\end_layout
+
+\begin_layout Subparagraph
+Solution
+\end_layout
+
+\begin_layout Standard
+Our goal is to define a recursive type
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+F6
+\end_layout
+
+\end_inset
+
+ with the required properties.
+\end_layout
+
+\begin_layout Standard
+Start with the raw tree encoding, which is a binary tree with leaves of
+ type
+\begin_inset Formula $\bbnum 1+T$
+\end_inset
+
+.
+ The type
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+F6[T]
+\end_layout
+
+\end_inset
+
+ must be similarly a binary tree with leaves of that type.
+ However, the left identity law (
+\begin_inset Formula $e\oplus x=x$
+\end_inset
+
+) means that in any branching of the tree, the left branch cannot be an
+
+\begin_inset Quotes eld
+\end_inset
+
+empty
+\begin_inset Quotes erd
+\end_inset
+
+ leaf (a leaf carrying the value
+\begin_inset Formula $e$
+\end_inset
+
+).
+ The right branch remains unrestricted.
+ To implement the restriction on the left branches, we introduce a special
+ type (
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+TreeNonEmpty
+\end_layout
+
+\end_inset
+
+) for a tree that cannot be an empty leaf value.
+ The left branches of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+TreeNonEmpty
+\end_layout
+
+\end_inset
+
+ must also have type
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+TreeNonEmpty
+\end_layout
+
+\end_inset
+
+ (cannot be empty leaves), while the right branches are unrestricted (have
+ type
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+F6
+\end_layout
+
+\end_inset
+
+).
+ Finally, we define the type
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+F6
+\end_layout
+
+\end_inset
+
+ as a tree that can itself be an empty leaf, but whose left branches have
+ type
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+TreeNonEmpty
+\end_layout
+
+\end_inset
+
+ (cannot be empty leaves).
+ The right branches of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+F6
+\end_layout
+
+\end_inset
+
+ have again type
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+F6
+\end_layout
+
+\end_inset
+
+.
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+sealed trait TreeNE[T] // Cannot be an empty leaf.
+\end_layout
+
+\begin_layout Plain Layout
+
+final case class LeafNE[T](t: T) extends TreeNE[T]
+\end_layout
+
+\begin_layout Plain Layout
+
+final case class BranchNE[T](left: TreeNE[T], right: F6[T]) extends TreeNE[T]
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+sealed trait F6[T] // This tree can be an empty leaf, but its left branch.
+\end_layout
+
+\begin_layout Plain Layout
+
+final case class LeafT[T](t: T) extends F6[T]
+\end_layout
+
+\begin_layout Plain Layout
+
+final case class LeafE[T]() extends F6[T]
+\end_layout
+
+\begin_layout Plain Layout
+
+final case class BranchF6[T](left: TreeNE[T], right: F6[T]) extends F6[T]
+\end_layout
+
+\end_inset
+
+In the type notation, the encoding
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+F6
+\end_layout
+
+\end_inset
+
+ is expressed via two
+\series bold
+mutually recursive types
+\series default
+
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+mutually recursive types
+\end_layout
+
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align*}
+\text{\texttt{F6[T]} in the code}:\quad & F_{6}^{T}\triangleq\bbnum 1+T+G^{T}\times F_{6}^{T}\quad,\\
+\text{\texttt{TreeNE[T]} in the code}:\quad & G^{T}\triangleq T+G^{T}\times F_{6}^{T}\quad.
+\end{align*}
+
+\end_inset
+
+
+\begin_inset Quotes erd
+\end_inset
+
+Mutually recursive
+\begin_inset Quotes erd
+\end_inset
+
+ means that each the definitions of
+\begin_inset Formula $F_{6}^{T}$
+\end_inset
+
+ and
+\begin_inset Formula $G$
+\end_inset
+
+ uses both these types.
+\end_layout
+
+\begin_layout Standard
+Let us implement the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Monoid
+\end_layout
+
+\end_inset
+
+ instance and a universal runner for
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+F6
+\end_layout
+
+\end_inset
+
+, which we write via two mutually recursive functions (
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+runnerF6NE
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+runnerF6
+\end_layout
+
+\end_inset
+
+):
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+def wrapF6[T](t: T): F6[T] = LeafT(t)
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+def toTreeNE[T]: F6[T] => TreeNE[T] = {
+\end_layout
+
+\begin_layout Plain Layout
+
+ case LeafE() => ??? // This case will never be used.
+\end_layout
+
+\begin_layout Plain Layout
+
+ case LeafT(t) => LeafNE(t)
+\end_layout
+
+\begin_layout Plain Layout
+
+ case BranchF6(left, right) => BranchNE(left, right)
+\end_layout
+
+\begin_layout Plain Layout
+
+}
+\end_layout
+
+\begin_layout Plain Layout
+
+def concatF6[T]: (F6[T], F6[T]) => F6[T] = {
+\end_layout
+
+\begin_layout Plain Layout
+
+ case (LeafE(), x) => x // Left identity law holds automatically.
+\end_layout
+
+\begin_layout Plain Layout
+
+ case (first, second) => BranchF6(toTreeNE(first), second) // `first` is
+ guaranteed to be non-empty.
+\end_layout
+
+\begin_layout Plain Layout
+
+ }
+\end_layout
+
+\begin_layout Plain Layout
+
+def emptyF6[T]: F6[T] = LeafE()
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+implicit def monoidF6[T]: Monoid[F6[T]] = Monoid(concatF6[T], emptyF6[T])
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+def runnerF6NE[M: Monoid, T](runT: T => M)(tree: TreeNE[T]): M = tree match
+ {
+\end_layout
+
+\begin_layout Plain Layout
+
+ case LeafNE(t) => runT(t)
+\end_layout
+
+\begin_layout Plain Layout
+
+ case BranchNE(left, LeafE()) => runnerF6NE(runT)(left)
+\end_layout
+
+\begin_layout Plain Layout
+
+ case BranchNE(left, right) => runnerF6NE(runT)(left) |+| runnerF6(runT)(right)
+\end_layout
+
+\begin_layout Plain Layout
+
+}
+\end_layout
+
+\begin_layout Plain Layout
+
+def runnerF6[M: Monoid, T](runT: T => M)(tree: F6[T]): M = tree match {
+\end_layout
+
+\begin_layout Plain Layout
+
+ case LeafE() => Monoid[M].empty
+\end_layout
+
+\begin_layout Plain Layout
+
+ case LeafT(t) => runT(t)
+\end_layout
+
+\begin_layout Plain Layout
+
+ case BranchF6(left, right) => runnerF6NE(runT)(left) |+| runnerF6(runT)(right)
+\end_layout
+
+\begin_layout Plain Layout
+
+}
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+We test this code with the same data as in the previous example.
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+scala> val testF6 = emptyF6[Int] |+| wrapF6(1) |+| emptyF6 |+| wrapF6(2)
+ |+| emptyF6
+\end_layout
+
+\begin_layout Plain Layout
+
+val testF6: F6[Int] = BranchF6(BranchNE(BranchNE(LeafNE(1),LeafE()),LeafT(2)),Le
+afE())
+\end_layout
+
+\end_inset
+
+We see that the monoid program
+\begin_inset Formula $(((e\oplus1)\oplus e)\oplus2)\oplus e$
+\end_inset
+
+ is simplified to the expression tree
+\begin_inset Formula $((1\oplus e)\oplus2)\oplus e$
+\end_inset
+
+ because the free monoid
+\begin_inset Formula $F_{6}$
+\end_inset
+
+ only respects the left identity law but not the associativity law.
+\end_layout
+
+\begin_layout Standard
+Apply
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+runnerF6
+\end_layout
+
+\end_inset
+
+ to
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+testF6
+\end_layout
+
+\end_inset
+
+ using the same function
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+runT
+\end_layout
+
+\end_inset
+
+ as before:
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+scala> runnerF6(runT)(testF6)
+\end_layout
+
+\begin_layout Plain Layout
+
+val res1: String = 0000100002
+\end_layout
+
+\end_inset
+
+This is the same result as in the previous example.
+\end_layout
+
+\begin_layout Standard
+***Exercises: free monoids that satisfy the right identity law and the associati
+vity law; or just the right identity law.
+ Find a map between free monoids that satisfy the right identity law and
+ that satisfy the left; show that operations are not preserved and that
+ maps are not injective.
+ Use a sorted list to implement commutativity law for semigroups and for
+ monoids.
+ Find a free semigroup that is commutative but not associative.
+
+\end_layout
+
+\begin_layout Subsection
+Free functors
+\end_layout
+
+\begin_layout Standard
+Consider the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Functor
+\end_layout
+
+\end_inset
+
+ typeclass whose only method is
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+fmap
+\end_layout
+
+\end_inset
+
+:
+\begin_inset Formula
+\[
+\text{fmap}:\left(A\rightarrow B\right)\rightarrow F^{A}\rightarrow F^{B}\quad.
+\]
+
+\end_inset
+
+The
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+fmap
+\end_layout
+
+\end_inset
+
+ method is supported by all covariant type constructors, but is not available
+ when
+\begin_inset Formula $F$
+\end_inset
+
+ is a contrafunctor or a GADT.
+ (See Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Examples-of-non-functors"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ for more examples.) Let us now apply the raw tree encoding recipe to the
+
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Functor
+\end_layout
+
+\end_inset
+
+ typeclass.
+ The result will be a new type constructor that we call a
+\series bold
+free functor on
+\series default
+
+\begin_inset Formula $F$
+\end_inset
+
+.
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+free functor
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+The recipe tells us to define a case class for the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+fmap
+\end_layout
+
+\end_inset
+
+ method and another case class to wrap the given type constructor
+\begin_inset Formula $F$
+\end_inset
+
+.
+ So, the raw tree encoding of the free functor on
+\begin_inset Formula $F$
+\end_inset
+
+ looks like this:
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+sealed trait FFR[F[_], A] {
+\end_layout
+
+\begin_layout Plain Layout
+
+ def map[B](f: A => B): FFR[F, B] = FMap(f, this)
+\end_layout
+
+\begin_layout Plain Layout
+
+}
+\end_layout
+
+\begin_layout Plain Layout
+
+final case class FMap[F[_], X, Y](f: X => Y, p: FFR[F, X]) extends FFR[F,
+ Y]
+\end_layout
+
+\begin_layout Plain Layout
+
+final case class Op[F[_], A](op: F[A]) extends FFR[F, A]
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+This code corresponds to the following notation for the lifting
+\begin_inset Formula $f^{\uparrow\text{FFR}}$
+\end_inset
+
+:
+\begin_inset Formula
+\begin{align}
+ & \text{FFR}^{F,A}\triangleq F^{A}+\exists X.\,(X\rightarrow A)\times\text{FFR}^{F,X}\quad,\label{eq:definition-FFR-existential-type}\\
+ & p^{:\text{FFR}^{F,A}}\triangleright(f^{:A\rightarrow B})^{\uparrow\text{FFR}^{F,\bullet}}\triangleq\bbnum 0^{:F^{B}}+\exists^{A}.\,f^{:A\rightarrow B}\times p^{:\text{FFR}^{F,A}}\quad.\nonumber
+\end{align}
+
+\end_inset
+
+The notation
+\begin_inset Formula $\exists^{A}$
+\end_inset
+
+ means that we bind the type
+\begin_inset Formula $A$
+\end_inset
+
+ to the existentially quantified type
+\begin_inset Formula $X$
+\end_inset
+
+ in the definition
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:definition-FFR-existential-type"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) of
+\begin_inset Formula $\text{FFR}^{F,B}$
+\end_inset
+
+.
+ This notation expresses the requirement that the existentially quantified
+ type must be assigned to a specific type every time we create a specific
+ value.
+\end_layout
+
+\begin_layout Standard
+A
+\begin_inset Quotes eld
+\end_inset
+
+free functor program
+\begin_inset Quotes erd
+\end_inset
+
+ is a value of type
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+FFR[F, A]
+\end_layout
+
+\end_inset
+
+.
+ To construct such values, we must begin with a wrapped
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+F
+\end_layout
+
+\end_inset
+
+-operation and then apply zero or more
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map
+\end_layout
+
+\end_inset
+
+ methods.
+
+\end_layout
+
+\begin_layout Standard
+To use a free functor program in practice, we need to apply a runner to
+ it.
+ A simple runner is a function of type
+\begin_inset Formula $\forall A.\,\text{FFR}^{F,A}\rightarrow A$
+\end_inset
+
+ that extracts a value of type
+\begin_inset Formula $A$
+\end_inset
+
+ from a free functor program.
+ To obtain a runner, we need to know how to extract values from the effect
+ constructor
+\begin_inset Formula $F$
+\end_inset
+
+.
+ That information is given by a function of type
+\begin_inset Formula $\forall C.\,F^{C}\rightarrow C$
+\end_inset
+
+ (an
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+effect runner
+\end_layout
+
+\end_inset
+
+effect runner for
+\begin_inset Formula $F$
+\end_inset
+
+).
+ To implement such functions, we use the trait
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Runner
+\end_layout
+
+\end_inset
+
+ defined in Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:A-first-recipe-monadic-dsl"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+ Now we can write the code of the universal runner for
+\begin_inset Formula $\text{FFR}^{F,A}$
+\end_inset
+
+:
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+def runFFR[F[_], A](runner: Runner[F]): FFR[F, A] => A = {
+\end_layout
+
+\begin_layout Plain Layout
+
+ case FMap(f, p) => f(runFFR(runner)(p))
+\end_layout
+
+\begin_layout Plain Layout
+
+ case Op(op) => runner.apply(op)
+\end_layout
+
+\begin_layout Plain Layout
+
+}
+\end_layout
+
+\end_inset
+
+The code notation for this function is:
+\begin_inset Formula
+\begin{align*}
+ & \text{runFFR}^{F,A}:(\forall C.\,F^{C}\rightarrow C)\rightarrow\text{FFR}^{F,A}\rightarrow A\quad,\\
+ & \text{runFFR}(\text{run}:\forall C.\,F^{C}\rightarrow C)\triangleq\forall B.\,\,\begin{array}{|c||c|}
+ & A\\
+\hline F^{A} & \text{run}\\
+(B\rightarrow A)\times\text{FFR}^{F,B} & f^{:B\rightarrow A}\times p^{:FFR^{F,B}}\rightarrow p\triangleright\big(\overline{\text{runFFR}}(\text{run})\big)\triangleright f
+\end{array}\quad.
+\end{align*}
+
+\end_inset
+
+The outside quantifier
+\begin_inset Formula $\forall B$
+\end_inset
+
+ replaces
+\begin_inset Formula $\exists B$
+\end_inset
+
+ in the function argument, according to Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:existential-via-universal"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+\end_layout
+
+\begin_layout Standard
+More generally, we may need to run the effects of
+\begin_inset Formula $F$
+\end_inset
+
+ into the effects of a given functor
+\begin_inset Formula $G$
+\end_inset
+
+.
+ (The functor
+\begin_inset Formula $G$
+\end_inset
could, for example, describe errors or asynchronous execution.) The correspondin
-g runner will have type
+g effect runner will have type
\begin_inset Formula $\forall C.\,F^{C}\rightarrow G^{C}$
\end_inset
-, and the code is:
+ instead of
+\begin_inset Formula $\forall C.\,F^{C}\rightarrow C$
+\end_inset
+
+.
+ The code for the universal runner is:
\begin_inset Formula
\begin{align*}
- & \text{runFFR}^{F^{\bullet},G^{\bullet},A}:(\forall C.\,F^{C}\rightarrow G^{C})\rightarrow\text{FFR}^{F^{\bullet},A}\rightarrow G^{A}\quad,\\
+ & \text{runFFR}^{F,G,A}:(\forall C.\,F^{C}\rightarrow G^{C})\rightarrow\text{FFR}^{F,A}\rightarrow G^{A}\quad,\\
& \text{runFFR}\,(\text{run})\triangleq\forall B.\,\,\begin{array}{|c||c|}
& G^{A}\\
\hline F^{A} & \text{run}\\
-(B\rightarrow A)\times\text{FFR}^{F^{\bullet},B} & f^{:B\rightarrow A}\times p^{:FFR^{F^{\bullet},B}}\rightarrow p\triangleright\big(\overline{\text{runFFR}}\,(\text{run})\big)\triangleright f^{\uparrow G}
+(B\rightarrow A)\times\text{FFR}^{F,B} & f^{:B\rightarrow A}\times p^{:FFR^{F,B}}\rightarrow p\triangleright\big(\overline{\text{runFFR}}\,(\text{run})\big)\triangleright f^{\uparrow G}
\end{array}\quad.
\end{align*}
@@ -21564,6 +22897,14 @@ g runner will have type
\end_layout
+\begin_layout Standard
+*** example code: what if
+\begin_inset Formula $\forall C.\,F^{C}\rightarrow C$
+\end_inset
+
+ cannot be implemented? What weaker property is sufficient?
+\end_layout
+
\begin_layout Standard
The type constructor
\begin_inset listings
@@ -21631,7 +22972,7 @@ noprefix "false"
\begin_layout Standard
Take any free functor (
-\begin_inset Formula $\text{FFR}^{F^{\bullet},A}$
+\begin_inset Formula $\text{FFR}^{F,A}$
\end_inset
) and any runner (
@@ -21644,12 +22985,12 @@ Take any free functor (
is a lawful functor.
Denote for brevity
-\begin_inset Formula $f^{\uparrow\text{FFR}}\triangleq f^{\uparrow\text{FFR}^{F^{\bullet},\bullet}}$
+\begin_inset Formula $f^{\uparrow\text{FFR}}\triangleq f^{\uparrow\text{FFR}^{F,\bullet}}$
\end_inset
.
- The functor laws will hold if we apply the runner function, denoted for
- brevity by
+ The functor laws will hold after applying the runner function, denoted
+ for brevity by
\begin_inset Formula $\rho\triangleq\text{runFFR}\,(\text{run})$
\end_inset
@@ -21757,8 +23098,7 @@ The right-hand side is then simplified to the same code:
\begin_layout Standard
To transform the raw tree encoding of the free functor into a reduced encoding,
we require that all functor laws should hold even before applying a runner.
- We begin by finding out in detail why the functor laws fail to hold for
-
+ We begin by finding out in detail why the functor laws fail for
\begin_inset listings
inline true
status open
@@ -22117,19 +23457,7 @@ F
\begin_inset Formula $F$
\end_inset
--effects by the
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-
-FMap
-\end_layout
-
-\end_inset
-
- case class as
+-effects by the expression
\begin_inset listings
inline true
status open
@@ -22271,7 +23599,7 @@ f
\end_inset
.
- So, we may remove the
+ It means we may remove the
\begin_inset listings
inline true
status open
@@ -22284,11 +23612,94 @@ Op
\end_inset
case class altogether.
+ Only one case class (
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+FMap
\end_layout
-\begin_layout Standard
-The result is a simplified definition of the free functor.
- The complete code is:
+\end_inset
+
+) remains.
+ However, we still need to implement the free functor as a trait
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+FF[F, A]
+\end_layout
+
+\end_inset
+
+ containing a single case class
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+FMap[F, C, A]
+\end_layout
+
+\end_inset
+
+.
+ This is because
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+FMap[F, C, A]
+\end_layout
+
+\end_inset
+
+ has an extra type parameter (
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+C
+\end_layout
+
+\end_inset
+
+) that does not appear in
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+FF[F, A]
+\end_layout
+
+\end_inset
+
+.
+ (In other words, the type parameter
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+X
+\end_layout
+
+\end_inset
+
+ is existentially quantified.) The complete code is:
\begin_inset listings
inline false
status open
@@ -22310,12 +23721,12 @@ sealed trait FF[F[_], A] {
\begin_layout Plain Layout
-final case class FMap[F[_], X, Y](f: X => Y, p: F[X]) extends FF[F, Y] {
+final case class FMap[F[_], C, A](f: C => A, p: F[C]) extends FF[F, A] {
\end_layout
\begin_layout Plain Layout
- def map[Z](g: Y => Z): FF[F, Z] = FMap[F, X, Z](f andThen g, p)
+ def map[B](g: A => B): FF[F, B] = FMap[F, C, B](f andThen g, p)
\end_layout
\begin_layout Plain Layout
@@ -22335,7 +23746,7 @@ def runFF[F[_], A](runner: Runner[F]): FF[F, A] => A = {
\begin_layout Plain Layout
-}*** check if this works
+}
\end_layout
\end_inset
@@ -22344,11 +23755,11 @@ def runFF[F[_], A](runner: Runner[F]): FF[F, A] => A = {
\end_layout
\begin_layout Standard
-The code notation for this code and a general runner is:
+The code notation for this code is:
\begin_inset Formula
\begin{align*}
- & \text{FF}^{F^{\bullet},A}\triangleq\exists C.\,\left(C\rightarrow A\right)\times F^{C}\quad,\quad\quad(\exists C.\,f^{:C\rightarrow A}\times p^{:F^{C}})\triangleright(g^{:A\rightarrow B})^{\uparrow\text{FR}}\triangleq\exists^{C}.\,(f\bef g)\times p\quad,\\
- & \text{runFF}:(\forall C.\,F^{C}\rightarrow G^{C})\rightarrow\text{FF}^{F^{\bullet},A}\rightarrow G^{A}\quad,\\
+ & \text{FF}^{F,A}\triangleq\exists C.\,\left(C\rightarrow A\right)\times F^{C}\quad,\quad\quad(\exists C.\,f^{:C\rightarrow A}\times p^{:F^{C}})\triangleright(g^{:A\rightarrow B})^{\uparrow\text{FR}}\triangleq\exists^{C}.\,(f\bef g)\times p\quad,\\
+ & \text{runFF}:(\forall C.\,F^{C}\rightarrow G^{C})\rightarrow\text{FF}^{F,A}\rightarrow G^{A}\quad,\\
& \text{runFF}\,(\text{run})\triangleq(\exists C.\,f^{:C\rightarrow A}\times p^{:F^{C}})\rightarrow p\triangleright\text{run}\triangleright f^{\uparrow G}\quad.
\end{align*}
@@ -22386,7 +23797,7 @@ FF[F, A]
\end_inset
- even before applying a runner.
+.
\end_layout
\begin_layout Standard
@@ -22494,7 +23905,7 @@ co-Yoneda identity
\end_inset
-We will prove this type equivalence in Statement
+We will prove this type identity in Statement
\begin_inset space ~
\end_inset
@@ -22597,54 +24008,55 @@ FMap(f andThen g, p)
.
The Scala compiler cannot directly handle the composition of a large number
- of functions without causing a stack overflow.
- This problem can be resolved if we postpone the function composition and
- instead create a list of functions that need to be composed.
- The runner can evaluate the list of functions without running into a stack
- overflow.
-\end_layout
-
-\begin_layout Standard
-This gives us an idea for another encoding of the stack-safe free functor,
- which we will call
+ of functions without causing a stack overflow:
\begin_inset listings
-inline true
+inline false
status open
\begin_layout Plain Layout
-FFS
+def composed(n: Int): Long => Long = (1 to n).foldLeft[Long => Long](x =>
+ x){ (prev, i) => prev andThen (x => x + i) }
\end_layout
-\end_inset
+\begin_layout Plain Layout
-.
- First, we implement a data structure called
-\begin_inset listings
-inline true
-status open
+\end_layout
\begin_layout Plain Layout
-FuncSeq
+scala> composed(100)(0) // OK to compose 100 functions.
\end_layout
-\end_inset
+\begin_layout Plain Layout
- for storing a list of functions with matching types.
- A value of type
-\begin_inset listings
-inline true
-status open
+res0: Long = 5050
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
\begin_layout Plain Layout
-FuncSeq[A, B]
+scala> composed(100000)(0) // Cannot compose 100000 functions.
+\end_layout
+
+\begin_layout Plain Layout
+
+java.lang.StackOverflowError
\end_layout
\end_inset
- holds a list of functions with types
+This code causes a stack overflow because each function composition creates
+ a new stack frame when functions are applied.
+\end_layout
+
+\begin_layout Standard
+Stack overflows can be avoided if we postpone the function compositions.
+ Instead, we just store all the functions that need to be composed as a
+ sequence of functions with types
\begin_inset Formula $A\rightarrow C_{1}$
\end_inset
@@ -22664,113 +24076,272 @@ FuncSeq[A, B]
\begin_inset Formula $C_{i}$
\end_inset
- are some chosen types.
- A list of with those types can be composed to yield a function of type
+ are some fixed types.
+ Then we write a
+\begin_inset Quotes eld
+\end_inset
+
+runner
+\begin_inset Quotes erd
+\end_inset
+
+ that applies the functions one by one to a given initial value of type
+\begin_inset Formula $A$
+\end_inset
+
+.
+ The result is as if we have evaluated a single function of type
\begin_inset Formula $A\rightarrow B$
\end_inset
.
- To simplify code, we will cast all intermediate types to
+\end_layout
+
+\begin_layout Standard
+Here is an example implementation of this idea.
+ Define a helper class
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-Any
+SafeFunction
\end_layout
\end_inset
- and back.
- Our code will take care to construct
+ as a subclass of
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-FuncSeq
+A => B
\end_layout
\end_inset
- values with correct types.
+ that overrides the composition methods (
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-final case class FuncSeq[X, Y](first: X => Any, funcs: Vector[Any => Any])
- {
+compose
\end_layout
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
\begin_layout Plain Layout
- def append[Z](g: Y => Z): FuncSeq[X, Z] = FuncSeq(first, funcs :+ g.asInstanceO
-f[Any => Any])
+andThen
\end_layout
+\end_inset
+
+).
+ Instead of composing the functions immediately, the new function bodies
+ are added to a sequence of already stored functions.
+ The
+\begin_inset listings
+inline true
+status open
+
\begin_layout Plain Layout
-}
+apply
\end_layout
\end_inset
+ method is the
+\begin_inset Quotes eld
+\end_inset
+
+runner
+\begin_inset Quotes erd
+\end_inset
+ for computing the final result in constant stack space.
\end_layout
\begin_layout Standard
-To ensure stack safety when working with
+To simplify code, we will store functions in a sequence of type
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Vector[Any => Any]
+\end_layout
+
+\end_inset
+
+;; type safety will be guaranteed when constructing values of type
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-FuncSeq
+SafeFunction
\end_layout
\end_inset
-, we implement a tail-recursive function
+.
+ The choice of the
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-runSeq
+Vector
+\end_layout
+
+\end_inset
+
+ container type allows us efficient appending and prepending to the sequence.
+
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+final case class SafeFunction[A, B](funcs: Vector[Any => Any]) extends (A
+ => B) {
+\end_layout
+
+\begin_layout Plain Layout
+
+ def apply(a: A): B = funcs.foldLeft[Any](a){ (prev, func) => func(prev)
+ }.asInstanceOf[B]
+\end_layout
+
+\begin_layout Plain Layout
+
+ override def andThen[C](g: B => C): A => C =
+\end_layout
+
+\begin_layout Plain Layout
+
+ SafeFunction(funcs :+ g.asInstanceOf[Any => Any])
+\end_layout
+
+\begin_layout Plain Layout
+
+ override def compose[C](g: C => A): C => B =
+\end_layout
+
+\begin_layout Plain Layout
+
+ SafeFunction(g.asInstanceOf[Any => Any] +: funcs)
+\end_layout
+
+\begin_layout Plain Layout
+
+}
\end_layout
\end_inset
- that composes all functions stored in the sequence and applies them to
- a given value.
+
\end_layout
\begin_layout Standard
+Converting an ordinary function to a
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+SafeFunction
+\end_layout
+
+\end_inset
+
+ is straightforward:
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
-@tailrec def runSeq[X, Y](x: X, p: FuncSeq[X, Y]): Y = p.funcs.headOption
- match {
+def toSafeFunction[A, B](f: A => B): SafeFunction[A, B] = f match {
+\end_layout
+
+\begin_layout Plain Layout
+
+ case SafeFunction(_) => f.asInstanceOf[SafeFunction[A, B]]
\end_layout
\begin_layout Plain Layout
- case None => p.first(x).asInstanceOf[Y]
+ case _ => SafeFunction(Vector(f.asInstanceOf[Any => Any]))
\end_layout
\begin_layout Plain Layout
- case Some(second) => runSeq(p.first(x), FuncSeq(second, p.funcs.tail))
+}
+\end_layout
+
+\end_inset
+
+For convenience, we also define the corresponding extension methods (
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+safeAndThen
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+safeCompose
+\end_layout
+
+\end_inset
+
+) on ordinary functions:
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+implicit class SafeCompose[A, B](f: A => B) {
+\end_layout
+
+\begin_layout Plain Layout
+
+ def safeAndThen[C](g: B => C): A => C = toSafeFunction(f).andThen(g)
+\end_layout
+
+\begin_layout Plain Layout
+
+ def safeCompose[C](g: C => A): C => B = toSafeFunction(f).compose(g)
\end_layout
\begin_layout Plain Layout
@@ -22780,7 +24351,54 @@ status open
\end_inset
-Now we can write the code of the free functor
+
+\end_layout
+
+\begin_layout Standard
+Millions of functions can be now composed with no stack overflow:
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+def safeComposed(n: Int): Long => Long = (1 to n).foldLeft[Long => Long](x
+ => x){ (prev, i) => prev.safeAndThen(x => x + i) }
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+scala> safeComposed(10000000)(0) // Compose 10 million functions.
+\end_layout
+
+\begin_layout Plain Layout
+
+res1: Long = 50000005000000
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+We use
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+safeAndThen
+\end_layout
+
+\end_inset
+
+ to obtain a stack-safe encoding of the free functor (
\begin_inset listings
inline true
status open
@@ -22792,7 +24410,7 @@ FFS
\end_inset
-:
+) with no changes in the runner:
\begin_inset listings
inline false
status open
@@ -22814,13 +24432,13 @@ sealed trait FFS[F[_], A] {
\begin_layout Plain Layout
-final case class FMap[F[_], X, Y](f: FuncSeq[X, Y], p: F[X]) extends FFS[F,
- Y] {
+final case class FMap[F[_], X, Y](f: X => Y, p: F[X]) extends FFS[F, Y]
+ {
\end_layout
\begin_layout Plain Layout
- def map[Z](g: Y => Z): FFS[F, Z] = FMap[F, X, Z](f append g, p)
+ def map[Z](g: Y => Z): FFS[F, Z] = FMap[F, X, Z](f.safeAndThen(g), p)
\end_layout
\begin_layout Plain Layout
@@ -22835,17 +24453,17 @@ def runFF[F[_], A](runner: Runner[F]): FFS[F, A] => A = {
\begin_layout Plain Layout
- case FMap(f, p) => runSeq(runner.apply(p), f)
+ case FMap(f, p) => f(runner.apply(p))
\end_layout
\begin_layout Plain Layout
-}*** check if this works
+}
\end_layout
\end_inset
-
+Test this code: ***
\end_layout
\begin_layout Subsection
@@ -22862,7 +24480,7 @@ Method
\begin_layout Standard
Tree encoding:
-\begin_inset Formula $\text{FreeCF}^{F^{\bullet},B}\triangleq F^{B}+\exists A.\text{FreeCF}^{F^{\bullet},A}\times\left(B\rightarrow A\right)$
+\begin_inset Formula $\text{FreeCF}^{F,B}\triangleq F^{B}+\exists A.\text{FreeCF}^{F,A}\times\left(B\rightarrow A\right)$
\end_inset
@@ -22870,7 +24488,7 @@ Tree encoding:
\begin_layout Standard
Reduced encoding:
-\begin_inset Formula $\text{FreeCF}^{F^{\bullet},B}\triangleq\exists A.F^{A}\times\left(B\rightarrow A\right)$
+\begin_inset Formula $\text{FreeCF}^{F,B}\triangleq\exists A.F^{A}\times\left(B\rightarrow A\right)$
\end_inset
@@ -22878,7 +24496,7 @@ Reduced encoding:
\begin_layout Standard
A value of type
-\begin_inset Formula $\text{FreeCF}^{F^{\bullet},B}$
+\begin_inset Formula $\text{FreeCF}^{F,B}$
\end_inset
must be of the form
@@ -22956,11 +24574,11 @@ def prefixLog[A](p: A): A
\begin_layout Standard
If
-\begin_inset Formula $F^{\bullet}$
+\begin_inset Formula $F$
\end_inset
is already a contrafunctor then
-\begin_inset Formula $\text{FreeCF}^{F^{\bullet},A}\cong F^{A}$
+\begin_inset Formula $\text{FreeCF}^{F,A}\cong F^{A}$
\end_inset
@@ -23816,11 +25434,7 @@ noprefix "false"
\end_inset
-), consider a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass called
+), consider an FM-typeclass called
\begin_inset listings
inline true
status open
@@ -24065,11 +25679,8 @@ TC
\end_inset
parametrically.
- We expect that similar code will work for any other
-\begin_inset Formula $P$
-\end_inset
-
--typeclass to define a free instance.
+ We expect that similar code will work for any other FM-typeclass to define
+ a free instance.
To see that more clearly, rewrite the type signature of the function
\begin_inset listings
inline true
@@ -24136,11 +25747,7 @@ TC
\end_inset
- to an arbitrary
-\begin_inset Formula $P$
-\end_inset
-
--typeclass, replacing the type
+ to an arbitrary FM-typeclass, replacing the type
\begin_inset Formula $\text{TC}^{A}$
\end_inset
@@ -24148,16 +25755,8 @@ TC
\begin_inset Formula $P^{A}\rightarrow A$
\end_inset
- that describes all the methods of the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass.
- Then the free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass instance constructor is given by:
+ that describes all the methods of the FM-typeclass.
+ Then the free FM-typeclass instance constructor is given by:
\begin_inset Formula
\[
\forall A.\,(T\rightarrow A)\rightarrow(P^{A}\rightarrow A)\rightarrow A\quad.
@@ -24187,24 +25786,13 @@ This type can be rewritten as
\end_inset
.
- Indeed, we know from the theory of
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses that the free monad on
-\begin_inset Formula $P$
-\end_inset
-
- gives the raw tree encoding of the free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass.
- If the
+ Indeed, we know from the theory of FM-typeclasses that the free monad on
+
\begin_inset Formula $P$
\end_inset
--typeclass has no laws then this is the only available encoding.
+ gives the raw tree encoding of the free FM-typeclass.
+ If the FM-typeclass has no laws then this is the only available encoding.
\end_layout
\begin_layout Standard
@@ -24608,11 +26196,8 @@ What happens if we apply the same technique to a typeclass that is
\emph on
not
\emph default
- of the form of a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass? As it turns out, the construction no longer works as expected.
+ of the form of an FM-typeclass? As it turns out, the construction no longer
+ works as expected.
An example is the
\begin_inset listings
inline true
@@ -24873,20 +26458,12 @@ This chapter started by developing the free monad via the implementation
Can we formulate any properties or laws that validate the correctness of
those constructions? Are all the different encodings equally safe to use?
We will now develop the necessary theory for answering these questions
- in the case of
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses for ordinary types.
+ in the case of FM-typeclasses for ordinary types.
(The notion of a
\begin_inset Quotes eld
\end_inset
-
-\begin_inset Formula $P$
-\end_inset
-
--typeclass
+FM-typeclass
\begin_inset Quotes erd
\end_inset
@@ -24904,11 +26481,7 @@ noprefix "false"
\end_inset
-.) We expect that
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses for type constructors (such as
+.) We expect that FM-typeclasses for type constructors (such as
\begin_inset listings
inline true
status open
@@ -24937,11 +26510,7 @@ Monad
\end_layout
\begin_layout Subsection
-Free constructions for
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses
+Free constructions for FM-typeclasses
\begin_inset CommandInset label
LatexCommand label
name "subsec:Free-constructions-for-inductive-typeclasses"
@@ -24958,24 +26527,20 @@ Some features are common to all the free typeclass constructions we have
generalize what we have learned about specific typeclasses (free monads,
free monoids, etc.) to an arbitrary typeclass.
We will use the encodings of the free monoid as the starting point and
- generalize to encodings of an arbitrary free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass.
+ generalize to encodings of an arbitrary free FM-typeclass.
\end_layout
\begin_layout Standard
-The free monoid is a type constructor (denoted by
-\begin_inset Quotes eld
-\end_inset
-
+The free monoid is a type constructor (which turns out to be
+\begin_inset listings
+inline true
+status open
-\begin_inset Formula $\text{FM}$
-\end_inset
+\begin_layout Plain Layout
+List
+\end_layout
-\begin_inset Quotes erd
\end_inset
) that transforms an arbitrary type
@@ -24983,7 +26548,7 @@ The free monoid is a type constructor (denoted by
\end_inset
into a new type (
-\begin_inset Formula $\text{FM}^{T}$
+\begin_inset Formula $\text{List}^{T}$
\end_inset
) having a
@@ -25004,7 +26569,7 @@ Monoid
\end_inset
can be wrapped into values of type
-\begin_inset Formula $\text{FM}^{T}$
+\begin_inset Formula $\text{List}^{T}$
\end_inset
.
@@ -25025,7 +26590,7 @@ free monoid program
\end_inset
(i.e., a value of type
-\begin_inset Formula $\text{FM}^{T}$
+\begin_inset Formula $\text{List}^{T}$
\end_inset
) can be
@@ -25042,11 +26607,11 @@ run into
.
The resulting runner (of type
-\begin_inset Formula $\text{FM}^{T}\rightarrow M$
+\begin_inset Formula $\text{List}^{T}\rightarrow M$
\end_inset
) will preserve the monoid operations between
-\begin_inset Formula $\text{FM}^{T}$
+\begin_inset Formula $\text{List}^{T}$
\end_inset
and
@@ -25063,7 +26628,7 @@ free monoid program
\end_inset
, even when the chosen encoding
-\begin_inset Formula $\text{FM}^{T}$
+\begin_inset Formula $\text{List}^{T}$
\end_inset
violates some of the monoid laws.
@@ -25071,11 +26636,7 @@ free monoid program
\begin_layout Standard
To generalize from monoids to other typeclasses, recall the definition of
- a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass (Section
+ an FM-typeclass (Section
\begin_inset space ~
\end_inset
@@ -25093,23 +26654,16 @@ noprefix "false"
\begin_inset Formula $P$
\end_inset
-, a
-\begin_inset Formula $P$
-\end_inset
-
-
+, an FM-
\series bold
--typeclass
+typeclass
\series default
\begin_inset Index idx
status open
\begin_layout Plain Layout
-\begin_inset Formula $P$
-\end_inset
-
--typeclass
+FM-typeclass
\end_layout
\end_inset
@@ -25161,12 +26715,8 @@ arguments
\end_inset
).
- So, we imagine that the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass combines all methods of a typeclass into a single value (of type
-
+ So, we imagine that the FM-typeclass combines all methods of a typeclass
+ into a single value (of type
\begin_inset Formula $P^{A}\rightarrow A$
\end_inset
@@ -25182,11 +26732,7 @@ preserving the monoid's operations
\begin_inset Quotes erd
\end_inset
- to an arbitrary
-\begin_inset Formula $P$
-\end_inset
-
--typeclass.
+ to an arbitrary FM-typeclass.
Given two monoids
\begin_inset Formula $M$
\end_inset
@@ -25429,11 +26975,7 @@ preserving the typeclass operations
\begin_inset Quotes erd
\end_inset
- for an arbitrary
-\begin_inset Formula $P$
-\end_inset
-
--typeclass: we just need to impose Eq.
+ for an arbitrary FM-typeclass: we just need to impose Eq.
\begin_inset space ~
\end_inset
@@ -25879,11 +27421,8 @@ F\text{-algebra morphism law for }h^{:L\rightarrow M}:\quad & =\gunderline{g^{\u
\end_layout
\begin_layout Standard
-We can now formulate our findings about
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses in the language of
+We can now formulate our findings about FM-typeclasses in the language of
+
\begin_inset Formula $P$
\end_inset
@@ -25896,23 +27435,16 @@ We can now formulate our findings about
\end_inset
).
- We say that a
-\begin_inset Formula $P$
-\end_inset
-
-
+ We say that an FM-
\series bold
--typeclass with laws
+typeclass with laws
\series default
is
\begin_inset Index idx
status open
\begin_layout Plain Layout
-\begin_inset Formula $P$
-\end_inset
-
--typeclass!with laws
+FM-typeclass!with laws
\end_layout
\end_inset
@@ -25935,11 +27467,7 @@ evidence value
\begin_inset Formula $M$
\end_inset
- belongs to the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass.
+ belongs to the FM-typeclass.
If
\begin_inset Formula $M$
\end_inset
@@ -25968,11 +27496,7 @@ evidence value
\begin_inset Quotes eld
\end_inset
-preserves the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass operations
+preserves the FM-typeclass operations
\begin_inset Quotes erd
\end_inset
@@ -25985,11 +27509,7 @@ The next step is to generalize the free monoid construction to a
\begin_inset Quotes eld
\end_inset
-free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass
+free FM-typeclass
\begin_inset Quotes erd
\end_inset
@@ -26013,11 +27533,7 @@ encoding
\begin_inset Quotes erd
\end_inset
- of a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass:
+ of a free FM-typeclass:
\end_layout
\begin_layout Itemize
@@ -26029,16 +27545,9 @@ We expect to have a type constructor
\begin_inset Formula $T$
\end_inset
- and produces a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass instance automatically.
- (However, that
-\begin_inset Formula $P$
-\end_inset
-
--typeclass instance may not obey all of the typeclass laws.)
+ and produces an FM-typeclass instance automatically.
+ (However, that FM-typeclass instance may not obey all of the typeclass
+ laws.)
\end_layout
\begin_layout Itemize
@@ -26067,11 +27576,7 @@ Values of type
\begin_inset Quotes eld
\end_inset
-
-\begin_inset Formula $P$
-\end_inset
-
--typeclass programs
+FM-typeclass programs
\begin_inset Quotes erd
\end_inset
@@ -26101,11 +27606,7 @@ runner
\begin_inset Formula $C$
\end_inset
- must be an instance of the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass.
+ must be an instance of the FM-typeclass.
The
\begin_inset Quotes eld
\end_inset
@@ -26206,11 +27707,8 @@ So, we require that a function of type
\end_layout
\begin_layout Standard
-We now define a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding by making these expectations precise:
+We now define a free FM-typeclass encoding by making these expectations
+ precise:
\end_layout
\begin_layout Subsubsection
@@ -26235,7 +27733,7 @@ noprefix "false"
\end_layout
\begin_layout Standard
-Given a functor
+Given a structure functor
\begin_inset Formula $P$
\end_inset
@@ -26243,13 +27741,9 @@ Given a functor
\series bold
free
\series default
-
-\begin_inset Formula $P$
-\end_inset
-
-
+ FM-
\series bold
--typeclass
+typeclass
\series default
\series bold
@@ -26337,17 +27831,9 @@ noprefix "false"
\begin_inset Formula $T$
\end_inset
- may obey some (or none) of the laws of the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass.
+ may obey some (or none) of the laws of the FM-typeclass.
There is only a finite number of typeclass laws; so we may consider the
- largest subset of the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws obeyed by
+ largest subset of the FM-typeclass laws obeyed by
\begin_inset Formula $p_{E}^{T}$
\end_inset
@@ -26474,11 +27960,7 @@ evaluator
\begin_inset Formula $p_{C}:P^{C}\rightarrow C$
\end_inset
- obeys all the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws assured by
+ obeys all the FM-typeclass laws assured by
\begin_inset Formula $E$
\end_inset
@@ -26540,12 +28022,8 @@ all
\begin_inset Formula $E$
\end_inset
- means that if a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass law (such as an identity law, an associativity law, etc.) is satisfied
- by
+ means that if an FM-typeclass law (such as an identity law, an associativity
+ law, etc.) is satisfied by
\begin_inset Formula $E^{T}$
\end_inset
@@ -26585,12 +28063,8 @@ noprefix "false"
\end_inset
- will describe
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws in more detail, but we do not yet need the techniques developed
- there.)
+ will describe FM-typeclass laws in more detail, but we do not yet need
+ the techniques developed there.)
\end_layout
\begin_layout Standard
@@ -26628,16 +28102,10 @@ noprefix "false"
\begin_layout Standard
The uniqueness property of the evaluator reflects a programmer's expectation
- that there is only one correct way of running (i.e., evaluating) a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass program while preserving the typeclass's operations.
- However, in practice we need to evaluate not only
-\begin_inset Formula $P$
-\end_inset
-
--typeclass programs of type
+ that there is only one correct way of running (i.e., evaluating) a free FM-typecl
+ass program while preserving the typeclass's operations.
+ However, in practice we need to evaluate not only FM-typeclass programs
+ of type
\begin_inset Formula $E^{C}$
\end_inset
@@ -26650,15 +28118,8 @@ The uniqueness property of the evaluator reflects a programmer's expectation
\end_inset
-algebra and already belongs to the typeclass.
- The usefulness of a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass construction is in supporting
-\begin_inset Formula $P$
-\end_inset
-
--typeclass programs of type
+ The usefulness of a free FM-typeclass construction is in supporting FM-typeclas
+s programs of type
\begin_inset Formula $E^{T}$
\end_inset
@@ -26741,11 +28202,7 @@ universal runner
\begin_inset Quotes erd
\end_inset
- will evaluate a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass program of type
+ will evaluate a free FM-typeclass program of type
\begin_inset Formula $E^{T}$
\end_inset
@@ -26794,11 +28251,7 @@ Suppose
\begin_inset Formula $E$
\end_inset
- is a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding,
+ is a free FM-typeclass encoding,
\begin_inset Formula $C$
\end_inset
@@ -27063,11 +28516,7 @@ noprefix "false"
\end_layout
\begin_layout Standard
-It is important that the definition of a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding
+It is important that the definition of a free FM-typeclass encoding
\begin_inset Formula $E$
\end_inset
@@ -27079,11 +28528,7 @@ It is important that the definition of a free
\emph on
all
\emph default
- of the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws.
+ of the FM-typeclass laws.
For instance, we have seen that the raw tree encoding of free monads, free
monoids, and other typeclasses does not obey any of the relevant laws.
Because this does
@@ -27094,11 +28539,7 @@ not
\begin_inset Quotes eld
\end_inset
-free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encodings
+free FM-typeclass encodings
\begin_inset Quotes erd
\end_inset
@@ -27119,30 +28560,19 @@ Monoid
\end_inset
- to an arbitrary
-\begin_inset Formula $P$
-\end_inset
-
--typeclass and to show that it satisfies the definition of a
+ to an arbitrary FM-typeclass and to show that it satisfies the definition
+ of a
\begin_inset Quotes eld
\end_inset
-free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding
+free FM-typeclass encoding
\begin_inset Quotes erd
\end_inset
.
Although the raw tree encoding does not satisfy any typeclass laws, it
gives us a valid and usable encoding that we can use as a starting point
- to develop other, more concise encodings for a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass.
+ to develop other, more concise encodings for a free FM-typeclass.
\end_layout
@@ -27193,15 +28623,8 @@ The parts of the disjunctive type
\end_inset
.
- We can now generalize to arbitrary
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses and define the raw tree encoding of a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass (denoted by
+ We can now generalize to arbitrary FM-typeclasses and define the raw tree
+ encoding of a free FM-typeclass (denoted by
\begin_inset Formula $\text{FPR}^{T}$
\end_inset
@@ -27298,11 +28721,7 @@ The free monad on
\begin_inset Formula $\text{FPR}^{T}\triangleq T+P^{\text{FPR}^{T}}$
\end_inset
-, is a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding.
+, is a free FM-typeclass encoding.
The monad's
\begin_inset listings
inline true
@@ -27758,11 +29177,7 @@ The two code matrices are now equal due to the assumed law
\begin_inset Formula $C$
\end_inset
- with
-\begin_inset Formula $P$
-\end_inset
-
--typeclass instance
+ with FM-typeclass instance
\begin_inset Formula $p_{C}:P^{C}\rightarrow C$
\end_inset
@@ -27906,17 +29321,9 @@ flatten
\begin_inset Formula $P$
\end_inset
--algebra morphism; in other words, it preserves the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass operations.
- So, it is not useful to apply the free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass construction twice, as the result can be reduced to a single
- layer of
+-algebra morphism; in other words, it preserves the FM-typeclass operations.
+ So, it is not useful to apply the free FM-typeclass construction twice,
+ as the result can be reduced to a single layer of
\begin_inset listings
inline true
status open
@@ -28063,11 +29470,7 @@ It is not accidental that the raw tree encoding (
\emph on
all
\emph default
- free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encodings are monads (although not necessarily free monads):
+ free FM-typeclass encodings are monads (although not necessarily free monads):
\end_layout
\begin_layout Subsubsection
@@ -28092,11 +29495,7 @@ noprefix "false"
\end_layout
\begin_layout Standard
-Any free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding
+Any free FM-typeclass encoding
\begin_inset Formula $E$
\end_inset
@@ -28518,11 +29917,7 @@ noprefix "false"
\end_layout
\begin_layout Subsection
-Describing laws of
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses as values
+Describing laws of FM-typeclasses as values
\begin_inset CommandInset label
LatexCommand label
name "subsec:Describing-laws-of-P-typeclasses-as-values"
@@ -28542,11 +29937,8 @@ first-class
\begin_inset Quotes erd
\end_inset
- description of
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws: each law will be represented by a value of a certain type.
+ description of FM-typeclass laws: each law will be represented by a value
+ of a certain type.
To make sure we have really found a representation that adequately captures
our understanding of what typeclass laws are, we will show three type formulas
for the laws, arriving at them via different motivations.
@@ -28684,11 +30076,8 @@ Monoid
\end_inset
will be different.
- To generalize to arbitrary
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses, let us express the laws as much as possible through
+ To generalize to arbitrary FM-typeclasses, let us express the laws as much
+ as possible through
\begin_inset Formula $P$
\end_inset
@@ -28824,16 +30213,8 @@ Monoid
\end_inset
- laws to other
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses.
- A
-\begin_inset Formula $P$
-\end_inset
-
--typeclass may impose zero or more laws.
+ laws to other FM-typeclasses.
+ An FM-typeclass may impose zero or more laws.
Each law is represented by a function of type
\begin_inset Formula $\text{LawF}_{P}$
\end_inset
@@ -28910,11 +30291,8 @@ Laws as expression trees
\begin_layout Standard
Another approach to describing typeclass laws is by viewing the two sides
of a law as expression trees.
- Recall that the raw tree encoding of a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass (which we denoted by
+ Recall that the raw tree encoding of a free FM-typeclass (which we denoted
+ by
\begin_inset Formula $\text{FPR}^{T}$
\end_inset
@@ -29299,11 +30677,7 @@ Monoid
\end_inset
- to an arbitrary
-\begin_inset Formula $P$
-\end_inset
-
--typeclass.
+ to an arbitrary FM-typeclass.
The two sides of the law are functions that take as arguments one or more
arbitrary values of type
\begin_inset Formula $T$
@@ -29378,11 +30752,7 @@ et: LawET
\begin_inset Formula $T$
\end_inset
- with
-\begin_inset Formula $P$
-\end_inset
-
--typeclass evidence value
+ with FM-typeclass evidence value
\begin_inset Formula $p_{T}:P^{T}\rightarrow T$
\end_inset
@@ -29835,11 +31205,7 @@ FMR[Int]
\end_layout
\begin_layout Standard
-Generalizing this to arbitrary
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses, we obtain the type
+Generalizing this to arbitrary FM-typeclasses, we obtain the type
\begin_inset Formula $\text{FPR}^{\text{Int}}\times\text{FPR}^{\text{Int}}$
\end_inset
@@ -30172,11 +31538,7 @@ LawET
\end_layout
\begin_layout Standard
-It turns out that laws of a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass are closely connected with
+It turns out that laws of an FM-typeclass are closely connected with
\begin_inset Formula $P$
\end_inset
@@ -30281,11 +31643,7 @@ preserve
\begin_inset Quotes erd
\end_inset
- the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws.
+ the FM-typeclass laws.
\end_layout
\begin_layout Standard
@@ -30346,11 +31704,7 @@ hides
\begin_inset Quotes erd
\end_inset
- violations of the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws.
+ violations of the FM-typeclass laws.
\end_layout
\begin_layout Subparagraph
@@ -30607,11 +31961,7 @@ noprefix "false"
\end_inset
.
- Now we see that this is a general property that applies to all
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses.
+ Now we see that this is a general property that applies to all FM-typeclasses.
It is safe to use a free typeclass encoding (even if it violates some laws)
as long as its runner preserves the typeclass operations and the target
type is a lawful typeclass member.
@@ -30627,11 +31977,7 @@ partially lawful
\end_layout
\begin_layout Subsection
-Free
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses that satisfy a subset of the laws
+Free FM-typeclasses that satisfy a subset of the laws
\begin_inset CommandInset label
LatexCommand label
name "subsec:Free--typeclasses-that-satisfy-laws"
@@ -30720,25 +32066,15 @@ noprefix "false"
\end_inset
, although they obey different subsets of the laws of monoids.
- We will now generalize that situation to
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses and study the properties of free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass constructions that satisfy only a subset of the typeclass's laws.
+ We will now generalize that situation to FM-typeclasses and study the propertie
+s of free FM-typeclass constructions that satisfy only a subset of the typeclass
+'s laws.
The resulting theory will make it simpler to prove that a given type constructo
r
\begin_inset Formula $E$
\end_inset
- is indeed a valid free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding as specified by Definition
+ is indeed a valid free FM-typeclass encoding as specified by Definition
\begin_inset space ~
\end_inset
@@ -31043,11 +32379,7 @@ Let
\begin_inset Formula $E$
\end_inset
- be any free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding.
+ be any free FM-typeclass encoding.
\end_layout
\begin_layout Standard
@@ -31071,11 +32403,7 @@ Let
\begin_inset Formula $E^{U}$
\end_inset
- obeys all the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws that
+ obeys all the FM-typeclass laws that
\begin_inset Formula $E^{T}$
\end_inset
@@ -31120,11 +32448,7 @@ smaller
\begin_inset Formula $E^{\text{Int}\times\text{Int}}$
\end_inset
- obeys some law of the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass then
+ obeys some law of the FM-typeclass then
\begin_inset Formula $E^{T}$
\end_inset
@@ -31148,11 +32472,7 @@ smaller
\begin_inset Formula $E^{\text{Int}}$
\end_inset
- obeys some law of the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass then
+ obeys some law of the FM-typeclass then
\begin_inset Formula $E^{T}$
\end_inset
@@ -31280,11 +32600,7 @@ noprefix "false"
\begin_inset Formula $E^{U}$
\end_inset
- obeys all the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws that
+ obeys all the FM-typeclass laws that
\begin_inset Formula $E^{T}$
\end_inset
@@ -31642,12 +32958,8 @@ The restriction to polynomial functors
\end_inset
is not a limitation in practice.
- All known
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses have only a finite set of operations, and each operation has
- a fixed and finite number of arguments.
+ All known FM-typeclasses have only a finite set of operations, and each
+ operation has a fixed and finite number of arguments.
The functor
\begin_inset Formula $P$
\end_inset
@@ -31665,12 +32977,8 @@ The next statement shows that a functor
\begin_inset Formula $E$
\end_inset
- is a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding if it has an injective map into the raw tree encoding
- (
+ is a free FM-typeclass encoding if it has an injective map into the raw
+ tree encoding (
\begin_inset listings
inline true
status open
@@ -31683,11 +32991,8 @@ FPR
\end_inset
) and has certain additional properties.
- This statement helps us validate free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encodings with less work than by using Definition
+ This statement helps us validate free FM-typeclass encodings with less
+ work than by using Definition
\begin_inset space ~
\end_inset
@@ -31890,11 +33195,7 @@ smaller
\begin_inset Formula $E^{T}$
\end_inset
- satisfies some (or all) of the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws but
+ satisfies some (or all) of the FM-typeclass laws but
\emph on
no other
\emph default
@@ -31917,11 +33218,7 @@ no other
\begin_inset Formula $e:\text{FPR}^{\text{Int}}\times\text{FPR}^{\text{Int}}$
\end_inset
- for describing
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws (see Section
+ for describing FM-typeclass laws (see Section
\begin_inset space ~
\end_inset
@@ -31944,11 +33241,7 @@ noprefix "false"
\begin_inset Quotes eld
\end_inset
-no other laws than those of the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass
+no other laws than those of the FM-typeclass
\begin_inset Quotes erd
\end_inset
@@ -31960,11 +33253,7 @@ no other laws than those of the
\begin_inset Formula $C$
\end_inset
- that obeys all the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws and for any
+ that obeys all the FM-typeclass laws and for any
\begin_inset Formula $e:\text{FPR}^{\text{Int}}\times\text{FPR}^{\text{Int}}$
\end_inset
@@ -32034,11 +33323,7 @@ If assumptions 1-5 hold then:
\begin_inset Formula $E$
\end_inset
- is a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding.
+ is a free FM-typeclass encoding.
When the function
\begin_inset Formula $\text{in}_{E}$
\end_inset
@@ -32081,11 +33366,7 @@ not
\end_inset
-algebra morphism.
- Then we are able to describe free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encodings
+ Then we are able to describe free FM-typeclass encodings
\begin_inset Formula $E$
\end_inset
@@ -32294,11 +33575,8 @@ We find that we must have
\emph on
isomorphism
\emph default
- (a type equivalence that preserves the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass operations) between
+ (a type equivalence that preserves the FM-typeclass operations) between
+
\begin_inset Formula $E^{T}$
\end_inset
@@ -32331,11 +33609,7 @@ To show that
\begin_inset Formula $E$
\end_inset
- is a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding, we look at the conditions in Definition
+ is an FM-typeclass encoding, we look at the conditions in Definition
\begin_inset space ~
\end_inset
@@ -32379,11 +33653,7 @@ To verify condition (c), we assume that
\begin_inset Formula $P$
\end_inset
--algebra that obeys all the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws that
+-algebra that obeys all the FM-typeclass laws that
\begin_inset Formula $E$
\end_inset
@@ -32978,11 +34248,7 @@ noprefix "false"
\end_layout
\begin_layout Subsection
-Imposing laws of
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses via monad algebras
+Imposing laws of FM-typeclasses via monad algebras
\begin_inset CommandInset label
LatexCommand label
name "subsec:Imposing-laws-of-P-typeclasses-via-monad-algebras"
@@ -33007,11 +34273,7 @@ noprefix "false"
\end_inset
- that any free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding
+ that any free FM-typeclass encoding
\begin_inset Formula $E$
\end_inset
@@ -33020,11 +34282,7 @@ noprefix "false"
\begin_inset Formula $E$
\end_inset
-'s monad methods to impose
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws on a given
+'s monad methods to impose FM-typeclass laws on a given
\begin_inset Formula $P$
\end_inset
@@ -33147,6 +34405,11 @@ The monad algebra's laws require a certain kind of compatibility between
's methods.
\end_layout
+\begin_layout Standard
+*** How does a monad algebra impose laws? How to write a law as explicit
+ equation, given E? give examples.
+\end_layout
+
\begin_layout Standard
Note that for any monad
\begin_inset Formula $E$
@@ -33231,7 +34494,7 @@ flatten
\end_layout
\begin_layout Standard
-When any type
+When
\begin_inset Formula $E^{T}$
\end_inset
@@ -33239,7 +34502,11 @@ When any type
\begin_inset Formula $P$
\end_inset
--functor algebra, we have a special relationship between
+-functor algebra for all
+\begin_inset Formula $T$
+\end_inset
+
+ then one can derive a special relationship between
\begin_inset Formula $E$
\end_inset
@@ -33280,11 +34547,7 @@ Suppose
\begin_inset Formula $E$
\end_inset
- is a free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding according to Definition
+ is a free FM-typeclass encoding according to Definition
\begin_inset space ~
\end_inset
@@ -33355,7 +34618,11 @@ noprefix "false"
\begin_inset Formula $P$
\end_inset
--algebra.
+-algebra that obeys all the laws assured by
+\begin_inset Formula $E$
+\end_inset
+
+.
The structure map
\begin_inset Formula $s:E^{C}\rightarrow C$
\end_inset
@@ -33393,7 +34660,7 @@ noprefix "false"
\begin_inset Formula $C$
\end_inset
- that satisfies the laws assured by
+ that satisfies all the laws assured by
\begin_inset Formula $E$
\end_inset
@@ -33409,15 +34676,23 @@ noprefix "false"
\series bold
(c)
\series default
- The
+ Items
+\series bold
+(a)
+\series default
+ and
+\series bold
+(b)
+\series default
+ give a a 1-to-1 correspondence between
\begin_inset Formula $P$
\end_inset
--algebras and the
+-algebras and
\begin_inset Formula $E$
\end_inset
--monad algebras are in a 1-to-1 correspondence.
+-monad algebras.
\end_layout
\begin_layout Subparagraph
@@ -33492,6 +34767,10 @@ P\text{-algebra morphism law~(\ref{eq:P-algebra-morphism-law-of-flatten}) of }\t
\end_inset
+
+\end_layout
+
+\begin_layout Standard
The
\family roman
\series medium
@@ -33531,10 +34810,7 @@ The
\end_inset
is surjective.
-\end_layout
-
-\begin_layout Standard
-By Statement
+ By Statement
\begin_inset space ~
\end_inset
@@ -33623,7 +34899,7 @@ We note that this part of the proof does not use the uniqueness property
\begin_inset Formula $s:E^{C}\rightarrow C$
\end_inset
- by:
+ by:***rewrite this proof using eval instead of run:
\begin_inset Formula
\[
s:E^{C}\rightarrow C\quad,\quad\quad s\triangleq\text{eval}_{E}^{C}\quad.
@@ -33986,11 +35262,7 @@ Let
\begin_inset Formula $E$
\end_inset
- be any free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding by Definition
+ be any free FM-typeclass encoding by Definition
\begin_inset space ~
\end_inset
@@ -34186,11 +35458,7 @@ In the next section, we will use monad algebras to prove that certain typeclass
\end_layout
\begin_layout Subsection
-Laws for the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass derivation constructions
+Laws for the FM-typeclass derivation constructions
\begin_inset CommandInset label
LatexCommand label
name "subsec:Laws-for-the-P-typeclass-constructions"
@@ -34217,16 +35485,10 @@ noprefix "false"
we have shown certain type constructions that derive new typeclass instances
from previous ones.
- For example, the product of two types that belong to a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass will again belong to that typeclass.
- However, in that chapter we only showed that one can compute a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass evidence values for those constructions.
+ For example, the product of two types that belong to an FM-typeclass will
+ again belong to that typeclass.
+ However, in that chapter we only showed that one can compute an FM-typeclass
+ evidence values for those constructions.
Now we have developed a theory that can also prove that the laws hold automatic
ally for each of those constructions.
This theory justifies automatic typeclass derivation for those cases.
@@ -34246,11 +35508,7 @@ Instead of dealing with laws explicitly as values, it is more convenient
\begin_inset Formula $T$
\end_inset
- is a lawful member of a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass if
+ is a lawful member of an FM-typeclass if
\begin_inset Formula $T$
\end_inset
@@ -34262,11 +35520,7 @@ Instead of dealing with laws explicitly as values, it is more convenient
\begin_inset Formula $E$
\end_inset
- is the free
-\begin_inset Formula $P$
-\end_inset
-
--typeclass encoding that assures the laws of the typeclass.
+ is the free FM-typeclass encoding that assures the laws of the typeclass.
Using this formulation of laws, it is sufficient to prove that a new derived
type is again an
\begin_inset Formula $E$
@@ -34929,11 +36183,7 @@ Unlike the proof in part
\end_layout
\begin_layout Subsection
-Church encodings of free
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses
+Church encodings of free FM-typeclasses
\begin_inset CommandInset label
LatexCommand label
name "subsec:Church-encodings-for-free-P-typeclasses"
@@ -36813,11 +38063,7 @@ call
\series bold
structure functor
\series default
- of the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass
+ of the FM-typeclass
\begin_inset Formula $C$
\end_inset
@@ -38902,11 +40148,7 @@ acts
\begin_inset Formula $\text{Mod}_{L}$
\end_inset
- is a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass.
+ is an FM-typeclass.
Implement a free
\begin_inset Formula $L$
\end_inset
diff --git a/sofp-src/lyx/sofp-monads.lyx b/sofp-src/lyx/sofp-monads.lyx
index 6b52ddddc..e4d47ab61 100644
--- a/sofp-src/lyx/sofp-monads.lyx
+++ b/sofp-src/lyx/sofp-monads.lyx
@@ -380,7 +380,8 @@ flatMap
\end_inset
method.
- This chapter begins by developing an intuition for the behavior of
+ This chapter begins by developing a motivation and an intuition for the
+ use of
\begin_inset listings
inline true
status open
@@ -604,7 +605,7 @@ flatten
\end_inset
-, and its combination with
+, and its composition with
\begin_inset listings
inline true
status open
@@ -616,7 +617,7 @@ map
\end_inset
- can be replaced by
+ is known as
\begin_inset listings
inline true
status open
@@ -10340,8 +10341,9 @@ flatMap
\end_inset
- method can be supported by many other type constructors useful for various
- programming tasks not necessarily related to nested iteration.
+ method is supported by many other type constructors (not just containers)
+ and may be used for various programming tasks not necessarily related to
+ nested iteration.
\end_layout
\begin_layout Standard
@@ -10358,7 +10360,7 @@ A general (semi)monad type constructor
\begin_inset Formula $A$
\end_inset
- wrapped in a special
+ wrapped in type constructor representing a special
\begin_inset Quotes eld
\end_inset
@@ -10367,7 +10369,7 @@ computational effect
\end_inset
.
- We view
+ By
\begin_inset Quotes eld
\end_inset
@@ -10379,7 +10381,7 @@ computations with an
\begin_inset Quotes erd
\end_inset
- as functions of type
+ we simply mean functions of type
\begin_inset Formula $A\rightarrow L^{B}$
\end_inset
@@ -10398,29 +10400,6 @@ flatMap
's argument type).
In this view, different monads — such as list-like, pass/fail, or tree-like
— implement different kinds of effects.
-
-\begin_inset Note Note
-status open
-
-\begin_layout Plain Layout
-An ordinary function of type
-\begin_inset Formula $A\rightarrow B$
-\end_inset
-
- is a computation with a
-\begin_inset Quotes eld
-\end_inset
-
-trivial effect
-\begin_inset Quotes erd
-\end_inset
-
-.
-\end_layout
-
-\end_inset
-
-
\end_layout
\begin_layout Standard
@@ -10474,7 +10453,7 @@ value-like behavior
\begin_inset Quotes erd
\end_inset
- describes the information computed by a function of type
+ describes whatever else is computed by a function of type
\begin_inset Formula $A\rightarrow L^{B}$
\end_inset
@@ -10634,7 +10613,7 @@ which has the form
\end_inset
if we define
-\begin_inset Formula $L^{A}\triangleq Z\rightarrow A$
+\begin_inset Formula $L^{B}\triangleq Z\rightarrow B$
\end_inset
.
@@ -12370,8 +12349,12 @@ Logs
\end_inset
- is not a monoid because its binary operation discards some of the input
- data, so we cannot define an
+ is
+\emph on
+not
+\emph default
+ a monoid because its binary operation discards some of the input data,
+ so we cannot define an
\begin_inset Quotes eld
\end_inset
@@ -13441,11 +13424,11 @@ Eval
status open
\begin_layout Plain Layout
-monads!lazy/eager evaluation monad (
+monads!
\family typewriter
Eval
\family default
-)
+ (lazy/eager evaluation monad)
\end_layout
\end_inset
@@ -21442,7 +21425,11 @@ empty effect
\end_inset
, such that merging the empty effect leaves other effects unchanged.
- A monad
+ A
+\series bold
+monad
+\series default
+
\begin_inset Formula $M$
\end_inset
@@ -21530,7 +21517,7 @@ def pure[A](a: A): M[A]
\end_layout
\begin_layout Standard
-To get intuition about the properties of a vaguely defined
+To get intuition about the behavior of what we called an
\begin_inset Quotes eld
\end_inset
@@ -21538,7 +21525,7 @@ empty effect
\begin_inset Quotes erd
\end_inset
-, consider nested iteration over arrays.
+, consider nested iteration over lists.
The
\begin_inset Quotes eld
\end_inset
@@ -21547,33 +21534,35 @@ empty effect
\begin_inset Quotes erd
\end_inset
- is an array containing
+ should correspond to trivial iterations; that is, an iteration through
+ a list containing
\emph on
one
\emph default
element.
- An iteration over such an array will just need to process that single value.
- In a functor block using arrays, a source line with an
-\begin_inset Quotes eld
-\end_inset
+
+\begin_inset Note Note
+status collapsed
+
+\begin_layout Plain Layout
+An iteration over such a list will just need to process that one element.
+\end_layout
-empty effect
-\begin_inset Quotes erd
\end_inset
- (
+ Indeed, in a functor block using lists, a source line
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-y <- pure(x)
+y <- List(x)
\end_layout
\end_inset
-) will be equivalent to just
+ is equivalent to just
\begin_inset listings
inline true
status open
@@ -21585,10 +21574,27 @@ y = x
\end_inset
- with no iteration.
+ with no extra iterations.
+\end_layout
+
+\begin_layout Standard
+To understand the properties of empty effects more formally, consider a
+ functor block with a source line
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+y <- pure(x)
+\end_layout
+
+\end_inset
+
+.
That line may occur either before or after another source line.
- So, we need to examine two situations: first, when an empty effect comes
- before another source line:
+ When an empty effect comes before another source line, the code can be
+ simplified like this:
\end_layout
\begin_layout Standard
@@ -22114,7 +22120,7 @@ noprefix "false"
\end_inset
).
- So, we could say that a monad is a pointed semi-monad whose
+ So, a monad is a pointed semi-monad whose
\begin_inset listings
inline true
status open
@@ -22230,7 +22236,7 @@ noprefix "false"
\end_inset
).
- A full monad's
+ For the same reason, a monad's
\begin_inset listings
inline true
status open
@@ -22242,8 +22248,8 @@ pure
\end_inset
- method must also satisfy that naturality law, in addition to the two identity
- laws.
+ method must also satisfy that naturality law (in addition to the two identity
+ laws).
\end_layout
\begin_layout Standard
@@ -22284,6 +22290,7 @@ noprefix "false"
\end_inset
).
+ We will see other examples later in this chapter.
\end_layout
\begin_layout Subsection
@@ -22533,6 +22540,13 @@ In the next section, we will give reasons for the names of these laws.
\begin_layout Subsection
Monad laws in terms of Kleisli functions
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Monad-laws-in-Kleisli"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -23852,6 +23866,13 @@ flatMap
\begin_layout Subsection
Verifying the monad laws using Kleisli functions
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Verifying-the-monad-via-Kleisli-trick"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -23927,8 +23948,31 @@ flipped Kleisli
flipped Kleisli
\series default
makes direct proofs of laws shorter.
- That trick applies to monads of a function type, such as the continuation
- and the state monads.
+ That trick applies to monads of a function type, such as
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Cont
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+State
+\end_layout
+
+\end_inset
+
+, and some other monads that we will discover later.
\end_layout
\begin_layout Subsubsection
@@ -24357,6 +24401,558 @@ We have seen different examples of well-known monads that were discovered
analysis to semi-monads and monads.
For each type construction, we will prove rigorously that the monad laws
hold.
+ The results are summarized in Table
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:Constructions-of-monads"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+\begin_inset Float table
+wide false
+sideways false
+status open
+
+\begin_layout Plain Layout
+\align center
+\begin_inset Tabular
+
+
+
+
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\series bold
+\size small
+Construction
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\series bold
+\size small
+Type notation
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\series bold
+\size small
+Assumptions, results
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+fixed type
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq Z$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F$
+\end_inset
+
+ is a monad if
+\begin_inset Formula $Z=\bbnum 1$
+\end_inset
+
+;
+\begin_inset Formula $F$
+\end_inset
+
+ is a semi-monad for
+\begin_inset Formula $Z\neq\bbnum 1$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+identity
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq A$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F$
+\end_inset
+
+ is a full monad
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+product
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq P^{A}\times Q^{A}$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $P$
+\end_inset
+
+ and
+\begin_inset Formula $Q$
+\end_inset
+
+ are (semi-)monads
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+product
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq A\times P^{A}$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F$
+\end_inset
+
+ is a semi-monad when
+\begin_inset Formula $P$
+\end_inset
+
+ is any functor
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+free pointed
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq A+P^{A}$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F$
+\end_inset
+
+ is a monad when
+\begin_inset Formula $P$
+\end_inset
+
+ is a monad
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+function type
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq Z\rightarrow P^{A}$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $Z$
+\end_inset
+
+ is a fixed type,
+\begin_inset Formula $P$
+\end_inset
+
+ is a (semi-)monad
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+function type
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq H^{A}\rightarrow A$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F$
+\end_inset
+
+ is a monad when
+\begin_inset Formula $H$
+\end_inset
+
+ is any contrafunctor
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+function type
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq H^{A}\rightarrow G^{A}$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $G$
+\end_inset
+
+ is a (semi-)monad,
+\begin_inset Formula $H$
+\end_inset
+
+ is a
+\begin_inset Formula $G$
+\end_inset
+
+-filterable contrafunctor
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+free monad
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq A+L^{F^{A}}$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $L$
+\end_inset
+
+ is any functor
+\end_layout
+
+\end_inset
+ |
+
+
+|
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+tree semi-monad
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F^{A}\triangleq L^{A}+L^{F^{A}}$
+\end_inset
+
+
+\end_layout
+
+\end_inset
+ |
+
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\size footnotesize
+\begin_inset Formula $F$
+\end_inset
+
+ is a semi-monad if
+\begin_inset Formula $L$
+\end_inset
+
+ is any functor
+\end_layout
+
+\end_inset
+ |
+
+
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+\begin_inset Caption Standard
+
+\begin_layout Plain Layout
+Constructions of semi-monads and monads.
+\begin_inset CommandInset label
+LatexCommand label
+name "tab:Constructions-of-monads"
+
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
\end_layout
\begin_layout Paragraph
@@ -26366,7 +26962,14 @@ F^{L^{A}} & \bbnum 0 & \gamma^{\uparrow F}\bef\text{ftn}_{F}
& A & F^{A}\\
\hline A & \text{id} & \bbnum 0\\
F^{A} & \bbnum 0 & \text{id}
-\end{array}\,=\text{id}\quad,\\
+\end{array}\,=\text{id}\quad,
+\end{align*}
+
+\end_inset
+
+
+\begin_inset Formula
+\begin{align*}
& \text{pu}_{L}^{\uparrow L}\bef\text{ftn}_{L}=\,\begin{array}{|c||ccc|}
& A & F^{A} & F^{L^{A}}\\
\hline A & \text{id} & \bbnum 0 & \bbnum 0\\
@@ -26519,8 +27122,7 @@ F^{L^{L^{A}}} & \bbnum 0 & \bbnum 0 & \gamma^{\uparrow F}\bef\text{ftn}_{F}
\end_inset
-We are ready to verify the associativity law.
- Simplify both sides using matrix compositions:
+We are ready to verify the associativity law:
\begin_inset Formula
\begin{align*}
& \text{ftn}_{L}^{\uparrow L}\bef\text{ftn}_{L}=\,\begin{array}{|c||ccc|}
@@ -26534,14 +27136,7 @@ F^{L^{L^{A}}} & \bbnum 0 & \bbnum 0 & \text{ftn}_{L}^{\uparrow F}
\hline A & \text{id} & \bbnum 0\\
F^{A} & \bbnum 0 & \text{id}\\
F^{L^{A}} & \bbnum 0 & \gamma^{\uparrow F}\bef\text{ftn}_{F}
-\end{array}
-\end{align*}
-
-\end_inset
-
-
-\begin_inset Formula
-\begin{align*}
+\end{array}\\
& \quad=\,\begin{array}{|c||cc|}
& A & F^{A}\\
\hline A & \text{id} & \bbnum 0\\
@@ -26753,7 +27348,7 @@ F^{L^{A}} & \gamma^{\uparrow F}\bef\text{ftn}_{F}
\begin_inset Note Note
-status open
+status collapsed
\begin_layout Plain Layout
\begin_inset Formula
@@ -27055,8 +27650,11 @@ f^{:Z\rightarrow A\rightarrow F^{B}}\tilde{\diamond}_{_{L}}g^{:Z\rightarrow B\ri
\end_inset
+\end_layout
+
+\begin_layout Standard
\begin_inset Note Note
-status open
+status collapsed
\begin_layout Plain Layout
\begin_inset Formula
@@ -27072,10 +27670,6 @@ f^{:Z\rightarrow A\rightarrow F^{B}}\tilde{\diamond}_{_{L}}g^{:Z\rightarrow B\ri
\end_inset
-
-\end_layout
-
-\begin_layout Standard
To verify the laws, it is convenient to substitute an arbitrary
\begin_inset Formula $z^{:Z}$
\end_inset
@@ -28678,9 +29272,7 @@ def flatMap_L[A, B](la: L[A])(f: A => L[B]): L[B] = la match {
\begin_layout Plain Layout
- case Right(fla) => Right(fla.map { (x: L[A]) => flatMap_L(x)(f) }) //
- Recursive call of flatMap_L.
-
+ case Right(fla) => Right(fla.map { (x: L[A]) => flatMap_L(x)(f) })
\end_layout
\begin_layout Plain Layout
@@ -28706,8 +29298,7 @@ def flatten_L[A]: L[L[A]] => L[A] = { // Match on L[L[A]] = Either[Either[A,
\begin_layout Plain Layout
- case Right(Right(flla)) => Right(flla.map(x => flatten_L(x))) //
- Recursive call of flatten_L.
+ case Right(Right(flla)) => Right(flla.map(x => flatten_L(x)))
\end_layout
\begin_layout Plain Layout
@@ -28852,7 +29443,7 @@ F^{L^{L^{L^{A}}}} & \bbnum 0 & \bbnum 0 & \big(\text{ftn}_{L}^{\overline{\uparro
\end_inset
-We can now verify the identity and associativity laws of
+We can now verify the laws of
\begin_inset Formula $\text{pu}_{L}$
\end_inset
@@ -28863,7 +29454,7 @@ We can now verify the identity and associativity laws of
.
Identity laws:
\begin_inset Note Note
-status collapsed
+status open
\begin_layout Plain Layout
\begin_inset Formula
@@ -30283,7 +30874,15 @@ pure
status open
\begin_layout Plain Layout
-There are several implementations of
+Functors of the form
+\begin_inset Formula $F^{A}\triangleq\bbnum 1+A\times...\times A$
+\end_inset
+
+ are not monads:
+\emph on
+none
+\emph default
+ of the possible implementations of
\begin_inset listings
inline true
status open
@@ -30307,16 +30906,8 @@ flatten
\end_inset
- for
-\begin_inset Formula $D^{A}\triangleq\bbnum 1+A\times A$
-\end_inset
-
-, but
-\emph on
-none
-\emph default
- of them obey the monad laws (Hew Wolff, private communication).
- For details, see
+ obey the monad laws (Hew Wolff, private communication).
+ For some details, see
\family typewriter
\begin_inset CommandInset href
@@ -33521,7 +34112,7 @@ monadic program
\begin_inset Formula $A$
\end_inset
- and is a result of nested iterations.
+.
For a pass/fail monad
\begin_inset Formula $M$
\end_inset
@@ -36850,7 +37441,7 @@ noprefix "false"
\end_inset
).
- One can also show that
+ One can show that
\begin_inset Formula $F$
\end_inset
@@ -36886,12 +37477,22 @@ By the same logic, we can conclude that
\end_inset
cannot be obtained through monad constructions.
- It is likely (although this book does not have a proof) that
-\begin_inset Formula $F^{A}\triangleq\bbnum 1+A\times A\times A$
+ It is known
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+Hew Wolff, private communication (2024).
+\end_layout
+
+\end_inset
+
+ that
+\begin_inset Formula $F^{A}\triangleq\bbnum 1+A\times A$
\end_inset
,
-\begin_inset Formula $F^{A}\triangleq\bbnum 1+A\times A\times A\times A$
+\begin_inset Formula $F^{A}\triangleq\bbnum 1+A\times A\times A$
\end_inset
, and all other similarly constructed functors are
@@ -37175,11 +37776,13 @@ status open
\end_layout
\begin_layout Standard
-We have shown some examples of
+The concepts of
\begin_inset Formula $M$
\end_inset
--filterable functors in Statement
+-filterable functors and contrafunctors are not well known and not widely
+ used.
+ To build up intuition, we have shown some examples in Statement
\begin_inset space ~
\end_inset
@@ -37212,7 +37815,7 @@ In the following constructions, we assume that
\end_layout
\begin_layout Standard
-We omit the proofs of all following statements because they are fully analogous
+We omit the proofs of all the following statements because they are analogous
to the proofs of filterable functor and contrafunctor constructions in
Sections
\begin_inset space ~
diff --git a/sofp-src/lyx/sofp-summary.lyx b/sofp-src/lyx/sofp-summary.lyx
index 0199abad8..dcb2194fc 100644
--- a/sofp-src/lyx/sofp-summary.lyx
+++ b/sofp-src/lyx/sofp-summary.lyx
@@ -335,7 +335,7 @@ The book has been written in a tutorial format, motivating and deriving
\end_layout
\begin_layout Section
-Main points and results by chapter
+Main ideas and results by chapter
\end_layout
\begin_layout Standard
@@ -1148,7 +1148,7 @@ noprefix "false"
\begin_layout Standard
This chapter begins the second part of the book, which is devoted to a systemati
c analysis of various type constructions that produce data structures with
- different properties.
+ certain useful properties.
The first kind of data structure to be analysed is
\begin_inset Quotes eld
\end_inset
@@ -1169,8 +1169,58 @@ wrappers
\begin_inset Quotes erd
\end_inset
- of data.
- Those containers should have a
+ of data; a first example is a sequence type such as Scala's
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Seq[A]
+\end_layout
+
+\end_inset
+
+.
+ A typical operation for sequences is a loop over elements of the sequence.
+ In functional programming, those loops are implemented by the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map
+\end_layout
+
+\end_inset
+
+ method.
+ Generalizing from
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Seq
+\end_layout
+
+\end_inset
+
+ to an arbitrary container
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+F
+\end_layout
+
+\end_inset
+
+, we find that the
\begin_inset listings
inline true
status open
@@ -1249,8 +1299,15 @@ map
\end_inset
must obey.
- In this way, we arrive at the functor laws: the identity law and the compositio
-n law.
+ In this way, we arrive at the
+\begin_inset Quotes eld
+\end_inset
+
+functor laws
+\begin_inset Quotes erd
+\end_inset
+
+: the identity law and the composition law.
\end_layout
\begin_layout Standard
@@ -1279,8 +1336,31 @@ yield
\end_inset
syntax for chains of functor operations.
- In later chapters, we will see how this syntax extends to conditionals
- and nested loops.
+ (In later chapters, we will see how the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+for
+\end_layout
+
+\end_inset
+
+/
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+yield
+\end_layout
+
+\end_inset
+
+ syntax can also support conditionals and nested loops.)
\end_layout
\begin_layout Standard
@@ -1301,7 +1381,21 @@ contramap
\end_inset
method can be implemented.
- This motivates the concept of a contrafunctor (short for
+ This motivates the concept of a
+\series bold
+contrafunctor
+\series default
+
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+contrafunctor
+\end_layout
+
+\end_inset
+
+ (short for
\begin_inset Quotes eld
\end_inset
@@ -1524,7 +1618,7 @@ noprefix "false"
\end_layout
\begin_layout Standard
-This book uses certain non-standard notation to write types and code more
+This book uses certain non-standard notations to write types and code more
concisely.
For instance, type parameters are written as superscripts (
\begin_inset Formula $F^{A}$
@@ -1614,7 +1708,7 @@ noprefix "false"
\end_layout
\begin_layout Standard
-A
+The concept of
\begin_inset Quotes eld
\end_inset
@@ -1622,7 +1716,8 @@ typeclass
\begin_inset Quotes erd
\end_inset
- is a mechanism for constraining type parameters in generic functions.
+ is motivated as a mechanism for constraining type parameters in generic
+ functions.
We show how a typeclass can be implemented by passing evidence values in
extra arguments.
We show how to define functions whose type parameters are constrained to
@@ -2276,11 +2371,7 @@ Why many typeclasses have similar properties as regards typeclass derivation;
\begin_inset Quotes eld
\end_inset
-
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses
+FM-typeclasses
\begin_inset Quotes erd
\end_inset
@@ -2650,7 +2741,7 @@ Kleisli functions
\begin_layout Itemize
We notice the similarity between the laws of several typeclasses and the
standard functor laws, which invites us to take a first glance at category
- theory and its more general definition of functors.
+ theory that provides a more general definition of a functor.
We show that the laws of typeclasses can be derived from the laws of categories
and of categorical functors.
This gives us assurance that the typeclass laws are chosen in a consistent
@@ -2665,16 +2756,17 @@ This chapter studies filterable functors by following a pattern that all
\begin_inset space ~
\end_inset
-II will also follow.
+II also follow.
Beginning with working Scala code involving some operation, we formulate
- a typeclass whose members support that operation.
- Then we motivate and derive the mathematical laws that describe a programmer's
- expectations about that operation's behavior.
+ a typeclass whose member types support that operation.
+ Then we motivate a programmer's expectations about that operation's behavior,
+ and derive the corresponding mathematical laws.
To make the reasoning easier, we simplify those laws by introducing other,
equivalent operations that have simpler laws.
We proceed to structural analysis and discover what type constructions
can support the given operation and its laws.
- As a result, we obtain many examples of types that belong to the typeclass.
+ As a result, we obtain many examples of types that belong to the typeclass
+ (as well as examples of types that do not).
\end_layout
\begin_layout Subsection
@@ -2696,233 +2788,5556 @@ noprefix "false"
\end_layout
\begin_layout Standard
-***
-\end_layout
-
-\begin_layout Subsection
-Chapter
-\begin_inset space ~
+\begin_inset Quotes eld
\end_inset
-
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "chap:8-Applicative-functors,-contrafunctors"
-plural "false"
-caps "false"
-noprefix "false"
-
+Semi-monads
+\begin_inset Quotes erd
\end_inset
+ are introduced as functors that support a
+\begin_inset listings
+inline true
+status open
-\end_layout
+\begin_layout Plain Layout
-\begin_layout Standard
-***
+flatMap
\end_layout
-\begin_layout Subsection
-Chapter
-\begin_inset space ~
\end_inset
+ method.
+ This is motivated by considering how functional programming can represent
+ nested loops.
+ Simple loops are translated into an application of a
+\begin_inset listings
+inline true
+status open
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "chap:9-Traversable-functors-and"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Plain Layout
+
+map
+\end_layout
\end_inset
+ function to sequences; similarly, nested loops are translated into applications
+ of
+\begin_inset listings
+inline true
+status open
-\end_layout
+\begin_layout Plain Layout
-\begin_layout Standard
-***
+flatMap
\end_layout
-\begin_layout Subsection
-Chapter
-\begin_inset space ~
\end_inset
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "chap:Free-type-constructions"
-plural "false"
-caps "false"
-noprefix "false"
+map
+\end_layout
\end_inset
-
+ functions.
+
\end_layout
\begin_layout Standard
-***
+Scala's
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+for
\end_layout
-\begin_layout Subsection
-Chapter
-\begin_inset space ~
\end_inset
+ /
+\begin_inset listings
+inline true
+status open
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "chap:monad-transformers"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Plain Layout
+
+yield
+\end_layout
\end_inset
+ syntax (which is itself modeled on a mathematical notation) is equivalent
+ to nested
+\begin_inset listings
+inline true
+status open
-\end_layout
+\begin_layout Plain Layout
-\begin_layout Standard
-***
+map
\end_layout
-\begin_layout Subsection
-Appendix
-\begin_inset space ~
\end_inset
+ and
+\begin_inset listings
+inline true
+status open
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "app:Proofs-of-naturality-parametricity"
-plural "false"
-caps "false"
-noprefix "false"
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
\end_inset
+ calls.
+ We give examples for using these functions (either directly or via the
+
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+for
\end_layout
-\begin_layout Standard
-This appendix studies
-\begin_inset Quotes eld
\end_inset
-parametricity properties
-\begin_inset Quotes erd
+ /
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+yield
+\end_layout
+
\end_inset
- that apply to all fully parametric code.
- Those properties are a mathematical expression of the idea that a fully
- parametric function works
+ syntax) for implementing various iterative computations with sequences
+ and other
\begin_inset Quotes eld
\end_inset
-in the same way
+list-like
\begin_inset Quotes erd
\end_inset
- for all types.
- This appendix develops the necessary theory and technique in order and
- proves the following results:
-\end_layout
-
-\begin_layout Standard
-A given type constructor may have one fully parametric and lawful implementation
- of the
+ monads such as
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-Functor
+Array
\end_layout
\end_inset
- or
+ and
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-Contrafunctor
+Set
\end_layout
\end_inset
- typeclass instance.
- (For most other typeclasses, such as
+.
+\end_layout
+
+\begin_layout Standard
+Computations with sequences and other list-like types is the first step
+ towards generalizing the
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-Filterable
+map
\end_layout
\end_inset
- or
+ and
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-Monad
+flatMap
\end_layout
\end_inset
-, type constructors often have several inequivalent and lawful typeclass
- instances.) The unique implementations are used in the type constructions
- shown in Sections
-\begin_inset space ~
-\end_inset
+ functions to other data structures.
+ The next step is to consider
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Option
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Either
+\end_layout
+
+\end_inset
+
+ types (the
+\begin_inset Quotes eld
+\end_inset
+
+pass/fail
+\begin_inset Quotes erd
+\end_inset
+
+ monads).
+ Computations with those types are also expressible via
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+ calls, and can benefit from using the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+for
+\end_layout
+
+\end_inset
+
+ /
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+yield
+\end_layout
+
+\end_inset
+
+ syntax.
+\end_layout
+
+\begin_layout Standard
+We then turn to tree-like monads and show how computations with binary trees
+ and abstract syntax trees are naturally expressed via a special implementation
+ of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+Further generalization is motivated by the idea of viewing functions of
+ type
+\begin_inset Formula $A\rightarrow L^{B}$
+\end_inset
+
+ a
+\begin_inset Quotes eld
+\end_inset
+
+computation with an
+\begin_inset Formula $L$
+\end_inset
+
+-effect
+\begin_inset Quotes erd
+\end_inset
+
+.
+ By that we mean not a side effect, but any extra computational work that
+ is done in a function of type
+\begin_inset Formula $A\rightarrow L^{B}$
+\end_inset
+
+ other than computing a result value of type
+\begin_inset Formula $B$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+With this picture in mind, we are able to derive the monad types that represent
+ certain special computational situations: computing a value while reading
+ another given value (the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Reader
+\end_layout
+
+\end_inset
+
+ monad); computing a value while writing out another value (the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Writer
+\end_layout
+
+\end_inset
+
+ monad); computing a value while updating another value (the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+State
+\end_layout
+
+\end_inset
+
+ monad); and computing a value but passing it to a given callback function
+ (
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Cont
+\end_layout
+
+\end_inset
+
+, the continuation monad).
+ Finally, the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Eval
+\end_layout
+
+\end_inset
+
+ monad represents the possibilities of computing a result eagerly or lazily.
+ We look at code examples to illustrate the practical use of all those well-know
+n monads.
+
+\end_layout
+
+\begin_layout Standard
+Next, we consider the laws that the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+ operation should obey.
+ To derive those laws, we look at several code patterns that a programmer
+ would intuitively expect to behave in certain ways.
+ Each of those code patterns gives rise to a specific law of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+.
+ In this way, we derive an associativity law and two naturality laws for
+
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+.
+ Analogous laws for the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map
+\end_layout
+
+\end_inset
+
+ operation were derived in Chapter
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "chap:Functors,-contrafunctors,-and"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+, where we defined functors as type constructors with a lawful
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map
+\end_layout
+
+\end_inset
+
+ method.
+ Functors with a lawful
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+ method are
+\series bold
+semi-monads
+\series default
+.
+ In this way, we find that the functor type involved in a
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+for
+\end_layout
+
+\end_inset
+
+ /
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+yield
+\end_layout
+
+\end_inset
+
+ block (in this book, we call them
+\series bold
+functor blocks
+\series default
+) must be in general a semi-monad.
+\end_layout
+
+\begin_layout Standard
+The three laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+ are equivalent to just two laws if we pass to a simpler function known
+ in Scala as
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatten
+\end_layout
+
+\end_inset
+
+.
+ We derive the laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatten
+\end_layout
+
+\end_inset
+
+ and prove that they are equivalent to the laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+.
+ A formal proof of type equivalence between
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatten
+\end_layout
+
+\end_inset
+
+ (Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-flatten-equivalent-to-flatMap"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) requires assuming one naturality law of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+.
+
+\end_layout
+
+\begin_layout Standard
+We show how to verify the associativity law of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatten
+\end_layout
+
+\end_inset
+
+ for the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Either
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Reader
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+List
+\end_layout
+
+\end_inset
+
+, and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Writer
+\end_layout
+
+\end_inset
+
+ monads.
+
+\end_layout
+
+\begin_layout Standard
+Almost all semi-monads we considered are in fact
+\begin_inset Quotes eld
+\end_inset
+
+full monads
+\begin_inset Quotes erd
+\end_inset
+
+, as they support an additional operation called
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pure
+\end_layout
+
+\end_inset
+
+.
+ We motivate this operation by considering an
+\begin_inset Quotes eld
+\end_inset
+
+empty effect
+\begin_inset Quotes erd
+\end_inset
+
+; for instance, an iteration over a list of length
+\begin_inset Formula $1$
+\end_inset
+
+.
+ Then we derive the laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pure
+\end_layout
+
+\end_inset
+
+ by looking at how we expect functor block code to behave when using
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pure
+\end_layout
+
+\end_inset
+
+.
+ The laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pure
+\end_layout
+
+\end_inset
+
+ have a simpler form when written using
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatten
+\end_layout
+
+\end_inset
+
+ instead of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+.
+ As we derive those simpler forms, we introduce Kleisli functions (of type
+
+\begin_inset Formula $A\rightarrow M^{B}$
+\end_inset
+
+) and the Kleisli composition operation (
+\begin_inset Formula $\diamond_{_{M}}$
+\end_inset
+
+) for a given monad
+\begin_inset Formula $M$
+\end_inset
+
+.
+ Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Monad-laws-in-Kleisli"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ derives the laws of the Kleisli composition operation from the laws of
+
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pure
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatten
+\end_layout
+
+\end_inset
+
+ and also proves a full formal equivalence between the formulations of the
+ monad operations and laws via Kleisli functions and via
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pure
+\end_layout
+
+\end_inset
+
+ /
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatten
+\end_layout
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+Formulating monads via Kleisli functions has certain advantages when verifying
+ laws of monads involving function types.
+ Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Verifying-the-monad-via-Kleisli-trick"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ shows how the
+\begin_inset Quotes eld
+\end_inset
+
+flipped / curried Kleisli
+\begin_inset Quotes erd
+\end_inset
+
+ trick makes the proofs of monad laws shorter and clearer for the continuation
+ monad and the state monad.
+\end_layout
+
+\begin_layout Standard
+We pass on to structural analysis of semi-monads and monads.
+ The resulting type constructions are shown in Table
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:Constructions-of-monads"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+ Some constructions only give semi-monads, but most create full monads.
+\end_layout
+
+\begin_layout Standard
+The chapter concludes by some further theoretical developments:
+\end_layout
+
+\begin_layout Itemize
+Monads must be functors: it is impossible to define nontrivial monads that
+ are contrafunctors.
+\end_layout
+
+\begin_layout Itemize
+In this and the previous chapters, we proved the type isomorphisms between
+
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pure
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+wu
+\end_layout
+
+\end_inset
+
+ (for pointed functors), between
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+liftOpt
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+deflate
+\end_layout
+
+\end_inset
+
+ (for filterable functors), and between
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatten
+\end_layout
+
+\end_inset
+
+ (for semi-monads).
+ It turns out that all those isomorphisms are special cases of more general
+ type isomorphisms, known as the Yoneda identities.
+\end_layout
+
+\begin_layout Itemize
+For monads that are not containers, a
+\begin_inset Quotes eld
+\end_inset
+
+runner
+\begin_inset Quotes erd
+\end_inset
+
+ is needed to extract result values.
+ It turns out that
+\begin_inset Quotes eld
+\end_inset
+
+runners
+\begin_inset Quotes erd
+\end_inset
+
+ are functions that need to satisfy certain laws, known as the laws of
+\begin_inset Quotes eld
+\end_inset
+
+monad morphisms
+\begin_inset Quotes erd
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Itemize
+Monad morphisms and their laws are known in category theory; they are the
+ morphisms in the category of monads.
+ Monad morphisms are natural transformations between monads that map one
+ monad's
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pure
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatten
+\end_layout
+
+\end_inset
+
+ operations onto the same operations of another monad.
+ We show some examples to build up intuition about monad morphisms.
+\end_layout
+
+\begin_layout Itemize
+Each monad gives rise to a category we denote by
+\begin_inset Quotes eld
+\end_inset
+
+
+\begin_inset Formula $M$
+\end_inset
+
+-Kleisli
+\begin_inset Quotes erd
+\end_inset
+
+; morphisms in that category are Kleisli functions.
+\end_layout
+
+\begin_layout Itemize
+Polynomial functors are sometimes monads (but sometimes not; one example
+ is
+\begin_inset Formula $F^{A}\triangleq\bbnum 1+A\times A\times...\times A$
+\end_inset
+
+).
+ We list the known type constructions that build up polynomial monads.
+\end_layout
+
+\begin_layout Itemize
+One of the monad constructions involves the notion of an
+\begin_inset Formula $M$
+\end_inset
+
+-filterable contrafunctor.
+ They can be motivated as generalizations of filterable contrafunctors when
+ we replace the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Option
+\end_layout
+
+\end_inset
+
+ monad in the type signature of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+filter
+\end_layout
+
+\end_inset
+
+ by an arbitrary monad
+\begin_inset Formula $M$
+\end_inset
+
+.
+ We show formal definitions of
+\begin_inset Formula $M$
+\end_inset
+
+-filterable functors and contrafunctors, and briefly explore their structural
+ analysis.
+\end_layout
+
+\begin_layout Subsection
+Chapter
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "chap:8-Applicative-functors,-contrafunctors"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+We begin by looking at the familiar
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ operation for sequences (which are functors).
+ It turns out that
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ can be generalized to work with many other types.
+ Type constructors that support a
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ method satisfying suitable laws are called
+\begin_inset Quotes eld
+\end_inset
+
+applicative
+\begin_inset Quotes erd
+\end_inset
+
+.
+ This chapter will develop a rigorous description of applicative functors,
+ contrafunctors, and profunctors.
+
+\end_layout
+
+\begin_layout Standard
+We begin with examples of practical use of the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ method, showing how
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ can be used to combine polynomial data types, binary trees, and even some
+ non-covariant type constructors.
+ Other uses of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ include gathering multiple errors while validating data; performing multiple
+ computations in parallel; and transposing matrices.
+ We arrive at an intuition that applicative functors express combination
+ of effects that are independent of previously computed values.
+ For that reason, effects can be sometimes evaluated and combined in parallel.
+ The condition for that is called
+\begin_inset Quotes eld
+\end_inset
+
+commutativity
+\begin_inset Quotes erd
+\end_inset
+
+ of applicative functors.
+ This property will be formally defined and studied later in this chapter.
+\end_layout
+
+\begin_layout Standard
+Another practically useful function is
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map2
+\end_layout
+
+\end_inset
+
+.
+ We show that
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map2
+\end_layout
+
+\end_inset
+
+ can be expressed via
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+, and that analogous methods
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map3
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map4
+\end_layout
+
+\end_inset
+
+, etc., may be defined via
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip3
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip4
+\end_layout
+
+\end_inset
+
+, etc.
+ We can avoid having to implement all those functions via boilerplate code
+ if we instead implement a method known as
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+ap
+\end_layout
+
+\end_inset
+
+.
+ However, this trick works only for covariant functors.
+ Non-covariant functors must define methods such as
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+xmap2
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+xmap3
+\end_layout
+
+\end_inset
+
+, etc., separately.
+\end_layout
+
+\begin_layout Standard
+We show further use cases for applicative functors: the applicative
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Reader
+\end_layout
+
+\end_inset
+
+ functor;
+\begin_inset Quotes eld
+\end_inset
+
+fusion
+\begin_inset Quotes erd
+\end_inset
+
+ of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+fold
+\end_layout
+
+\end_inset
+
+-like operations into single traversals; and parsing via parsing combinators.
+ To build up intuition, we show code that contrasts the applicative and
+ the monadic approaches to fold fusion and to parsing combinators.
+\end_layout
+
+\begin_layout Standard
+Applicative operations may be used in functor blocks as explicit
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ operations.
+ Scala does not have a widely accepted special syntax for applicative functor
+ blocks, although some experimental proposals exist (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Functor-block-syntax-for-applicative"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+\end_layout
+
+\begin_layout Standard
+We turn to the derivation of the laws for
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+.
+ First, we show that the methods
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+ap
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map2
+\end_layout
+
+\end_inset
+
+, and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ are equivalent as types if we assume suitable naturality laws.
+ We prefer to define the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Zippable
+\end_layout
+
+\end_inset
+
+ typeclass via the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ method, for the reason that the same typeclass will be usable with non-covarian
+t functors.
+\end_layout
+
+\begin_layout Standard
+The laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map2
+\end_layout
+
+\end_inset
+
+ follow from the monad laws if we implement
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map2
+\end_layout
+
+\end_inset
+
+ through
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+.
+ Of course, applicative functors do not necessary have
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+; but this derivation allows us to motivate a reasonable set of laws for
+
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map2
+\end_layout
+
+\end_inset
+
+.
+ These are the associativity law and the two identity laws.
+ We then derive the corresponding laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+We formally define the property of commutativity for applicative functors
+ and show how it simplifies the other laws.
+ Most applicative functors used in practice are commutative and are suitable
+ for parallel evaluation.
+\end_layout
+
+\begin_layout Standard
+Many applicative functors are at the same time monads.
+ However, most monads used in practice are
+\emph on
+not
+\emph default
+ commutative.
+ For this reason, it is typically not the case that applicative functors
+ have their
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ functions derived from
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+.
+ For example, the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+List
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Either
+\end_layout
+
+\end_inset
+
+ are monads whose standard
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ methods do not follow from the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+ code for those monads.
+\end_layout
+
+\begin_layout Standard
+Having derived the laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+, the next step is to perform structural analysis and to discover type construct
+ions that create new applicative type constructors.
+ The results for applicative functors are shown in Table
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:Constructions-of-applicative-functors"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+, for applicative contrafunctors in Table
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:Constructions-of-applicative-contrafunctors"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+, and for applicative profunctors in Table
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:Constructions-of-applicative-profunctors"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+
+\end_layout
+
+\begin_layout Standard
+Usually, there will be several inequivalent but lawful implementations for
+ the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ method; so, the applicative typeclass instances are not unique.
+ Another consequence of structural analysis is that all exponential-polynomial
+
+\emph on
+contravariant
+\emph default
+ functors are applicative.
+ It is perhaps surprizing that a lawful
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+ method can be defined for a wide range of profunctors that are neither
+ covariant nor contravariant.
+ One practical use case for this property is shown in Example
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-applicative-profunctor"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+Further theoretical developments at the end of this chapter include:
+\end_layout
+
+\begin_layout Itemize
+We have previously seen several examples of methods that are equivalent
+ as types:
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatten
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+map2
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zip
+\end_layout
+
+\end_inset
+
+, and so on.
+ Now we clarify and formulate rigorously what it means that two typeclass
+ methods are
+\begin_inset Quotes eld
+\end_inset
+
+isomorphic as types assuming some laws hold
+\begin_inset Quotes erd
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Itemize
+All monads are applicative at least in one way (but not all applicative
+ functors are monads).
+ In many cases, the applicative instance derived from the monad instance
+ is not as useful in applications as a different, inequivalent applicative
+ instance for the same type constructor.
+ We show some examples illustrating this.
+\end_layout
+
+\begin_layout Itemize
+We motivate and define the concept of
+\begin_inset Quotes eld
+\end_inset
+
+applicative morphism
+\begin_inset Quotes erd
+\end_inset
+
+: a mapping between two applicative functors that preserves the applicative
+ methods.
+\end_layout
+
+\begin_layout Itemize
+The laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+ap
+\end_layout
+
+\end_inset
+
+ are easier to derive if we get some help from category theory.
+ For an applicative functor
+\begin_inset Formula $L$
+\end_inset
+
+, we define the
+\begin_inset Quotes eld
+\end_inset
+
+
+\begin_inset Formula $L$
+\end_inset
+
+-ap
+\begin_inset Quotes erd
+\end_inset
+
+ category whose morphisms have type
+\begin_inset Formula $L^{A\rightarrow B}$
+\end_inset
+
+ and are composed using the special operation (
+\begin_inset Formula $\odot$
+\end_inset
+
+).
+ In this formulation, the laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+ap
+\end_layout
+
+\end_inset
+
+ follow from the category laws of
+\begin_inset Formula $L$
+\end_inset
+
+-ap.
+\end_layout
+
+\begin_layout Itemize
+We summarize various typeclass methods and laws defined in this and the
+ previous chapter and examine the patterns in their type signatures (see
+ Table
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:functorial-typeclasses"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ It turns out that the laws of each typeclass are equivalent to the standard
+ functor laws, if we consider a certain categorical functor defined in a
+ suitable way for that typeclass.
+ This provides a general and abstract picture justifying the choice of typeclass
+ laws.
+\end_layout
+
+\begin_layout Subsection
+Chapter
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "chap:9-Traversable-functors-and"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+We begin by considering the standard
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+reduce
+\end_layout
+
+\end_inset
+
+ method for sequences.
+ Traversable functors are found by a generalization that we motivate in
+ several steps.
+ As a first step, we pass from
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+reduce
+\end_layout
+
+\end_inset
+
+ to
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+foldMap
+\end_layout
+
+\end_inset
+
+, which is parameterized by an arbitrary monoid
+\begin_inset Formula $M$
+\end_inset
+
+.
+ The next step generalizes from sequences to functors that support an analogous
+
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+foldMap
+\end_layout
+
+\end_inset
+
+ method.
+ The final step is to replace the monoid
+\begin_inset Formula $M$
+\end_inset
+
+ by an arbitrary applicative functor with a type parameter.
+ The result is a powerful operation known as
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+The
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+ function can be implemented for any polynomial functor (we will prove that
+ rigorously later in that chapter).
+ To build up intuition, we show several examples of implementing
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+ for different data types, such as lists and trees.
+\end_layout
+
+\begin_layout Standard
+Another useful function equivalent to
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+foldMap
+\end_layout
+
+\end_inset
+
+ is
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+toList
+\end_layout
+
+\end_inset
+
+: it extracts all data from a functor in a certain fixed order into a
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+List
+\end_layout
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+We illustrate the usage of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+foldMap
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+toList
+\end_layout
+
+\end_inset
+
+, and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+ for tasks such as depth-first or breadth-first aggregations and
+\begin_inset Quotes eld
+\end_inset
+
+decorations
+\begin_inset Quotes erd
+\end_inset
+
+ on trees.
+ A typical
+\begin_inset Quotes eld
+\end_inset
+
+decoration
+\begin_inset Quotes erd
+\end_inset
+
+ function is
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zipWithIndex
+\end_layout
+
+\end_inset
+
+: it adds integer labels to data according to the traversal order.
+ We show how
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+ makes implementing
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zipWithIndex
+\end_layout
+
+\end_inset
+
+ simpler.
+ Different traversal orders correspond to different implementations of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+, while the
+\begin_inset Quotes eld
+\end_inset
+
+decoration
+\begin_inset Quotes erd
+\end_inset
+
+ logic remains the same.
+\end_layout
+
+\begin_layout Standard
+Defining the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Traversable
+\end_layout
+
+\end_inset
+
+ typeclass via the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+ method, we show how to implement various traversal-like operations such
+ as
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zipWithIndex
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+scanLeft
+\end_layout
+
+\end_inset
+
+ using that typeclass.
+\end_layout
+
+\begin_layout Standard
+Then we give examples of tasks that cannot be performed via
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+ because it cannot obtain certain required information while traversing
+ the data structure.
+ To overcome this difficulty, we introduce a generalized
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+fold
+\end_layout
+
+\end_inset
+
+ operation that depends on the pattern functor of a recursive type.
+ The
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+fold
+\end_layout
+
+\end_inset
+
+ operation is a
+\series bold
+recursion scheme
+\series default
+
+\begin_inset Index idx
+status open
+
+\begin_layout Plain Layout
+recursion scheme
+\end_layout
+
+\end_inset
+
+: a higher-order function that supplies recursive behavior and is parameterized
+ by a calculation that needs to be performed repeatedly.
+ We give some examples of using
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+fold
+\end_layout
+
+\end_inset
+
+ for implementing tasks such as depth labeling (
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zipWithDepth
+\end_layout
+
+\end_inset
+
+) and pretty-printing.
+\end_layout
+
+\begin_layout Standard
+A recursion scheme opposite to
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+fold
+\end_layout
+
+\end_inset
+
+ is
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfold
+\end_layout
+
+\end_inset
+
+: it creates a new recursive structure by following specified logic.
+ We give examples of using unfold for creating lists and trees of specified
+ shape.
+\end_layout
+
+\begin_layout Standard
+Unlike
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+fold
+\end_layout
+
+\end_inset
+
+ that always terminates, the termination of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfold
+\end_layout
+
+\end_inset
+
+ is not guaranteed, as it can go on indefinitely creating new parts of recursive
+ structures.
+ This problem can be avoided by using lazy data structures that delay evaluation
+ of recursive parts.
+ We show how to define a
+\begin_inset Quotes eld
+\end_inset
+
+lazy
+\begin_inset Quotes erd
+\end_inset
+
+ binary tree that can simulate trees of unbounded depth.
+\end_layout
+
+\begin_layout Standard
+We turn to investigating the laws and formal properties of folding and traversal
+ operations.
+ First, we show formally that
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+reduce
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+foldLeft
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+foldMap
+\end_layout
+
+\end_inset
+
+, and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+toList
+\end_layout
+
+\end_inset
+
+ are isomorphic as types if we assume suitable naturality laws.
+ When formulating those laws, we find it necessary to introduce
+\begin_inset Quotes eld
+\end_inset
+
+monoid morphisms
+\begin_inset Quotes erd
+\end_inset
+
+: functions mapping one monoid to another such that the monoid operations
+ are preserved.
+\end_layout
+
+\begin_layout Standard
+In Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:The-missing-laws-of-foldMap-and-reduce"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ we discuss the problem that the naturality laws alone do not guarantee
+ useful behavior of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+reduce
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+foldMap
+\end_layout
+
+\end_inset
+
+, and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+toList
+\end_layout
+
+\end_inset
+
+.
+ However, it does not appear possible to formulate any new laws.
+ Instead, we will formulate a law for
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+ and derive the folding operations from
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+.
+
+\end_layout
+
+\begin_layout Standard
+The lack of laws is not a serious issue since foldable functors can be character
+ized in a simple way: they are just all polynomial functors.
+ We show that all polynomial functors support a
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+toList
+\end_layout
+
+\end_inset
+
+ operation (and therefore all the other equivalent operations).
+\end_layout
+
+\begin_layout Standard
+We now turn to studying the laws of the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+ operation.
+ First, we note that an equivalent simpler operation is
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+sequence
+\end_layout
+
+\end_inset
+
+.
+ Then we formulate several laws of traverse: the applicative naturality
+ law, the identity law, and the composition law.
+ We motivate those laws by formal considerations and also show that these
+ laws do not hold for certain incorrect implementations of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+Then we derive the corresponding simpler laws for
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+sequence
+\end_layout
+
+\end_inset
+
+.
+ Using those laws, we perform structural analysis and prove that all polynomial
+ functors are traversable.
+ (We also explain why non-polynomial functors are not traversable.)
+\end_layout
+
+\begin_layout Standard
+In that proof, we needed a notion of
+\begin_inset Quotes eld
+\end_inset
+
+bitraversable
+\begin_inset Quotes erd
+\end_inset
+
+ bifunctors.
+ We define that property formally and show that all polynomial bifunctors
+ are bitraversable.
+\end_layout
+
+\begin_layout Standard
+In the last section of the chapter, we explore some further questions:
+\end_layout
+
+\begin_layout Itemize
+The recursion schemes
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+fold
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfold
+\end_layout
+
+\end_inset
+
+ generate
+\begin_inset Quotes eld
+\end_inset
+
+structure-preserving
+\begin_inset Quotes erd
+\end_inset
+
+ maps between types.
+ We define formally the notions of functor algebras and functor co-algebras
+ to show how the property of being
+\begin_inset Quotes eld
+\end_inset
+
+structure-preserving
+\begin_inset Quotes erd
+\end_inset
+
+ can be formulated via equations.
+\end_layout
+
+\begin_layout Itemize
+Some laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+ are still missing, as we are not able to use the existing laws for proving
+ certain expected properties of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zipWithIndex
+\end_layout
+
+\end_inset
+
+.
+ One needs a
+\begin_inset Quotes eld
+\end_inset
+
+representation theorem
+\begin_inset Quotes erd
+\end_inset
+
+ for
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+traverse
+\end_layout
+
+\end_inset
+
+ (Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-Bird-representation-theorem-for-traversal"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ A detailed proof of that theorem is beyond the scope of this book.
+ Using that theorem, we can prove the required properties of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+zipWithIndex
+\end_layout
+
+\end_inset
+
+.
+ We also show that a traversable functor always allows us to write an explicit
+ indexed table for all the data it contains (Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-polynomial-functors-Int-A"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+\end_layout
+
+\begin_layout Itemize
+We show that nontrivial traversable contrafunctors and profunctors do not
+ exist.
+\end_layout
+
+\begin_layout Itemize
+We show how to implement traversals for nested recursive types, and illustrate
+ with an example implementation of square-shaped nested lists.
+\end_layout
+
+\begin_layout Subsection
+Chapter
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "chap:Free-type-constructions"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+A
+\begin_inset Quotes eld
+\end_inset
+
+free typeclass
+\begin_inset Quotes erd
+\end_inset
+
+ is an advanced design pattern in functional programming.
+ The chapter begins by developing the
+\begin_inset Quotes eld
+\end_inset
+
+free monad
+\begin_inset Quotes erd
+\end_inset
+
+ organically by implementing embedded domain-specific languages (DSLs).
+ We consider two example DSLs: one for computations with complex numbers,
+ and another for reading files.
+ In the next few sections, we evolve the DSLs to make them type-safe and
+ to add the ability to bind variables to results of previous DSL computations.
+\end_layout
+
+\begin_layout Standard
+Refactoring the final code for the two DSLs, we divide the code into one
+ part that implements the custom DSL operations and another part performing
+ just the monadic functionality.
+ That second part is what is known as the
+\begin_inset Quotes eld
+\end_inset
+
+free monad
+\begin_inset Quotes erd
+\end_inset
+
+, meaning it is free from any domain-specific code.
+ This allows us to formulate a general recipe for creating DSL of this kind
+ and to write generic code that creates and runs DSL programs.
+\end_layout
+
+\begin_layout Standard
+We notice that the DSL type constructor looks like a monad but fails some
+ of the monad laws.
+ However, the monad laws hold after we apply a runner to a DSL program;
+ runners
+\begin_inset Quotes eld
+\end_inset
+
+hide
+\begin_inset Quotes erd
+\end_inset
+
+ law violations.
+ Because of that, using a law-violating DSL code is not problematic in practice.
+ Nevertheless, the code of the free monad can be modified so that the monad
+ laws hold.
+ We show that this actually simplifies the code as there are fewer case
+ classes needed.
+\end_layout
+
+\begin_layout Standard
+A monadic DSL can be evaluated (
+\begin_inset Quotes eld
+\end_inset
+
+run
+\begin_inset Quotes erd
+\end_inset
+
+) into another monad.
+ It turns out that the corresponding runner is
+\begin_inset Quotes eld
+\end_inset
+
+universal
+\begin_inset Quotes erd
+\end_inset
+
+ in that it works in the same way for all target monads.
+ We show how to implement a universal runner for monadic DSLs.
+ The universal runner translates a free monad's
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+pure
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+ operations into the corresponding operations of another monad.
+\end_layout
+
+\begin_layout Standard
+Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "sec:Different-encodings-of-free-monad"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ introduces the notion of an
+\begin_inset Quotes eld
+\end_inset
+
+encoding
+\begin_inset Quotes erd
+\end_inset
+
+ of the free monad.
+ In Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Motivation-free-monad-different-encodings"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+, we show that there have been different versions of
+\begin_inset Quotes eld
+\end_inset
+
+free monad
+\begin_inset Quotes erd
+\end_inset
+
+ presented in different sources.
+ Are these versions all correct, are they equivalent, or is one version
+ of a monadic DSL better than another? To resolve these questions, we look
+ at four different implementations (
+\begin_inset Quotes eld
+\end_inset
+
+encodings
+\begin_inset Quotes erd
+\end_inset
+
+) of a free monad and find out if they could be mapped to each other.
+ One of the encodings (the
+\begin_inset Quotes eld
+\end_inset
+
+raw tree
+\begin_inset Quotes erd
+\end_inset
+
+ encoding,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Free4
+\end_layout
+
+\end_inset
+
+) obeys
+\emph on
+none
+\emph default
+ of the monad laws while other encodings are smaller and do obey some of
+ the laws.
+ We show how one can derive a smaller (
+\begin_inset Quotes eld
+\end_inset
+
+reduced
+\begin_inset Quotes erd
+\end_inset
+
+) encoding from a larger one by imposing one of the monad laws.
+ We also show that smaller encodings have injective maps to larger ones.
+\end_layout
+
+\begin_layout Standard
+We take a digression to introduce the notion of existential type quantifiers
+ (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Types-with-existential-quantifiers"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ This is necessary in order to describe in a formal way the kinds of types
+ that free monad encodings require.
+ We show how existentially quantified types can be expressed through universal
+ quantifiers in Equations
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:existential-via-universal"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) and
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:existential-via-universal-Yoneda"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ Finally, we show that the
+\begin_inset Quotes eld
+\end_inset
+
+smallest
+\begin_inset Quotes erd
+\end_inset
+
+ free monad encoding (
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Free1
+\end_layout
+
+\end_inset
+
+) is equivalent to
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Free2
+\end_layout
+
+\end_inset
+
+ when
+\begin_inset Formula $F$
+\end_inset
+
+ is a functor.
+\end_layout
+
+\begin_layout Standard
+Having studied the free monad at length, we now turn to free constructions
+ for other typeclasses.
+ Before we generalize from the monad to other typeclasses, we need to understand
+ what general properties a free construction must satisfy.
+ To that end, Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "sec:Expected-properties-of-free-typeclass"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ examines the properties of the free monad construction and generalizes
+ those properties to other typeclasses.
+\end_layout
+
+\begin_layout Standard
+We introduce an important notion of a function that
+\begin_inset Quotes eld
+\end_inset
+
+preserves the typeclass operations
+\begin_inset Quotes erd
+\end_inset
+
+.
+ It is due to this property that a runner function removes monad law violations
+ in a free monad.
+
+\end_layout
+
+\begin_layout Standard
+With this motivation, we formulate laws that we expect to hold for other
+ free typeclass constructions.
+ Those laws are generally applicable for all typeclasses.
+\end_layout
+
+\begin_layout Standard
+Armed with this information, we proceed to show the types and the code for
+ various free typeclass constructions of different complexity.
+ For each typeclass, we will first construct the raw tree encoding
+\end_layout
+
+\begin_layout Standard
+The first example of a free typeclass is
+\begin_inset Quotes eld
+\end_inset
+
+free pointed type
+\begin_inset Quotes erd
+\end_inset
+
+ (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Free-pointed-type"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ We show that the properties of the free pointed type are a reformulation
+ of the properties of the standard
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Option
+\end_layout
+
+\end_inset
+
+ monad.
+\end_layout
+
+\begin_layout Standard
+Since a pointed type has no laws, the raw tree encoding is only one free
+ typeclass encoding for this typeclass.
+\end_layout
+
+\begin_layout Standard
+Next, we consider the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Semigroup
+\end_layout
+
+\end_inset
+
+ typeclass (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Free-semigroup"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ We begin by implementing the raw tree encoding and its evaluator.
+ Then we impose the associativity law and arrive at the reduced encoding.
+ We prove that the reduced encoding can be mapped (in several ways) to the
+ raw tree encoding, and all those maps are injective but do not preseve
+ the semigroup's methods.
+ The converse map (from the raw tree encoding to the reduced encoding) is
+ found as an application of the universal runner and preserves the semigroup's
+ methods.
+\end_layout
+
+\begin_layout Standard
+Later we will show that this situation is found in general for all FM-typeclasse
+s: a reduced encoding can be injected into the raw tree encoding by many
+ functions, neither of which preserves the typeclass methods.
+\end_layout
+
+\begin_layout Standard
+The next more complicated typeclass is
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Monoid
+\end_layout
+
+\end_inset
+
+ (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Free-monoids"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ We again start with the raw tree encoding and then discover several reduced
+ encodings by imposing different subsets of laws.
+ To illustrate the relationships between reduced encodings of a free typeclass,
+ we write down the code for 4 different encodings of the free monoid (denoted
+ by
+\begin_inset Formula $F_{1}$
+\end_inset
+
+,
+\begin_inset Formula $F_{2}$
+\end_inset
+
+,
+\begin_inset Formula $F_{3}$
+\end_inset
+
+,
+\begin_inset Formula $F_{4}$
+\end_inset
+
+).
+ We find that a given free monoid encoding can be injectively mapped into
+ any other encoding that obeys
+\emph on
+fewer
+\emph default
+ laws; but those injective maps do not preserve the monoid operations.
+ A given encoding may be mapped surjectively onto another encoding that
+ satisfies the same laws (and possibly more laws).
+\end_layout
+
+\begin_layout Standard
+As there are 3 monoid laws, we can construct 8 different free monoid encodings
+ that obey each of the 8 possible subsets of the three laws.
+ To illustrate the required techniques, we show two more encodings:
+\begin_inset Formula $F_{5}$
+\end_inset
+
+ obeying the left identity law and the associativity law, and
+\begin_inset Formula $F_{6}$
+\end_inset
+
+ obeying only the left identity law but no other monoid laws.
+\end_layout
+
+\begin_layout Standard
+***
+\end_layout
+
+\begin_layout Standard
+***
+\end_layout
+
+\begin_layout Subsection
+Chapter
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "chap:monad-transformers"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+This chapter is an in-depth study of monad transformers.
+\end_layout
+
+\begin_layout Standard
+To motivate monad transformers, we begin by trying to use two different
+ monads in a single functor block; we find that the code becomes hard to
+ work with.
+ The code can be simplified if we manage to combine two monads into a single
+ larger monad.
+ One way of combining monads is by functor composition, for example as
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Future[Option[A]]
+\end_layout
+
+\end_inset
+
+.
+ Table
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:Correct-and-incorrect-compositions"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ shows some examples of working and non-working functor composition of monads.
+ In some cases (such as Future and State), functor composition completely
+ fails.
+\end_layout
+
+\begin_layout Standard
+This suggests a different approach where one monad is fixed (the
+\begin_inset Quotes eld
+\end_inset
+
+base monad
+\begin_inset Quotes erd
+\end_inset
+
+
+\begin_inset Formula $L$
+\end_inset
+
+) and the other (
+\begin_inset Quotes eld
+\end_inset
+
+foreign
+\begin_inset Quotes erd
+\end_inset
+
+) monad
+\begin_inset Formula $M$
+\end_inset
+
+ is considered as a parameter.
+ This is known as the
+\begin_inset Quotes eld
+\end_inset
+
+monad transformer
+\begin_inset Quotes erd
+\end_inset
+
+ approach.
+ The result of combining
+\begin_inset Formula $L$
+\end_inset
+
+ and
+\begin_inset Formula $M$
+\end_inset
+
+ is a
+\begin_inset Quotes eld
+\end_inset
+
+larger
+\begin_inset Quotes erd
+\end_inset
+
+ monad (denoted by
+\begin_inset Formula $L\varangle M$
+\end_inset
+
+ in this book) that can express the effects of both monads
+\begin_inset Formula $L$
+\end_inset
+
+,
+\begin_inset Formula $M$
+\end_inset
+
+.
+ The
+\begin_inset Quotes eld
+\end_inset
+
+monad transformer
+\begin_inset Quotes erd
+\end_inset
+
+ of the base monad
+\begin_inset Formula $L$
+\end_inset
+
+ is the operation
+\begin_inset Formula $L\varangle$
+\end_inset
+
+ that can be applied to any foreign monad
+\begin_inset Formula $M$
+\end_inset
+
+ to obtain the new monad
+\begin_inset Formula $L\varangle M$
+\end_inset
+
+.
+ The code of
+\begin_inset Formula $L\varangle$
+\end_inset
+
+ is written once for every base monad
+\begin_inset Formula $L$
+\end_inset
+
+; the same code will then work for all foreign monads
+\begin_inset Formula $M$
+\end_inset
+
+.
+ This avoids the need for writing custom code that combines every pair of
+ monads.
+ Monad transformer code is written only once per base monad.
+
+\end_layout
+
+\begin_layout Standard
+Table
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:Known-monad-transformers"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ shows the types of monad transformers for a number of known monads.
+ Then we go through some examples, showing how monad transformers are implemente
+d in practice.
+\end_layout
+
+\begin_layout Standard
+In addition to having the code for the transformed monad
+\begin_inset Formula $L\varangle M$
+\end_inset
+
+, in practice one needs to be able to use the effects of each of the two
+ monads (
+\begin_inset Formula $L$
+\end_inset
+
+,
+\begin_inset Formula $M$
+\end_inset
+
+) within a functor block of type
+\begin_inset Formula $L\varangle M$
+\end_inset
+
+.
+ For that, we need functions that transform values of types
+\begin_inset Formula $L^{A}$
+\end_inset
+
+ and
+\begin_inset Formula $M^{A}$
+\end_inset
+
+ into values of type
+\begin_inset Formula $(L\varangle M)^{A}$
+\end_inset
+
+.
+ Those functions are called the
+\begin_inset Quotes eld
+\end_inset
+
+base lift
+\begin_inset Quotes erd
+\end_inset
+
+ (
+\begin_inset Formula $L\leadsto L\varangle M$
+\end_inset
+
+) and the
+\begin_inset Quotes eld
+\end_inset
+
+foreign lift
+\begin_inset Quotes erd
+\end_inset
+
+ (
+\begin_inset Formula $M\leadsto L\varangle M$
+\end_inset
+
+).
+
+\end_layout
+
+\begin_layout Standard
+In order to extract final results from monadic programs, one uses functions
+ called
+\begin_inset Quotes eld
+\end_inset
+
+runners
+\begin_inset Quotes erd
+\end_inset
+
+.
+ Those functions execute a monad's effects and deliver resulting values,
+ sometimes wrapped in another, simpler monad.
+ If we have runners for
+\begin_inset Formula $L$
+\end_inset
+
+ and
+\begin_inset Formula $M$
+\end_inset
+
+, we would need a way to obtain the corresponding runners for the combined
+ monad
+\begin_inset Formula $L\varangle M$
+\end_inset
+
+.
+ Showing examples with the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Reader
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+List
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+State
+\end_layout
+
+\end_inset
+
+, and some other monad transformers, we motivate introducing a
+\begin_inset Quotes eld
+\end_inset
+
+base runner
+\begin_inset Quotes erd
+\end_inset
+
+ (
+\begin_inset Formula $L\varangle M\leadsto M$
+\end_inset
+
+) and a
+\begin_inset Quotes eld
+\end_inset
+
+foreign runner
+\begin_inset Quotes erd
+\end_inset
+
+ (
+\begin_inset Formula $L\varangle M\leadsto L\varangle N$
+\end_inset
+
+).
+ Those runners execute the effects of one monad while keeping the effects
+ of another.
+
+\end_layout
+
+\begin_layout Standard
+Not all transformers support both lifts and both runners.
+ For instance, we show that the continuation monad's transformer does not
+ allow us to implement a base lift or any runners.
+\end_layout
+
+\begin_layout Standard
+The properties required for a monad transformer can be formulated by defining
+ a typeclass we denote
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+MTrans
+\end_layout
+
+\end_inset
+
+ (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:A-typeclass-for-monad-transformers"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+\end_layout
+
+\begin_layout Standard
+We turn to combining more than two monads, noticing that monad transformers
+ can be applied one after another; for example, as
+\begin_inset Formula $K\varangle(L\varangle M)$
+\end_inset
+
+ or as
+\begin_inset Formula $K\varangle(L\varangle(M\varangle N))$
+\end_inset
+
+.
+ The resulting combined monad is called a
+\begin_inset Quotes eld
+\end_inset
+
+monad stack
+\begin_inset Quotes erd
+\end_inset
+
+.
+ It is a new,
+\begin_inset Quotes eld
+\end_inset
+
+larger
+\begin_inset Quotes erd
+\end_inset
+
+ monad that can describe the effects of all its constituent monads (
+\begin_inset Formula $K$
+\end_inset
+
+,
+\begin_inset Formula $L$
+\end_inset
+
+,
+\begin_inset Formula $M$
+\end_inset
+
+, ...).
+\end_layout
+
+\begin_layout Standard
+We define monad transformer for the monad
+\begin_inset Formula $K\varangle L$
+\end_inset
+
+ by
+\begin_inset Formula $(K\varangle L)\varangle M\triangleq K\varangle(L\varangle M)$
+\end_inset
+
+.
+ This makes the operation
+\begin_inset Formula $\varangle$
+\end_inset
+
+ associative, so that we may write
+\begin_inset Formula $K\varangle L\varangle M$
+\end_inset
+
+ without ambiguity.
+ We also motivate the properties
+\begin_inset Formula $\text{Id}\varangle M\cong M$
+\end_inset
+
+ and
+\begin_inset Formula $M\varangle\text{Id}\cong M$
+\end_inset
+
+.
+ Later in this chapter we will rigorously prove those and other properties
+ for all known monad transformers.
+\end_layout
+
+\begin_layout Standard
+Building a monad stack in a different order (
+\begin_inset Formula $K\varangle L$
+\end_inset
+
+ or
+\begin_inset Formula $L\varangle K$
+\end_inset
+
+) will, as a rule, produce inequivalent monads.
+ Table
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:Examples-of-monad-stacks"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ shows some examples where transformers are applied in different orders.
+\end_layout
+
+\begin_layout Standard
+To write code in a large monad stack
+\begin_inset Formula $P\triangleq M_{1}\varangle M_{2}\varangle...\varangle M_{k}$
+\end_inset
+
+, we need functions that can lift any of the monads
+\begin_inset Formula $M_{i}$
+\end_inset
+
+ to the stack, as well as functions that run the effects of a certain monad
+
+\begin_inset Formula $M_{i}$
+\end_inset
+
+ while keeping all other effects.
+ We can construct the necessary lifts if all monads in the stack (except
+ possibly the last one,
+\begin_inset Formula $M_{k}$
+\end_inset
+
+) have transformers supporting their individual lift functions.
+ However, the resulting code is difficult to write because it is a composition
+ of up to
+\begin_inset Formula $k$
+\end_inset
+
+ individual lifts that have to be combined in exactly correct way.
+
+\end_layout
+
+\begin_layout Standard
+To make working with monad stacks easier, there are several techniques that
+ generate the necessary lifts automatically.
+ The first of these techniques (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Constructing-lifts-via-type-relations"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) obtains lifts from a type relation constructed automatically via typeclass
+ derivation.
+ The second of these techniques is known as MTL-style programming (
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Combining-monads-via-mtl-style"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ It requires the programmer to define a typeclass for each monad, encapsulating
+ the
+\begin_inset Quotes eld
+\end_inset
+
+operations
+\begin_inset Quotes erd
+\end_inset
+
+ that characterize working with that monad.
+ (Table
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:effectful-operations-for-some-monads"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ shows what those
+\begin_inset Quotes eld
+\end_inset
+
+operations
+\begin_inset Quotes erd
+\end_inset
+
+ are for a few well-known monads.) The programmer needs to write all code
+ in terms of those typeclasses and operations, rather than in terms of specific
+ monads.
+\end_layout
+
+\begin_layout Standard
+We turn to formulating the laws required of monad transformers.
+ We motivate those laws via examples of practical use.
+ Having obtained a large number of laws, we simplify and streamline their
+ formulations, using inspiration from category theory.
+ The result is a quip:
+\begin_inset Quotes eld
+\end_inset
+
+a monad transformer is a pointed endofunctor in the category of monads
+\begin_inset Quotes erd
+\end_inset
+
+ (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Category-theoretic-properties-of-lifts-and-runners-functors-in-category-of-monads"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ This formula expresses concisely the 18 laws of monad transformers that
+ we summarize in more detail in Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Laws-of-monad-transformers"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+The formulated laws can be verified for any given construction that is claimed
+ to give a monad transformer.
+ To illustrate that a law violation means failing to provide a required
+ functionality, we show a number of examples that do not satisfy the laws
+ of monad transformers.
+ In Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Examples-of-failure-of-generic-monad-transformer"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ we list several failing attempts to construct a general monad transformer
+ that could work for all monads at once.
+ Only one construction (the Church-encoded co-product in the category of
+ monads) satisfies all laws of a general transformer, but is unfortunately
+ unusable in mainstream programming languages due to lack of first-class
+ support for typeclass laws.
+\end_layout
+
+\begin_layout Standard
+In Sections
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Stacking-two-monads"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+–
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Stacking-any-number-of-monads"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ we prove that all laws hold for monad stacks involving any number of monads,
+ assuming that all the constituent monad transformers are lawful.
+\end_layout
+
+\begin_layout Standard
+The next sections will prove the laws for monad transformers of the individual
+ monads.
+ We begin with the
+\begin_inset Quotes eld
+\end_inset
+
+compositional
+\begin_inset Quotes erd
+\end_inset
+
+ transformers that work by composing the foreign monad as a functor either
+ inside or outside the base monad.
+ Both kinds of compositional transformers have common properties that we
+ begin to study in Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "sec:Monad-transformers-that-use-composition"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+ The key to simplifying the proofs for compositional transformers is to
+ consider the special
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+swap
+\end_layout
+
+\end_inset
+
+ function (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Motivation-for-the-swap-function"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ The required laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+swap
+\end_layout
+
+\end_inset
+
+ are motivated and derived in Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Deriving-the-necessary-laws-for-swap"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+ The laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+swap
+\end_layout
+
+\end_inset
+
+ are easier to verify for specific monads.
+ We show in Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Deriving-swap-from-flatten"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ that the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+swap
+\end_layout
+
+\end_inset
+
+ function is type-isomorphic to the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatten
+\end_layout
+
+\end_inset
+
+ method of the composed monad (either
+\begin_inset Formula $L\circ M$
+\end_inset
+
+ or
+\begin_inset Formula $M\circ L$
+\end_inset
+
+), assuming that their respective laws hold.
+
+\end_layout
+
+\begin_layout Standard
+We proceed to prove the laws of compositional monad transformers by assuming
+ that the laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+swap
+\end_layout
+
+\end_inset
+
+ already hold.
+ This proves at once the validity of all composed-inside and composed-outside
+ monad transformers.
+ It remains to verify the laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+swap
+\end_layout
+
+\end_inset
+
+ for specific monads.
+
+\end_layout
+
+\begin_layout Standard
+Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "sec:transformers-linear-monads"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ considers
+\begin_inset Quotes eld
+\end_inset
+
+linear monads
+\begin_inset Quotes erd
+\end_inset
+
+ (in the sense of being linear polynomials as functors) and proves that
+ the laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+swap
+\end_layout
+
+\end_inset
+
+ hold for those monads.
+ This covers
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Option
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Either
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Writer
+\end_layout
+
+\end_inset
+
+, and their compositions.
+\end_layout
+
+\begin_layout Standard
+Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "sec:transformers-rigid-monads"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ turns to monads whose transformers compose the foreign monad outside the
+ base monad.
+ Those monads are called
+\begin_inset Quotes eld
+\end_inset
+
+rigid
+\begin_inset Quotes erd
+\end_inset
+
+ in this book.
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+See the discussion here:
+\family typewriter
+
+\begin_inset CommandInset href
+LatexCommand href
+target "https://stackoverflow.com/questions/39649497/"
+literal "false"
+
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+ The only well-known example of a rigid monad is
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Reader
+\end_layout
+
+\end_inset
+
+.
+ To build up intuition, we show some type constructions that create new
+ rigid monads and obtain further examples.
+ Then we prove that the laws of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+swap
+\end_layout
+
+\end_inset
+
+ hold for all rigid monads.
+ This ensures the correctness of their monad transformers.
+\end_layout
+
+\begin_layout Standard
+Apart from functor composition, transformers for other monads do not follow
+ any general patterns.
+ The rest of the chapter goes over various known constructions that work
+ for specific kinds of monads.
+ The known patterns will be summarized in Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Summary-of-monad-transformer-constructions"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "sec:Transformers-for-products-and-free-pointed"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ proves the laws for transformers of product monads (see Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-monad-semimonad-product"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) and the
+\begin_inset Quotes eld
+\end_inset
+
+free pointed
+\begin_inset Quotes erd
+\end_inset
+
+ monads (see Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-co-product-with-identity-monad"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+
+\end_layout
+
+\begin_layout Standard
+Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "sec:Transformers-for-recursive-monads"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ proves the laws for transformers of two recursively defined monads.
+ One such monad is the
+\begin_inset Quotes eld
+\end_inset
+
+free monad
+\begin_inset Quotes erd
+\end_inset
+
+ on a given functor (see Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-monad-construction-4-free-monad"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ We also prove (Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-free-monad-transformer-coproduct"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) that two free monads combine via their transformers to a free monad on
+ a co-product of functors.
+ This is an important property that makes free monads easier to combine.
+\end_layout
+
+\begin_layout Standard
+The other recursive monad is the standard
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+List
+\end_layout
+
+\end_inset
+
+ monad whose associativity law was verified in Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-flatten-verify-for-monad-1-1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+ The
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+List
+\end_layout
+
+\end_inset
+
+ monad's transformer is complicated, and a proof of its laws takes some
+ work (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Transformer-for-the-List-monad"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+\end_layout
+
+\begin_layout Standard
+We now turn to
+\begin_inset Quotes eld
+\end_inset
+
+incomplete
+\begin_inset Quotes erd
+\end_inset
+
+ monad transformers that lack certain features.
+
+\end_layout
+
+\begin_layout Standard
+The first of those is the transformer for the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+State
+\end_layout
+
+\end_inset
+
+ monad (Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-state-monad-transformer"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ The only deficiency of the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+StateT
+\end_layout
+
+\end_inset
+
+ transformer is the violation of monad morphism laws by the base runner.
+ (This means that the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+StateT
+\end_layout
+
+\end_inset
+
+ transformer is a pointed but
+\emph on
+not
+\emph default
+ a co-pointed endofunctor in the category of monads.) Accordingly, running
+ a monadic program involving a
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+StateT
+\end_layout
+
+\end_inset
+
+ must run all
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+State
+\end_layout
+
+\end_inset
+
+ effects at once; it is incorrect to run the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+State
+\end_layout
+
+\end_inset
+
+ effects for parts of a program and then compose the results.
+\end_layout
+
+\begin_layout Standard
+The next sections prove the laws of the monad transformers for the continuation
+ monad, the generalized search monad, and the codensity monad.
+ Those transformers do not support base lifts, base runners, or foreign
+ runners; they are
+\emph on
+not
+\emph default
+ endofunctors in the category of monads.
+ Because of this, programmers cannot lift effects of different monads into
+ a transformed monad and cannot run effects in an arbitrary order unless
+ the problematic monads (continuation, search, codensity, etc.) are in the
+ deepest position in the monad stack.
+\end_layout
+
+\begin_layout Standard
+The chapter concludes by considering several directions of developing the
+ theory further:
+\end_layout
+
+\begin_layout Itemize
+Show some examples of monads that have more than one transformer.
+ As a rule, one transformer is complete and all others are incomplete.
+\end_layout
+
+\begin_layout Itemize
+Prove some general properties of monad morphisms that are useful for proofs
+ of laws of monad transformers.
+\end_layout
+
+\begin_layout Itemize
+\begin_inset Quotes eld
+\end_inset
+
+Rigid
+\begin_inset Quotes erd
+\end_inset
+
+ monad transformers are built via
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+swap
+\end_layout
+
+\end_inset
+
+ functions.
+ Do compositions of arbitrary rigid monads always have a corresponding
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+swap
+\end_layout
+
+\end_inset
+
+ function? This question is not yet fully answered (Problem
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "par:Problem-monads-5-1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+\end_layout
+
+\begin_layout Itemize
+The requirements for
+\begin_inset Quotes eld
+\end_inset
+
+rigid
+\begin_inset Quotes erd
+\end_inset
+
+ monads can be relaxed to yield
+\begin_inset Quotes eld
+\end_inset
+
+rigid
+\begin_inset Quotes erd
+\end_inset
+
+ functors.
+ We outline their properties and show some applications: the
+\begin_inset Quotes eld
+\end_inset
+
+functor-valued
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+flatMap
+\end_layout
+
+\end_inset
+
+
+\begin_inset Quotes erd
+\end_inset
+
+ and the
+\begin_inset Quotes eld
+\end_inset
+
+refactor-to-monad
+\begin_inset Quotes erd
+\end_inset
+
+ transformation.
+\end_layout
+
+\begin_layout Itemize
+The
+\begin_inset Quotes eld
+\end_inset
+
+MTL-style
+\begin_inset Quotes erd
+\end_inset
+
+ monadic programming can be made more general via the
+\begin_inset Quotes eld
+\end_inset
+
+monadically natural lifting
+\begin_inset Quotes erd
+\end_inset
+
+ of monad operations to monad stacks.
+ We prove the theoretical results underlying this technique.
+\end_layout
+
+\begin_layout Subsection
+Appendix
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "app:Proofs-of-naturality-parametricity"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+This appendix studies
+\begin_inset Quotes eld
+\end_inset
+
+parametricity properties
+\begin_inset Quotes erd
+\end_inset
+
+ that apply to all fully parametric code.
+ Those properties are a mathematical expression of the idea that a fully
+ parametric function works
+\begin_inset Quotes eld
+\end_inset
+
+in the same way
+\begin_inset Quotes erd
+\end_inset
+
+ for all types.
+ This appendix develops the necessary theory and technique to show how one
+ can prove a number of results used in other parts of the book.
+\end_layout
+
+\begin_layout Standard
+First, we show that a given type constructor may have at most one fully
+ parametric and lawful implementation of the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Functor
+\end_layout
+
+\end_inset
+
+ or
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Contrafunctor
+\end_layout
+
+\end_inset
+
+ typeclass instance.
+ (For most other typeclasses, such as
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Filterable
+\end_layout
+
+\end_inset
+
+ or
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Monad
+\end_layout
+
+\end_inset
+
+, type constructors often have several inequivalent and lawful typeclass
+ instances.) The unique implementations are used in the type constructions
+ shown in Sections
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:f-Functor-constructions"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ and
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:f-Contrafunctor-constructions"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+We show that the lifting methods of any fully parametric bifunctor or profunctor
+ will automatically obey the commutativity law such as Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:f-fmap-fmap-bifunctor-commutativity"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+
+\end_layout
+
+\begin_layout Standard
+Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "sec:Parametricity-theorem-for-relations"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ begins the study of the central theorem from which all applications of
+ parametricity will follow.
+ This theorem (the
+\begin_inset Quotes eld
+\end_inset
+
+parametricity theorem
+\begin_inset Quotes erd
+\end_inset
+
+) says that any fully parametric expression
+\begin_inset Formula $t:\forall A.\,Q^{A}$
+\end_inset
+
+ will automatically obey a certain relational naturality law, shown in Eq.
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:relational-naturality-law-1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+
+\end_layout
+
+\begin_layout Standard
+We explain how relations are defined and introduce certain combinators that
+ manipulate relations: the relational product, the relational co-product,
+ and the
+\begin_inset Quotes eld
+\end_inset
+
+pair mapper
+\begin_inset Quotes erd
+\end_inset
+
+ combinators.
+ Using those combinators and an important technical tool we call
+\begin_inset Quotes eld
+\end_inset
+
+simultaneous relational lifting
+\begin_inset Quotes erd
+\end_inset
+
+ (Definition
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Definition-simultaneous-relational-lifting"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+), Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Relational-parametricity-theorem"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ arrives at an inductive proof of the relational naturality law.
+
+\end_layout
+
+\begin_layout Standard
+The relational naturality law expresses a property of
+\emph on
+relations
+\emph default
+ (rather than functions) and is not always equivalent to any equation satisfied
+ by
+\begin_inset Formula $t$
+\end_inset
+
+.
+ Because of that, the relational naturality law is often hard to use directly.
+ Programmers are more interested in proving that a fully parametric function
+ satisfies some equation (a
+\begin_inset Quotes eld
+\end_inset
+
+law
+\begin_inset Quotes erd
+\end_inset
+
+).
+ Several shortcuts are available that, in most cases, quickly produce equational
+ laws automatically satisfied by fully parametric expressions.
+\end_layout
+
+\begin_layout Standard
+One shortcut is the dinaturality law
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:dinaturality-law-for-profunctors"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) obeyed by all fully parametric functions of type
+\begin_inset Formula $P^{A,A}\rightarrow Q^{A,A}$
+\end_inset
+
+ (where
+\begin_inset Formula $P$
+\end_inset
+
+,
+\begin_inset Formula $Q$
+\end_inset
+
+ are profunctors).
+ The form of the law depends only on the function's type signature and applies
+ to all fully parametric implementations of that type signature.
+ The dinaturality law is a generalization of the naturality law from type
+ signatures of the form
+\begin_inset Formula $F^{A}\rightarrow G^{A}$
+\end_inset
+
+ (where
+\begin_inset Formula $F$
+\end_inset
+
+ and
+\begin_inset Formula $G$
+\end_inset
+
+ are both covariant or both contravariant) to arbitrary type signatures
+ of the form
+\begin_inset Formula $P^{A,A}\rightarrow Q^{A,A}$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+Another useful shortcut the
+\begin_inset Quotes eld
+\end_inset
+
+strong dinaturality
+\begin_inset Quotes erd
+\end_inset
+
+ law
+\begin_inset space ~
+\end_inset
+
+(
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "eq:strong-dinaturality-law"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ That law holds whenever the type signature of
+\begin_inset Formula $t$
+\end_inset
+
+ satisfies the conditions of Statements
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-post-wedge-entails-strong-dinaturality"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ or
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-functor-post-pre-wedge"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+ Strong dinaturality gives more information than the ordinary dinaturality
+ law.
+\end_layout
+
+\begin_layout Standard
+The strong dinaturality law is the first of the parametricity techniques
+ that go beyond naturality laws and Yoneda identities.
+ Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Strong-dinaturality.-General-properties"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ is an in-depth study of strongly dinatural transformations.
+ We use structural analysis to look for possible function types
+\begin_inset Formula $P^{A,A}\rightarrow Q^{A,A}$
+\end_inset
+
+ for which the strong dinaturality law will hold.
+ The results of this analysis are used for proving properties of Church
+ encodings as well as in the proof of the type isomorphism between
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+foldMap
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+reduce
+\end_layout
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+Section
+\begin_inset space ~
+\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:f-Functor-constructions"
+reference "subsec:Universal-type-quantifiers"
plural "false"
caps "false"
noprefix "false"
\end_inset
- and
+ begins a further study of parametricity-based techniques for simplifying
+ types that contain universal quantifiers.
+ The Yoneda identities already provide such simplifications for a wide range
+ of such types, of which we show a number of examples.
+ We also show how the universal quantifier and the function types can encode
+ other type constructions (void type, unit type, products, co-products,
+ existentially quantified types, and recursive types).
+\end_layout
+
+\begin_layout Standard
+Category theory proves an abstract version of the Yoneda identity (the
+\begin_inset Quotes eld
+\end_inset
+
+Yoneda lemma
+\begin_inset Quotes erd
+\end_inset
+
+) for all categories.
+ The two Yoneda identities involving covariant and contravariant functors
+ are the most important practical applications of the Yoneda lemma to programmin
+g.
+ Other applications used in this book are Yoneda identities for type constructor
+s (see Section
\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:f-Contrafunctor-constructions"
+reference "subsec:The-Yoneda-identities-for-type-constructors"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+) and for lawful FM-typeclasses (used in Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:The-Jaskelioff-OConnor-theorem"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ in the proof of the Jaskelioff-O'Connor theorem).
+\end_layout
+
+\begin_layout Standard
+We turn to further applications of parametricity that go beyond what the
+ Yoneda identities can achieve.
+ Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:The-Church-encoding-of-recursive-types"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ gives full proofs of the Church encoding of a recursive type defined as
+ the least fixpoint (
+\begin_inset Formula $\mu A.\,F^{A}$
+\end_inset
+
+) of a pattern functor
+\begin_inset Formula $F$
+\end_inset
+
+.
+ It is also shown (Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-existence-of-church-encoding-type"
plural "false"
caps "false"
noprefix "false"
\end_inset
+) that the least fixpoint is non-void if and only if the type
+\begin_inset Formula $F^{\bbnum 0}$
+\end_inset
+
+ is non-void.
+ This section develops the machinery of
+\begin_inset Formula $F$
+\end_inset
+
+-functor algebras, catamorphisms, and defining the recursive type
+\begin_inset Formula $\mu A.\,F^{A}$
+\end_inset
+
+ via the standard functions
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+fix
+\end_layout
+
+\end_inset
+
+ and
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+unfix
+\end_layout
+
+\end_inset
+
.
\end_layout
\begin_layout Standard
-The lifting methods of any fully parametric bifunctor or profunctor obey
- the commutativity law such as Eq.
+Section
\begin_inset space ~
\end_inset
-(
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:f-fmap-fmap-bifunctor-commutativity"
+reference "subsec:The-Church-Yoneda-identity"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ proves a useful isomorphism that generalizes both the Church encoding and
+ the Yoneda identity:
+\begin_inset Formula
+\[
+G^{\mu A.\,F^{A}}\cong\forall A.\,(F^{A}\rightarrow A)\rightarrow G^{A}\quad.
+\]
+
+\end_inset
+
+In this book, this is called the
+\begin_inset Quotes eld
+\end_inset
+
+Church-Yoneda
+\begin_inset Quotes erd
+\end_inset
+
+ identity.
+ One application of that identity is in proving the
+\begin_inset Quotes eld
+\end_inset
+
+nested fixpoint lemma
+\begin_inset Quotes erd
+\end_inset
+
+ (Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-nested-fixpoints"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+):
+\begin_inset Formula
+\[
+\mu A.\,(\mu B.\,N^{A,B})\cong\mu B.\,N^{B,B}\quad.
+\]
+
+\end_inset
+
+Another is to establish the formula for the Church encoding of mutually
+ recursive types (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Least-fixpoints-of-mutually-recursive-types"
plural "false"
caps "false"
noprefix "false"
@@ -2930,156 +8345,230 @@ noprefix "false"
\end_inset
).
-
\end_layout
\begin_layout Standard
-Any fully parametric expression
-\begin_inset Formula $t:\forall A.\,Q^{A}$
+A general property of universal quantifiers is distributivity with respect
+ to products, co-products, and function types (Statement
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Statement-general-identities-forall"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+).
+ Distributivity with respect to co-products,
+\begin_inset Formula
+\[
+\forall A.\,F^{A}+G^{A}\cong(\forall A.\,F^{A})+(\forall A.\,G^{A})\quad,
+\]
+
+\end_inset
+
+can be generalized to the following isomorphism:
+\begin_inset Formula
+\[
+\forall A.\,P^{A}\rightarrow F^{A}+G^{A}\cong(\forall A.\,P^{A}\rightarrow F^{A})+(\forall A.\,P^{A}\rightarrow G^{A})\quad.
+\]
+
+\end_inset
+
+This holds for type constructors
+\begin_inset Formula $P$
+\end_inset
+
+ that are, in our terminology,
+\begin_inset Quotes eld
+\end_inset
+
+non-disjunctive
+\begin_inset Quotes erd
\end_inset
- satisfies the relational naturality law
+.
+ Section
\begin_inset space ~
\end_inset
-(
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:relational-naturality-law-1"
+reference "subsec:Non-disjunctive-type-constructors"
plural "false"
caps "false"
noprefix "false"
\end_inset
-).
- In general, the relational naturality law expresses a property of
-\emph on
-relations
-\emph default
- rather than functions and is not equivalent to any equation satisfied by
-
-\begin_inset Formula $t$
+ gives a formal definition of that property and goes through structural
+ analysis, discovering various non-disjunctive type constructors.
+ Some recipes for building non-disjunctive type constructors are shown in
+ Example
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-undisjunctive-type-constructors"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ and are generalized in Table
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "tab:Non-disjunctive-type-constructions"
+plural "false"
+caps "false"
+noprefix "false"
+
\end_inset
.
- The chapter explains how relations are defined and what operations are
- available for relations, and shows the proof of the relational naturality
- law.
\end_layout
\begin_layout Standard
-All fully parametric functions of type
-\begin_inset Formula $P^{A,A}\rightarrow Q^{A,A}$
+We turn to a brief study of existentially quantified types.
+ Section
+\begin_inset space ~
\end_inset
- (where
-\begin_inset Formula $P$
-\end_inset
-,
-\begin_inset Formula $Q$
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Existential-type-quantifiers"
+plural "false"
+caps "false"
+noprefix "false"
+
\end_inset
- are profunctors) obey the dinaturality law
+ proves the two co-Yoneda identities and establishes some other fundamental
+ properties of existential types.
+ Then Section
\begin_inset space ~
\end_inset
-(
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:dinaturality-law-for-profunctors"
+reference "subsec:The-greatest-fixpoints-and-Church-co-Yoneda"
plural "false"
caps "false"
noprefix "false"
\end_inset
-).
- The form of the law depends only on the function's type signature and applies
- to all fully parametric implementations of that type signature.
-\end_layout
+ shows that the greatest fixpoint of a functor
+\begin_inset Formula $F$
+\end_inset
+
+ is given by the Church encoding:
+\begin_inset Formula
+\[
+\nu A.\,F^{A}\cong\exists A.\,(A\rightarrow F^{A})\times A\quad,
+\]
+
+\end_inset
+
+and also proves the Church-co-Yoneda identity: for any functors
+\begin_inset Formula $F$
+\end_inset
+
+ and
+\begin_inset Formula $G$
+\end_inset
+
+,
+\begin_inset Formula
+\[
+G^{\nu A.\,F^{A}}\cong\exists A.\,(A\rightarrow F^{A})\times G^{A}\quad.
+\]
-\begin_layout Standard
-If the type signature of
-\begin_inset Formula $t$
\end_inset
- satisfies the conditions of Statements
+This identity allows us to derive the nested fixpoint lemma and the mutual
+ recursion formula for the greatest fixpoints.
+\end_layout
+
+\begin_layout Standard
+These techniques allow us to derive a number of properties for types with
+ universal and existential quantifiers.
+ Tables
\begin_inset space ~
\end_inset
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-post-wedge-entails-strong-dinaturality"
+reference "tab:Type-identities-proved-by-Yoneda"
plural "false"
caps "false"
noprefix "false"
\end_inset
- or
-\begin_inset space ~
-\end_inset
-
-
+–
\begin_inset CommandInset ref
LatexCommand ref
-reference "subsec:Statement-functor-post-pre-wedge"
+reference "tab:Type-identities-for-existential-types"
plural "false"
caps "false"
noprefix "false"
\end_inset
-, the function
-\begin_inset Formula $t$
-\end_inset
-
- satisfies the
-\begin_inset Quotes eld
-\end_inset
+ summarize the type isomorphisms proved in this Appendix by various techniques.
+\end_layout
-strong dinaturality
-\begin_inset Quotes erd
+\begin_layout Standard
+The final sections of the Appendix study the Jaskelioff-O'Connor theorem
+ and its applications to problems raised in this book.
+ One of those applications is a proof that the identity function of type
+
+\begin_inset Formula $\forall A.\,M^{A}\rightarrow M^{A}$
\end_inset
- law
-\begin_inset space ~
+ is the only monad morphism between a monad
+\begin_inset Formula $M$
\end_inset
-(
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "eq:strong-dinaturality-law"
-plural "false"
-caps "false"
-noprefix "false"
-
+ and itself that obeys the monadic naturality law with respect to
+\begin_inset Formula $M$
\end_inset
-).
- Strong dinaturality gives more information than the ordinary dinaturality
- law and is simpler to use than the general relational naturality law
+.
+ This property means that the non-degeneracy law of base runners (derived
+ in Chapter
\begin_inset space ~
\end_inset
-(
+
\begin_inset CommandInset ref
LatexCommand ref
-reference "eq:relational-naturality-law-1"
+reference "chap:monad-transformers"
plural "false"
caps "false"
noprefix "false"
\end_inset
-).
-\end_layout
-
-\begin_layout Standard
-***
+) is always satisfied automatically and does not need to be verified separately
+ for each monad transformer.
\end_layout
\begin_layout Standard
@@ -3105,7 +8594,7 @@ Restore the normal numbering of subsections and subsubsections
\end_inset
-
+)
\end_layout
\begin_layout Section
@@ -3124,8 +8613,8 @@ Trampolines and stack-safe recursion in functor blocks
\end_layout
\begin_layout Standard
-Recursion with applicative and monadic functors (say, a loop with the free
- monad) can lead to stack overflows when the nesting of
+Recursion with applicative and monadic functors (say, a loop within the
+ free monad) can lead to stack overflows when the nesting of
\begin_inset listings
inline true
status open
@@ -3164,11 +8653,11 @@ Functional programming in Scala
\end_inset
.
- Stack-safe implementations of standard monads have better performance but
- are mathematically equivalent to the same monads implemented via simple,
- non-stack-safe code.
- There is no new theory to be developed and no new laws to be proved about
- code that is specially engineered to be stack-safe.
+ Stack-safe implementations of standard monads are complicated but are mathemati
+cally equivalent to the same monads implemented via simple, non-stack-safe
+ code.
+ There is no new theory to be found and no new laws to be proved about code
+ that is specially engineered to be stack-safe.
\end_layout
\begin_layout Subsection
@@ -3262,7 +8751,7 @@ status open
\begin_layout Plain Layout
-Filterable
+Monad
\end_layout
\end_inset
@@ -3274,7 +8763,7 @@ status open
\begin_layout Plain Layout
-Monad
+Filterable
\end_layout
\end_inset
@@ -3489,7 +8978,7 @@ duplicate
\end_inset
The type signatures of those methods are similar to the type signatures
- of the monads' methods
+ of the monadic methods
\begin_inset listings
inline true
status open
@@ -3513,7 +9002,7 @@ flatten
\end_inset
- except that the function arrows point in the opposite direction:
+, except that the function arrows point in the opposite direction:
\begin_inset Formula
\[
\text{pu}_{F}:\forall A.\,A\rightarrow F^{A}\quad,\quad\quad\text{ftn}_{F}:\forall A.\,F^{F^{A}}\rightarrow F^{A}\quad.
@@ -3521,16 +9010,39 @@ flatten
\end_inset
-The comonad's methods must also satisfy the appropriate laws.
- Similarly to monads, two comonads can be combined via
+The
\begin_inset Quotes eld
\end_inset
-comonad transformers
+co-Kleisli
\begin_inset Quotes erd
\end_inset
- into a larger comonad.
+ functions have type
+\begin_inset Formula $F^{A}\rightarrow B$
+\end_inset
+
+ and are composed via the
+\begin_inset Quotes eld
+\end_inset
+
+co-Kleisli composition
+\begin_inset Quotes erd
+\end_inset
+
+ operation that has the type signature:
+\begin_inset Formula
+\[
+(F^{A}\rightarrow B)\rightarrow(F^{B}\rightarrow C)\rightarrow F^{A}\rightarrow C\quad.
+\]
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+The comonad's methods must also satisfy the appropriate laws.
An example of a comonad is the non-empty list (
\begin_inset listings
inline true
@@ -3544,6 +9056,51 @@ NEL
\end_inset
).
+ Some comonads are analogous to known monads: for instance, there is a
+\begin_inset Quotes eld
+\end_inset
+
+reader comonad
+\begin_inset Quotes erd
+\end_inset
+
+
+\begin_inset Formula $F^{A}=R\rightarrow A$
+\end_inset
+
+ (where
+\begin_inset Formula $R$
+\end_inset
+
+ needs to be a monoid), the
+\begin_inset Quotes eld
+\end_inset
+
+writer comonad
+\begin_inset Quotes erd
+\end_inset
+
+
+\begin_inset Formula $F^{A}\triangleq A\times W$
+\end_inset
+
+ (this time,
+\begin_inset Formula $W$
+\end_inset
+
+ does not need to be a monoid), and the
+\begin_inset Quotes eld
+\end_inset
+
+store comonad
+\begin_inset Quotes erd
+\end_inset
+
+
+\begin_inset Formula $F^{A}\triangleq S\times(S\rightarrow A)$
+\end_inset
+
+.
There is also a
\begin_inset Quotes eld
\end_inset
@@ -3552,7 +9109,16 @@ co-free comonad
\begin_inset Quotes erd
\end_inset
- construction, similar to the free monad.
+ construction, similarly to the free monad construction.
+ Similarly to monads, two comonads can be combined via
+\begin_inset Quotes eld
+\end_inset
+
+comonad transformers
+\begin_inset Quotes erd
+\end_inset
+
+ into a larger comonad.
\end_layout
\begin_layout Standard
@@ -3686,7 +9252,38 @@ Effect systems
\begin_layout Standard
Algebraic effects are currently an active topic of research and experimentation.
- The basic idea of an effect system is to use type signatures that indicate
+ Programming with
+\begin_inset Quotes eld
+\end_inset
+
+effects
+\begin_inset Quotes erd
+\end_inset
+
+ and
+\begin_inset Quotes eld
+\end_inset
+
+handlers
+\begin_inset Quotes erd
+\end_inset
+
+ is intended to replace the monad-based design patterns and in particular
+ avoid the need for monad transformers, which have proved to be complicated
+ and hard to use.
+ Effect systems can be viewed also as a way of incorporating the
+\begin_inset Quotes eld
+\end_inset
+
+free monad
+\begin_inset Quotes erd
+\end_inset
+
+ design pattern more directly into a programming language.
+\end_layout
+
+\begin_layout Standard
+The basic idea of an effect system is to use type signatures that indicate
precisely what side effects a function may execute when it is evaluated.
For instance, there is one effect type for printing to the console, another
effect type for querying a database, yet another for running code via parallel
@@ -3834,6 +9431,90 @@ literal "false"
will gain wide use.
\end_layout
+\begin_layout Subsection
+Programming language theory
+\end_layout
+
+\begin_layout Standard
+Certain theoretical questions are of interest to designers of programming
+ languages but not to users of those languages.
+ Here are some examples of such questions:
+\end_layout
+
+\begin_layout Itemize
+Proving that type inference and type checking are terminating procedures.
+\end_layout
+
+\begin_layout Itemize
+Proving that evaluation will be always error-free once an expression has
+ been type-checked.
+ (
+\begin_inset Quotes eld
+\end_inset
+
+Soundness
+\begin_inset Quotes erd
+\end_inset
+
+ of the type system.)
+\end_layout
+
+\begin_layout Itemize
+Proving that evaluating an expression will always give the same results
+ regardless of which part of the expression is evaluated first; or providing
+ precise conditions for that to be true.
+\end_layout
+
+\begin_layout Itemize
+Proving that composition of functions is associative by using a rigorous
+ definition of what it means for functions to be equal.
+\end_layout
+
+\begin_layout Itemize
+Defining a rigorous mathematical semantics for each construction of a programmin
+g language and proving its properties (for example, that it is equivalent,
+ or not equivalent, to the semantics of some other language).
+\end_layout
+
+\begin_layout Standard
+This book does not pursue those topics.
+\end_layout
+
+\begin_layout Subsection
+Bibliography
+\end_layout
+
+\begin_layout Standard
+This book does not include a list of references at the end.
+ Instead, throughout the book there are footnote references to books, papers,
+ video presentations, and blog posts that have some relevance to the material
+ being discussed.
+
+\end_layout
+
+\begin_layout Standard
+The lack of bibliography is appropriate because this book is a pedagogical
+ tutorial, not an academic treatise.
+ One of the purposes of an academic treatise is to demonstrate ample continuity
+ with previously published research.
+ An academic bibliography helps reviewers understand in what new direction
+ the presented research goes, without having to read the text itself.
+ It also helps other academic authors whose career depends on increased
+ citation counts.
+ For those purposes, it is convenient to see a bibliography showing tens
+ or hundreds of references to established academic literature.
+\end_layout
+
+\begin_layout Standard
+In contrast, the vision of this book is to present a sequence of pedagogically
+ accessible steps that will help readers to learn the theoretical material
+ relevant for the practice of functional programming.
+ All explanations are self-contained; it is not assumed that the reader
+ will first learn from some other books or papers on FP before embarking
+ on this book.
+ So, a bibliography section will not help the readers.
+\end_layout
+
\begin_layout Section
Additional exercises and open problems
\begin_inset CommandInset label
@@ -5738,7 +11419,7 @@ noprefix "false"
status open
\begin_layout Plain Layout
-This was an open problem but it was solved by Hew Wolff.
+This was an open problem solved in 2024 by Hew Wolff (private communication).
\end_layout
\end_inset
@@ -5958,87 +11639,24 @@ status open
\begin_layout Plain Layout
-Traversable
-\end_layout
-
-\end_inset
-
- instances for
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-
-Triang
-\end_layout
-
-\end_inset
-
-.
-\end_layout
-
-\begin_layout Subsubsection
-Exercise
-\begin_inset CommandInset label
-LatexCommand label
-name "par:Exercise-additional-15"
-
-\end_inset
-
-
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "par:Exercise-additional-15"
-plural "false"
-caps "false"
-noprefix "false"
-
-\end_inset
-
-
-\end_layout
-
-\begin_layout Standard
-Simplify the type
-\begin_inset Formula $\forall A.\,((A\rightarrow A)\rightarrow A)\rightarrow A$
-\end_inset
-
-, or in Scala:
-\begin_inset listings
-inline false
-status open
-
-\begin_layout Plain Layout
-
-def f[A]: ((A => A) => A) => A
-\end_layout
-
-\end_inset
-
-into a type expression that contains no quantifiers.
- Show how to implement all possible values of this type.
-
-\begin_inset Foot
-status open
-
-\begin_layout Plain Layout
-See
-\family typewriter
-
-\begin_inset CommandInset href
-LatexCommand href
-target "https://cstheory.stackexchange.com/questions/53855/"
-literal "false"
+Traversable
+\end_layout
\end_inset
+ instances for
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+Triang
\end_layout
\end_inset
-
+.
\end_layout
\begin_layout Subsubsection
@@ -6172,14 +11790,15 @@ noprefix "false"
\end_layout
\begin_layout Standard
-Prove the following type equivalences (assuming a fixed type
+Prove the following type equivalences (here
\begin_inset Formula $P$
\end_inset
-):
+ is a fixed type):
\end_layout
\begin_layout Standard
+\align center
\begin_inset Tabular
@@ -6435,7 +12054,7 @@ where
is any covariant functor.
\begin_inset Note Note
-status collapsed
+status open
\begin_layout Plain Layout
Use the Yoneda identities:
@@ -6481,7 +12100,7 @@ not
).
\begin_inset Note Note
-status collapsed
+status open
\begin_layout Plain Layout
If
@@ -6572,7 +12191,7 @@ Show that for any covariant functor
, the following Yoneda-like formula holds:
\begin_inset Note Note
-status collapsed
+status open
\begin_layout Plain Layout
Solution
@@ -6603,6 +12222,122 @@ G^{\exists C.\,F^{C}}\cong\forall D.\,(\forall C.\,F^{C}\rightarrow D)\rightarro
\end_inset
+\end_layout
+
+\begin_layout Subsubsection
+Exercise
+\begin_inset CommandInset label
+LatexCommand label
+name "par:Exercise-additional-16-3-1"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "par:Exercise-additional-16-3-1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+This is a generalization of Example
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-strong-dinaturality-show-void"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(a)
+\series default
+ For any (covariant) functors
+\begin_inset Formula $F$
+\end_inset
+
+ and
+\begin_inset Formula $G$
+\end_inset
+
+, show that:
+\begin_inset Formula
+\[
+\forall A.\,(A\times G^{A}\rightarrow A)\rightarrow F^{A}\cong F^{\bbnum 0}\quad.
+\]
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\series bold
+(b)
+\series default
+ For any contrafunctor
+\begin_inset Formula $H$
+\end_inset
+
+ and a type constructor
+\begin_inset Formula $G$
+\end_inset
+
+ that is either covariant or contravariant, show that:
+\begin_inset Formula
+\[
+\forall A.\,(G^{A}\rightarrow A)\rightarrow H^{A}\cong H^{\bbnum 1}\quad.
+\]
+
+\end_inset
+
+
+\begin_inset Note Note
+status open
+
+\begin_layout Plain Layout
+Follow the proof of that example.
+ Since
+\begin_inset Formula $G$
+\end_inset
+
+ is either covariant or contravariant, we can use the strong dinaturality
+ law.
+ The same
+\begin_inset Formula $f$
+\end_inset
+
+,
+\begin_inset Formula $p$
+\end_inset
+
+,
+\begin_inset Formula $q$
+\end_inset
+
+ will work.
+\end_layout
+
+\end_inset
+
+
\end_layout
\begin_layout Subsubsection
@@ -7207,7 +12942,8 @@ such that that suitable laws hold:
\begin_inset Formula
\begin{align*}
\text{naturality-identity law}:\quad & \text{liftE}_{S}^{A,B,R}(f^{:A\rightarrow B}\bef\text{pu}_{\text{Opt}}^{B})=f^{\uparrow S^{\bullet,R}}\bef(s^{:S^{B,R}}\rightarrow\bbnum 0^{:R}+s)\quad,\\
-\text{composition law}:\quad & \text{liftE}_{S}^{A,B,R}(f^{:A\rightarrow\bbnum 1+B})\bef\,???\,\bef\text{liftE}_{S}^{B,C,R}(g^{:B\rightarrow\bbnum 1+C})=\text{liftE}_{S}^{A,C,R}(f\diamond_{_{\text{Opt}}}g)\quad,\\
+\text{composition law}:\quad & \text{liftE}_{S}^{A,B,R}(f^{:A\rightarrow\bbnum 1+B})\bef\,???\,\bef\text{liftE}_{S}^{B,C,R}(g^{:B\rightarrow\bbnum 1+C})\\
+ & \quad=\text{liftE}_{S}^{A,C,R}(f\diamond_{_{\text{Opt}}}g)\quad,\\
\text{naturality law in }R:\quad & (g^{:Q\rightarrow R})^{\uparrow S^{A,\bullet}}\bef\text{liftE}_{S}^{A,B,R}(f)=\text{liftE}_{S}^{A,B,Q}(f)\bef g^{\uparrow U^{B,\bullet}}\quad.
\end{align*}
@@ -8442,8 +14178,16 @@ For certain monads
\begin_inset Formula $L$
\end_inset
-, the monad transformers
-\begin_inset Formula $T_{L}$
+ (such as the
+\begin_inset Quotes eld
+\end_inset
+
+rigid
+\begin_inset Quotes erd
+\end_inset
+
+ monads), the corresponding monad transformers
+\begin_inset Formula $L\varangle$
\end_inset
can be defined using a suitable
@@ -8815,7 +14559,7 @@ ListT
\end_inset
- (here denoted just by
+ (here denoted by
\begin_inset Formula $T$
\end_inset
@@ -8941,13 +14685,14 @@ brunE
(which is also a monoid type):
\begin_inset Formula
-\[
-\text{brunE}:M^{L^{R}}\rightarrow M^{R}\quad,\quad\quad\text{brunE}\triangleq\text{flm}_{M}\bigg(\,\begin{array}{|c||c|}
+\begin{align*}
+ & \text{brunE}:M^{L^{R}}\rightarrow M^{R}\quad,\\
+ & \text{brunE}\triangleq\text{flm}_{M}\bigg(\,\begin{array}{|c||c|}
& M^{R}\\
\hline \bbnum 1 & 1\rightarrow\text{pu}_{M}(e_{R})\\
R\times M^{L^{R}} & h\times t\rightarrow\text{pu}_{M}(h)\oplus_{M}\overline{\text{brunE}}\,(t)
\end{array}\,\bigg)\quad.
-\]
+\end{align*}
\end_inset
@@ -9045,21 +14790,7 @@ brunE
\end_inset
-(If so, Exercise
-\begin_inset space ~
-\end_inset
-
-
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "subsec:Exercise-traversables-10-1"
-plural "false"
-caps "false"
-noprefix "false"
-
-\end_inset
-
- would show that
+(If so,
\begin_inset listings
inline true
status open
@@ -9071,12 +14802,26 @@ brunE
\end_inset
- is also a
+ will be also a
\emph on
monoid
\emph default
morphism
\begin_inset Formula $M^{L^{A}}\rightarrow M^{A}$
+\end_inset
+
+ by Exercise
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Exercise-traversables-10-1"
+plural "false"
+caps "false"
+noprefix "false"
+
\end_inset
.)
@@ -9315,8 +15060,10 @@ shift
are defined by:
\begin_inset Formula
\begin{align*}
- & \text{reset}:\forall S.\,\text{Cont}^{R,R}\rightarrow\text{Cont}^{S,R}\quad,\quad\quad\text{reset}\triangleq c^{:\left(R\rightarrow R\right)\rightarrow R}\rightarrow k^{:R\rightarrow S}\rightarrow k(c(\text{id}))\quad,\\
- & \text{shift}:\forall A.\,((A\rightarrow R)\rightarrow\text{Cont}^{R,R})\rightarrow\text{Cont}^{R,A}\quad,\quad\quad\text{shift}\triangleq g^{:\left(A\rightarrow R\right)\rightarrow\text{Cont}^{R,R}}\rightarrow k^{:A\rightarrow R}\rightarrow g(k)(\text{id})\quad.
+ & \text{reset}:\forall S.\,\text{Cont}^{R,R}\rightarrow\text{Cont}^{S,R}\quad,\\
+ & \text{reset}\triangleq c^{:\left(R\rightarrow R\right)\rightarrow R}\rightarrow k^{:R\rightarrow S}\rightarrow k(c(\text{id}))\quad,\\
+ & \text{shift}:\forall A.\,((A\rightarrow R)\rightarrow\text{Cont}^{R,R})\rightarrow\text{Cont}^{R,A}\quad,\\
+ & \text{shift}\triangleq g^{:\left(A\rightarrow R\right)\rightarrow\text{Cont}^{R,R}}\rightarrow k^{:A\rightarrow R}\rightarrow g(k)(\text{id})\quad.
\end{align*}
\end_inset
@@ -9625,6 +15372,21 @@ where functions of type
\end_inset
are required to be fully parametric.
+\begin_inset Note Note
+status open
+
+\begin_layout Plain Layout
+(solved by transitive closure union of relations?) Do I actually have a
+ solution for this?
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+An equivalent statement
\begin_inset Foot
status open
@@ -9644,7 +15406,60 @@ literal "false"
\end_inset
+ is:
+\begin_inset Formula
+\[
+\forall A.\,F^{A\rightarrow A}\cong F^{\bbnum 1}
+\]
+
+\end_inset
+
+for any covariant functor
+\begin_inset Formula $F$
+\end_inset
+
+, under assumptions of parametricity.
+ (Use this isomorphism with
+\begin_inset Formula $F^{A}\triangleq(A\rightarrow P)\rightarrow Q$
+\end_inset
+
+ to obtain the previous formula.)
+\end_layout
+
+\begin_layout Standard
+Note that the last identity already holds for any
+\emph on
+strictly
+\emph default
+
+\emph on
+positive
+\emph default
+
+\begin_inset Formula $F$
+\end_inset
+
+; see Example
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Example-simplify-quantifier-A-A"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+(a).
+ Solving this problem would show if that identity holds for all covariant
+ functors
+\begin_inset Formula $F$
+\end_inset
+ (not necessarily strictly positive).
\end_layout
\begin_layout Standard
@@ -9657,17 +15472,70 @@ P\cong\exists A.\,(A\rightarrow A)\rightarrow P\quad.
\end_inset
-\begin_inset Note Note
-status open
+\end_layout
-\begin_layout Plain Layout
-(solved by transitive closure union of relations?) Do I actually have a
- solution for this?
+\begin_layout Subsubsection
+Problem
+\begin_inset CommandInset label
+LatexCommand label
+name "par:Problem-Peirce-law-1-1"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "par:Problem-Peirce-law-1-1"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Consider the following type isomorphisms:
+\begin_inset Formula
+\begin{align*}
+ & \forall A.\,\forall B.\,F^{A\times B}\cong\forall C.\,F^{C}\quad,\\
+ & \forall A.\,\forall B.\,F^{A+B}\cong\forall C.\,F^{C}\quad,\\
+ & \forall A.\,\forall B.\,F^{A\rightarrow B}\cong\forall C.\,F^{C}\quad.
+\end{align*}
+
+\end_inset
+
+For which
+\begin_inset Formula $F$
+\end_inset
+
+ do they hold or fail to hold (assuming parametricity)?
\end_layout
+\begin_layout Standard
+The question is easy to decide when
+\begin_inset Formula $F$
+\end_inset
+
+ is purely covariant or purely contravariant.
+ In those cases, all isomorphisms hold except for the one with
+\begin_inset Formula $F^{A+B}$
\end_inset
+ when
+\begin_inset Formula $F$
+\end_inset
+
+ is contravariant.
+\end_layout
+
+\begin_layout Standard
+The question remains open when
+\begin_inset Formula $F$
+\end_inset
+ is neither covariant nor contravariant.
\end_layout
\end_body
diff --git a/sofp-src/lyx/sofp-transformers.lyx b/sofp-src/lyx/sofp-transformers.lyx
index 71c9a04b2..3045be3c8 100644
--- a/sofp-src/lyx/sofp-transformers.lyx
+++ b/sofp-src/lyx/sofp-transformers.lyx
@@ -338,7 +338,7 @@ Combining monadic effects via functor composition
\begin_layout Standard
Monads describe effects that depend on previously computed values.
- It is often necessary to combine effects of several monads in one.
+ It is often necessary to combine effects of several monads.
For example, the effect of
\begin_inset listings
inline true
@@ -612,8 +612,7 @@ Future[Option[A]]
\end_inset
.
- The code is repetitive and deeply nested, which makes it hard to read and
- to change.
+ The code is repetitive and deeply nested, which makes it hard to work with.
\end_layout
@@ -10622,6 +10621,13 @@ Throughout this chapter, we will build transformers for every monad considered
\begin_layout Subsection
A typeclass for monad transformers
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:A-typeclass-for-monad-transformers"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -10724,8 +10730,13 @@ texttt{'}$s typeclass instance must be defined elsewhere.
\begin_layout Plain Layout
-trait MTrans[T[_[_]]] { // The type parameter T is a type constructor
- with 2 parameters.
+trait MTrans[T[_[_]]] { // The type parameter T has kind $(*
+\backslash
+rightarrow*)
+\backslash
+rightarrow *
+\backslash
+rightarrow*$.
\end_layout
\begin_layout Plain Layout
@@ -10761,12 +10772,31 @@ The transformer's code is parametric in the foreign monad
\begin_inset Formula $M$
\end_inset
- (but not in the base monad
+ but not in the base monad
\begin_inset Formula $L$
\end_inset
-).
- Although
+; in fact, the code of
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+MTrans
+\end_layout
+
+\end_inset
+
+ does not refer to
+\begin_inset Formula $L$
+\end_inset
+
+ at all.
+\end_layout
+
+\begin_layout Standard
+Although
\begin_inset listings
inline true
status open
@@ -11427,7 +11457,7 @@ Having computed a value of type, say,
runners, we can run the effects of any chosen monad, e.g., like this:
\begin_inset Formula
\[
-\text{frun}_{K}^{L\varangle M\varangle N}(\text{frun}_{L}^{M\varangle N}(\text{brun}_{M}^{N}(\theta_{M}))):K\varangle L\varangle M\varangle N\leadsto K\varangle L\varangle N\quad.
+\text{frun}_{K}^{L\varangle M\varangle N,L\varangle N}(\text{frun}_{L}^{M\varangle N,N}(\text{brun}_{M}^{N}(\theta_{M}))):K\varangle L\varangle M\varangle N\leadsto K\varangle L\varangle N\quad.
\]
\end_inset
@@ -22634,6 +22664,13 @@ Motivation for the
swap
\family default
function
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Motivation-for-the-swap-function"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -23480,7 +23517,14 @@ swap
\end_layout
\begin_layout Subsection
-Deriving the necessary laws for
+Deriving the necessary laws
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Deriving-the-necessary-laws-for-swap"
+
+\end_inset
+
+ for
\family typewriter
swap
\end_layout
@@ -29600,18 +29644,6 @@ monads!linear
of the form
\begin_inset Formula $M^{A}=P+Q\times A$
-\end_inset
-
- and
-\begin_inset Formula $M^{A}=Q\times\left(P+A\right)$
-\end_inset
-
-, called
-\begin_inset Quotes eld
-\end_inset
-
-linear
-\begin_inset Quotes erd
\end_inset
.
@@ -29635,6 +29667,17 @@ status open
\begin_layout Plain Layout
Monads of this kind do not seem to have an already accepted name.
+ See the discussion here:
+\family typewriter
+
+\begin_inset CommandInset href
+LatexCommand href
+target "https://stackoverflow.com/questions/39649497/"
+literal "false"
+
+\end_inset
+
+
\end_layout
\end_inset
@@ -29779,7 +29822,7 @@ literal "false"
\end_inset
-
+ for a discussion of the selector monad.
\end_layout
\end_inset
@@ -32451,6 +32494,13 @@ choice
\begin_layout Section
Transformers for other monad constructions
+\begin_inset CommandInset label
+LatexCommand label
+name "sec:Transformers-for-products-and-free-pointed"
+
+\end_inset
+
+
\end_layout
\begin_layout Subsection
@@ -35841,6 +35891,13 @@ This derivation concludes the proof of the laws of the free pointed monad
\begin_layout Section
Transformers for recursive monads
+\begin_inset CommandInset label
+LatexCommand label
+name "sec:Transformers-for-recursive-monads"
+
+\end_inset
+
+
\end_layout
\begin_layout Subsection
@@ -35960,7 +36017,7 @@ Monad laws
\end_layout
\begin_layout Standard
-Heuristically we may say that the recursively defined type
+Heuristically we may that the recursively defined type
\begin_inset Formula $(\text{Free}\varangle M)^{A}$
\end_inset
@@ -37018,12 +37075,12 @@ To implement the base runner, we use the similarity between the two disjunctive
types:
\begin_inset Formula
\[
-L^{A}\triangleq\text{Free}^{F\circ M,A}=A+F^{M^{\text{Free}^{F\circ M,A}}}=A+(F\circ M\circ L)^{A}\:\text{ and }\:\text{Free}^{F,M^{A}}=M^{A}+F^{\text{Free}^{F,M^{A}}}\quad.
+L^{A}\triangleq\text{Free}^{F\circ M,A}=A+F^{M^{\text{Free}^{F\circ M,A}}}=A+(F\circ M\circ L)^{A}\text{ and }\text{Free}^{F,M^{A}}=M^{A}+F^{\text{Free}^{F,M^{A}}}\quad.
\]
\end_inset
-The code for the base runner is:
+ The code for the base runner is:
\begin_inset Formula
\begin{align*}
& \text{brun}:(\text{Free}^{F}\leadsto\text{Id})\rightarrow M^{L^{A}}\rightarrow M^{A}\quad,\\
@@ -42853,8 +42910,8 @@ Incomplete transformers
\end_layout
\begin_layout Standard
-A monad transformer that obeys the laws of a pointed and co-pointed functor
- in the category of monads (see Section
+A monad transformer that obeys the laws of a pointed functor in the category
+ of monads (see Section
\begin_inset space ~
\end_inset
@@ -44080,6 +44137,13 @@ brun
\begin_layout Subsection
Transformer for the continuation monad.
Proofs
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Transformer-for-the-continuation-monad"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
@@ -44529,7 +44593,7 @@ The generalized
status open
\begin_layout Plain Layout
-monads!generalized
+monads!
\family typewriter
Search
\family default
@@ -44579,7 +44643,7 @@ Search
\end_inset
monad is obtained with
-\begin_inset Formula $L\triangleq\text{Opt}$
+\begin_inset Formula $L^{A}\triangleq\bbnum 1+A$
\end_inset
and
@@ -44668,7 +44732,7 @@ We assume that
\begin_inset Formula $L\varangle$
\end_inset
- already satisfies all the necessary transformer laws.
+ already satisfies all the laws of transformers.
\end_layout
\begin_layout Paragraph
@@ -44699,7 +44763,7 @@ noprefix "false"
\end_inset
-filterable contrafunctor
-\begin_inset Formula $H^{A}\triangleq A\rightarrow L^{Q}$
+\begin_inset Formula $K^{A}\triangleq A\rightarrow L^{Q}$
\end_inset
(see Statement
@@ -44747,11 +44811,11 @@ Search
is a lawful monad.
We will use this definition of
-\begin_inset Formula $H^{A}$
+\begin_inset Formula $H$
\end_inset
in the proof below.
- For brevity, we will denote the transformed monad
+ We denote the transformed monad
\begin_inset listings
inline true
status open
@@ -44771,7 +44835,7 @@ Search
\begin_inset Formula $T$
\end_inset
- (the foreign monad
+ for brevity (the foreign monad
\begin_inset Formula $M$
\end_inset
@@ -45500,16 +45564,7 @@ noprefix "false"
\end_layout
\begin_layout Standard
-Assume a monad
-\begin_inset Formula $K^{R,\bullet}$
-\end_inset
-
- with an extra type parameter
-\begin_inset Formula $R$
-\end_inset
-
-.
- In other words,
+Assume
\begin_inset Formula $K^{R,A}$
\end_inset
@@ -45517,7 +45572,7 @@ Assume a monad
\begin_inset Formula $A$
\end_inset
- and with a fixed
+ and with a fixed type
\begin_inset Formula $R$
\end_inset
@@ -45543,7 +45598,11 @@ Assume a monad
\begin_inset Formula $L^{\bullet}\leadsto K^{R,\bullet}$
\end_inset
-.
+ (that is,
+\begin_inset Formula $\forall A.\,L^{A}\rightarrow K^{R,A}$
+\end_inset
+
+).
\end_layout
\begin_layout Subparagraph
@@ -47027,6 +47086,10 @@ flift
.
\end_layout
+\begin_layout Section
+Further developments
+\end_layout
+
\begin_layout Subsection
Examples of monads with several different transformers
\begin_inset CommandInset label
@@ -47502,7 +47565,7 @@ noprefix "false"
\end_inset
and, for
-\begin_inset Formula $P$
+\begin_inset Formula $FM$
\end_inset
-typeclasses, by Statement
@@ -47663,10 +47726,6 @@ standard
transformer.
\end_layout
-\begin_layout Section
-Further developments
-\end_layout
-
\begin_layout Subsection
Some properties of monad morphisms
\end_layout
@@ -60062,10 +60121,17 @@ simple
\begin_layout Subsection
Summary of monad transformer constructions
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Summary-of-monad-transformer-constructions"
+
+\end_inset
+
+
\end_layout
\begin_layout Standard
-Monad transformers seen in this chapter fall into one of the 6 cases:
+All known monad transformers fall into one of the 7 cases:
\end_layout
\begin_layout Standard
@@ -60121,7 +60187,7 @@ rigid
\begin_layout Standard
2.
- The special monads
+ The special
\begin_inset listings
inline true
status open
@@ -60133,47 +60199,103 @@ State
\end_inset
-,
+ monad has a special, fully featured transformer.
+ The only deficiency is that the transformer
\begin_inset listings
inline true
status open
\begin_layout Plain Layout
-Cont
+StateT
\end_layout
\end_inset
-,
-\begin_inset listings
-inline true
-status open
+ has no lawful base runner.
+\end_layout
-\begin_layout Plain Layout
+\begin_layout Standard
+3.
+ The
+\begin_inset Quotes eld
+\end_inset
-Cod
-\end_layout
+continuation-like
+\begin_inset Quotes erd
+\end_inset
+ monads have transformers that are incomplete, having no foreign runners
+ or base lifts.
+ These are the transformers for the continuation monad (Section
+\begin_inset space ~
\end_inset
-,
-\begin_inset listings
-inline true
-status open
-\begin_layout Plain Layout
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Transformer-for-the-continuation-monad"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+), the search monad (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Transformer-for-the-generalized-search-monad"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+), the codensity monad (Section
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:The-codensity-monad"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+), and the
+\begin_inset Quotes eld
+\end_inset
+
+composed codensity
+\begin_inset Quotes erd
+\end_inset
+
+ monad (Exercise
+\begin_inset space ~
+\end_inset
-Search
-\end_layout
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:Exercise-combined-codensity-monad"
+plural "false"
+caps "false"
+noprefix "false"
\end_inset
-, whose transformers are not fully-featured.
+).
\end_layout
\begin_layout Standard
-3.
+4.
The
\begin_inset listings
inline true
@@ -60190,18 +60312,17 @@ List
\end_layout
\begin_layout Standard
-4.
- The transformer for a Cartesian product of monads is the Cartesian product
- of transformers.
+5.
+ The transformer for a product of monads is the product of transformers.
\end_layout
\begin_layout Standard
-5.
+6.
The free pointed monad has its special transformer.
\end_layout
\begin_layout Standard
-6.
+7.
Monad stacks (monads of the form
\begin_inset Formula $K\varangle L\varangle...\varangle P$
\end_inset
@@ -60218,12 +60339,76 @@ List
\begin_inset Formula $P$
\end_inset
- are given monads).
+ are given monads) have transformers defined via larger monad stacks, making
+ the operation
+\begin_inset Formula $\varangle$
+\end_inset
+
+ associative.
+
\end_layout
\begin_layout Standard
-No one knows any explicit examples of monads that do not fit into one of
- these cases.
+Known monad transformers are complete (that is, they are pointed endofunctors
+ in the category of monads) for all monads except the
+\begin_inset Quotes eld
+\end_inset
+
+continuation-like
+\begin_inset Quotes erd
+\end_inset
+
+ monads whose type signatures have the form
+\begin_inset Formula $(A\rightarrow P^{...})\rightarrow Q^{...}$
+\end_inset
+
+.
+ These are
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Cont
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Cod
+\end_layout
+
+\end_inset
+
+,
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Search
+\end_layout
+
+\end_inset
+
+, and the composed codensity monads.
+ The transformers for those monads have type signatures of the form
+\begin_inset Formula $(A\rightarrow M^{P^{...}})\rightarrow M^{Q^{...}}$
+\end_inset
+
+, which is not covariant with respect to
+\begin_inset Formula $M$
+\end_inset
+
+.
\end_layout
\begin_layout Subsection
@@ -61023,10 +61208,9 @@ def dbl[M[_]: Monad, A](m: M[A]): M[A] = for {
\begin_inset Formula
-\begin{align*}
-m^{:M^{A}}\triangleright\text{dbl} & \triangleq m\triangleright\text{flm}_{M}(\_^{:A}\rightarrow m)\\
- & =m\triangleright(\_\rightarrow m)^{\uparrow M}\bef\text{ftn}_{M}\quad.
-\end{align*}
+\[
+m^{:M^{A}}\triangleright\text{dbl}\triangleq m\triangleright\text{flm}_{M}(\_^{:A}\rightarrow m)\quad.
+\]
\end_inset
@@ -61266,7 +61450,7 @@ Consider the monads
\begin_inset Formula $\text{State}^{R,A}$
\end_inset
- (where
+ (
\begin_inset Formula $R$
\end_inset
@@ -61554,16 +61738,20 @@ U^{A}\triangleq L^{(L\varangle M)^{A}}\quad,\quad\quad V^{A}\triangleq M^{(L\var
\end_inset
-In a shorter notation,
-\begin_inset Formula $U\triangleq L\circ(L\varangle M)$
+For brevity, denote
+\begin_inset Formula $T\triangleq L\varangle M$
\end_inset
- and
-\begin_inset Formula $V\triangleq M\circ(L\varangle M)$
+,
+\begin_inset Formula $U\triangleq L\circ T$
+\end_inset
+
+, and
+\begin_inset Formula $V\triangleq M\circ T$
\end_inset
.
- We have the
+ The
\begin_inset listings
inline true
status open
@@ -61575,16 +61763,7 @@ swap
\end_inset
- functions:
-\begin_inset Formula
-\begin{align*}
-\text{sw}_{L,T} & :(L\varangle M)\circ L\leadsto L\circ(L\varangle M)\quad,\\
-\text{sw}_{M,T} & :(L\varangle M)\circ M\leadsto(M\circ L)\varangle M\quad,
-\end{align*}
-
-\end_inset
-
-defined using the already given methods
+ functions are expressed using the already given methods
\begin_inset listings
inline true
status open
@@ -61609,14 +61788,14 @@ blift
\end_inset
of
-\begin_inset Formula $L\varangle M$
+\begin_inset Formula $T$
\end_inset
as:
\begin_inset Formula
\begin{align*}
-\text{sw}_{L,T} & =\text{blift}^{\uparrow T}\bef\text{ftn}_{T}\bef\text{pu}_{L}\quad,\\
-\text{sw}_{M,T} & =\text{flift}^{\uparrow T}\bef\text{ftn}_{T}\bef\text{pu}_{M}\quad.
+\text{sw}_{L,T}:T\circ L\leadsto L\circ T\quad,\quad\quad\text{sw}_{L,T} & =\text{blift}^{\uparrow T}\bef\text{ftn}_{T}\bef\text{pu}_{L}\quad,\\
+\text{sw}_{M,T}:T\circ M\leadsto M\circ T\quad,\quad\quad\text{sw}_{M,T} & =\text{flift}^{\uparrow T}\bef\text{ftn}_{T}\bef\text{pu}_{M}\quad.
\end{align*}
\end_inset
@@ -61703,12 +61882,12 @@ swap
\begin_inset Formula $\,:M\circ L\leadsto L\circ M$
\end_inset
-, assume that the method
-\begin_inset Formula $\text{ftn}_{T}$
+, assume that
+\begin_inset Formula $T\triangleq L\circ M$
\end_inset
- of the monad
-\begin_inset Formula $T\triangleq L\circ M$
+ is a lawful monad whose method
+\begin_inset Formula $\text{ftn}_{T}$
\end_inset
is
@@ -61947,7 +62126,7 @@ search monad
\end_inset
by
-\begin_inset Formula $\text{Search}^{P,A}\triangleq\left(A\rightarrow\bbnum 1+P\right)\rightarrow\bbnum 1+A$
+\begin_inset Formula $\text{Search}^{P,A}\triangleq(A\rightarrow\bbnum 1+P)\rightarrow\bbnum 1+A$
\end_inset
.
@@ -62022,7 +62201,7 @@ finder
\emph on
not
\emph default
- a monad morphism
+ a monad morphism of type
\begin_inset Formula $\text{Sel}^{\bbnum 1+P,\bullet}\leadsto\text{Search}^{P,\bullet}$
\end_inset
@@ -62092,7 +62271,7 @@ def scc[P, A](s: (A => P) => A): (A => P) => P = { f: (A => P) => f(s(f))
\end_layout
\begin_layout Standard
-Hint: Use the flipped Kleisli technique to simplify the proof of the composition
+Hint: Use the flipped Kleisli technique for the proof of the composition
law.
\begin_inset Index idx
status open
@@ -62156,11 +62335,15 @@ noprefix "false"
\begin_inset Formula $(K^{A}\times L^{A})\times M^{A}\cong K^{A}\times(L^{A}\times M^{A})$
\end_inset
- is also a
+ has
\emph on
monad
\emph default
- isomorphism.
+
+\emph on
+morphisms
+\emph default
+ in both directions.
\end_layout
\begin_layout Subsubsection
@@ -62287,6 +62470,53 @@ monads!free pointed
\end_layout
+\begin_layout Subsubsection
+Exercise
+\begin_inset CommandInset label
+LatexCommand label
+name "par:Exercise-mt-3-4"
+
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "par:Exercise-mt-3-4"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+For any monad
+\begin_inset Formula $M$
+\end_inset
+
+, implement a natural transformation of type
+\begin_inset Formula $\forall(A,B).\,M^{A+M^{B}}\rightarrow M^{A+B}$
+\end_inset
+
+.
+ Show that this transformation is monadically natural with respect to a
+ suitable law involving arbitrary monads
+\begin_inset Formula $M$
+\end_inset
+
+,
+\begin_inset Formula $N$
+\end_inset
+
+ and an arbitrary monad morphism
+\begin_inset Formula $\phi:M\leadsto N$
+\end_inset
+
+.
+\end_layout
+
\begin_layout Subsubsection
Exercise
\begin_inset CommandInset label
@@ -62432,7 +62662,11 @@ cannot
\begin_inset Formula $(L\varangle M)^{A}\triangleq A+(K\varangle M)^{A}$
\end_inset
- because then (at least for some monads
+ because then there will be no monad morphism of type
+\begin_inset Formula $M^{A}\rightarrow A+(K\varangle M)^{A}$
+\end_inset
+
+, at least for some monads
\begin_inset Formula $K$
\end_inset
@@ -62440,10 +62674,6 @@ cannot
\begin_inset Formula $M$
\end_inset
-) there is no monad morphism
-\begin_inset Formula $\text{flift}:M\leadsto(L\varangle M)^{A}$
-\end_inset
-
.
\end_layout
@@ -62506,7 +62736,7 @@ not
\begin_layout Standard
\series bold
-(d)*
+(d)
\series default
Given a monad morphism
\begin_inset Formula $\theta_{L}:L^{A}\rightarrow A$
@@ -62577,86 +62807,12 @@ monads!free pointed
\begin_inset Note Note
status collapsed
-\begin_layout Plain Layout
-Exercise
-\begin_inset CommandInset ref
-LatexCommand ref
-reference "par:Exercise-mt-3-2"
-plural "false"
-caps "false"
-noprefix "false"
-
-\end_inset
-
-
-\end_layout
-
-\begin_layout Plain Layout
-
-\series bold
-(a)
-\series default
- Given a monad morphism
-\begin_inset Formula $\phi:K\leadsto L$
-\end_inset
-
-, show that one can implement a monad morphism
-\begin_inset Formula $\delta:K\leadsto\text{Opt}$
-\end_inset
-
-.
-\end_layout
-
-\begin_layout Plain Layout
-
-\series bold
-(b)*???
-\series default
- Given a monad morphism
-\begin_inset Formula $\delta:K\leadsto\text{Opt}$
-\end_inset
-
- (from
-\begin_inset Formula $K$
-\end_inset
-
- to the
-\begin_inset listings
-inline true
-status open
-
-\begin_layout Plain Layout
-
-Option
-\end_layout
-
-\end_inset
-
- monad), show that one can implement a monad morphism
-\begin_inset Formula $\phi:K\leadsto L$
-\end_inset
-
-.
-\end_layout
-
-\begin_layout Plain Layout
-– Not clear that we can actually prove part
-\series bold
-(b)
-\series default
-!
-\end_layout
-
\begin_layout Plain Layout
Solution
\end_layout
\begin_layout Plain Layout
-
-\series bold
-(a)
-\series default
- Consider the monad morphism
+Consider the monad morphism
\begin_inset Formula $\varepsilon:K\leadsto\bbnum 1$
\end_inset
@@ -62718,12 +62874,58 @@ Option
.
\end_layout
+\end_inset
+
+
+\begin_inset Note Note
+status collapsed
+
+\begin_layout Plain Layout
+Exercise
+\end_layout
+
\begin_layout Plain Layout
\series bold
-(b)
+???
\series default
- Given
+ Given a monad morphism
+\begin_inset Formula $\delta:K\leadsto\text{Opt}$
+\end_inset
+
+ (from
+\begin_inset Formula $K$
+\end_inset
+
+ to the
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Option
+\end_layout
+
+\end_inset
+
+ monad), show that one can implement a monad morphism
+\begin_inset Formula $\phi:K\leadsto L$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Plain Layout
+– Not clear that we can actually prove this!
+\end_layout
+
+\begin_layout Plain Layout
+Solution
+\end_layout
+
+\begin_layout Plain Layout
+Given
\begin_inset Formula $\delta:K^{A}\rightarrow\bbnum 1+A$
\end_inset
@@ -62960,7 +63162,7 @@ noprefix "false"
that adding a type quantifier to a monad gives again a monad.
Show that adding a type quantifier to any
-\begin_inset Formula $P$
+\begin_inset Formula $FM$
\end_inset
-typeclass (Section
@@ -62977,13 +63179,13 @@ noprefix "false"
\end_inset
-) gives again a
-\begin_inset Formula $P$
+) gives again an
+\begin_inset Formula $FM$
\end_inset
-typeclass.
- In detail: assume a
-\begin_inset Formula $P$
+ In detail: assume an
+\begin_inset Formula $FM$
\end_inset
-typeclass defined via a structure functor
@@ -63008,8 +63210,8 @@ noprefix "false"
\begin_inset Formula $\forall R.\,S^{R,A}\rightarrow A$
\end_inset
- is again a
-\begin_inset Formula $P$
+ is again an
+\begin_inset Formula $FM$
\end_inset
-typeclass (with a different choice of the structure functor).
@@ -63322,40 +63524,40 @@ composed
codensity monad
\series default
-\begin_inset Formula $\text{Cod}_{F}^{L,A}$
+\begin_inset Formula $\text{Cod}_{F}^{M,\bullet}$
\end_inset
is defined by:
\begin_inset Formula
\[
-\text{Cod}_{F}^{L,A}\triangleq\forall X.\,(A\rightarrow F^{X})\rightarrow F^{L^{X}}\quad,
+\text{Cod}_{F}^{M,A}\triangleq\forall X.\,(A\rightarrow F^{X})\rightarrow F^{M^{X}}\quad,
\]
\end_inset
where
-\begin_inset Formula $L$
+\begin_inset Formula $M$
\end_inset
- is any monad and
+ is any given monad and
\begin_inset Formula $F$
\end_inset
- is any functor.
- One may define the monad instance for
-\begin_inset Formula $\text{Cod}_{F}^{L,A}$
+ is any given functor.
+ The monad methods for
+\begin_inset Formula $\text{Cod}_{F}^{M,\bullet}$
\end_inset
- via the flipped Kleisli composition:
+ are defined via the flipped Kleisli composition:
\begin_inset Formula
\[
-f^{:\forall X.\,(B\rightarrow F^{X})\rightarrow A\rightarrow F^{L^{X}}}\tilde{\diamond}\,\,g^{:\forall Y.\,(C\rightarrow F^{Y})\rightarrow B\rightarrow F^{L^{Y}}}\triangleq\forall Z.\,k^{:C\rightarrow F^{Z}}\rightarrow\big(k\triangleright g^{Z}\triangleright f^{L^{Z}}\big)\bef\text{ftn}_{L}^{\uparrow F}\quad.
+f^{:\forall X.\,(B\rightarrow F^{X})\rightarrow A\rightarrow F^{M^{X}}}\tilde{\diamond}\,\,g^{:\forall Y.\,(C\rightarrow F^{Y})\rightarrow B\rightarrow F^{M^{Y}}}\triangleq\forall Z.\,k^{:C\rightarrow F^{Z}}\rightarrow\big(k\triangleright g^{Z}\triangleright f^{M^{Z}}\big)\bef\text{ftn}_{M}^{\uparrow F}\quad.
\]
\end_inset
Prove that the type constructor
-\begin_inset Formula $\text{Cod}_{F}^{L,\bullet}$
+\begin_inset Formula $\text{Cod}_{F}^{M,\bullet}$
\end_inset
is a lawful monad.
@@ -63364,10 +63566,10 @@ Prove that the type constructor
\begin_layout Standard
Hints: Use the flipped Kleisli formulation of the monad laws.
Assume that values of type
-\begin_inset Formula $\text{Cod}_{F}^{L,A}$
+\begin_inset Formula $\text{Cod}_{F}^{M,A}$
\end_inset
- are natural transformations obeying the appropriate naturality law.
+ are natural transformations obeying their naturality laws.
\end_layout
\begin_layout Standard
@@ -63379,31 +63581,31 @@ Hints: Use the flipped Kleisli formulation of the monad laws.
\begin_inset Formula $\forall X$
\end_inset
- cannot be removed from the definition of
-\begin_inset Formula $\text{Cod}_{F}^{L,A}$
+
+\emph on
+cannot
+\emph default
+ be removed from the definition of
+\begin_inset Formula $\text{Cod}_{F}^{M,\bullet}$
\end_inset
even if
-\begin_inset Formula $F^{A}\triangleq A$
+\begin_inset Formula $F^{X}\triangleq X$
\end_inset
: for a fixed type
\begin_inset Formula $X$
\end_inset
- and for some
-\begin_inset Formula $L^{\bullet}$
+ and for some monad
+\begin_inset Formula $M$
\end_inset
-, the type constructor
-\begin_inset Formula $P^{A}\triangleq(A\rightarrow X)\rightarrow L^{X}$
+, the functor
+\begin_inset Formula $P^{A}\triangleq(A\rightarrow X)\rightarrow M^{X}$
\end_inset
- is
-\emph on
-not
-\emph default
- a monad.
+ is not a monad.
\end_layout
\begin_layout Standard
@@ -63415,32 +63617,13 @@ not
\emph on
no
\emph default
- monad morphism
-\begin_inset Formula $L^{A}\rightarrow\text{Cod}_{F}^{L,A}$
-\end_inset
-
-.
-
-\begin_inset Note Note
-status open
-
-\begin_layout Plain Layout
-A simple counterexample is found with
-\begin_inset Formula $M^{A}\triangleq R\rightarrow A$
-\end_inset
-
- and
-\begin_inset Formula $L^{A}\triangleq\bbnum 1+A$
+ monad morphism of type
+\begin_inset Formula $\forall A.\,M^{A}\rightarrow\text{Cod}_{F}^{M,A}$
\end_inset
.
\end_layout
-\end_inset
-
-
-\end_layout
-
\begin_layout Subsubsection
Exercise
\begin_inset CommandInset label
diff --git a/sofp-src/lyx/sofp-traversable.lyx b/sofp-src/lyx/sofp-traversable.lyx
index dcb58bd2f..2187c8a71 100644
--- a/sofp-src/lyx/sofp-traversable.lyx
+++ b/sofp-src/lyx/sofp-traversable.lyx
@@ -445,7 +445,7 @@ traversable functors
\end_inset
.
- In this way, we will complete a theoretical study of the
+ In this way, we complete a theoretical study of the
\begin_inset listings
inline true
status open
@@ -17487,7 +17487,7 @@ noprefix "false"
\end_inset
-We need to choose
+We will now choose
\begin_inset Formula $A$
\end_inset
@@ -17499,7 +17499,7 @@ We need to choose
\begin_inset Formula $f$
\end_inset
- appropriately in order to be able to derive Eq.
+ in this equation appropriately, in order to derive Eq.
\begin_inset space ~
\end_inset
@@ -17514,15 +17514,17 @@ noprefix "false"
\end_inset
).
- After some guessing and trying, one finds that a good choice is
+ After some guessing and trying, one finds that a useful choice is to define
+
\begin_inset Formula $B\triangleq A\rightarrow A$
\end_inset
- and
+.
+ Then we choose
\begin_inset Formula $f^{:B\rightarrow A}$
\end_inset
- defined by:
+ as the following function:
\begin_inset Formula
\begin{equation}
f:(A\rightarrow A)\rightarrow A\quad,\quad\quad f\triangleq k^{:A\rightarrow A}\rightarrow k(a_{0})\quad\text{with a fixed }a_{0}:A\quad.\label{eq:f-for-relational-law-of-foldFn-derivation1}
@@ -17530,7 +17532,7 @@ f:(A\rightarrow A)\rightarrow A\quad,\quad\quad f\triangleq k^{:A\rightarrow A}\
\end_inset
-Each value
+Here, we assume that a value
\begin_inset Formula $a_{0}$
\end_inset
@@ -17538,7 +17540,16 @@ Each value
\begin_inset Formula $A$
\end_inset
- gives us a function
+ is given (and
+\begin_inset Formula $A\neq\bbnum 0$
+\end_inset
+
+).
+ Each
+\begin_inset Formula $a_{0}$
+\end_inset
+
+ specifies a different function
\begin_inset Formula $f_{a_{0}}:(A\rightarrow A)\rightarrow A$
\end_inset
@@ -18915,7 +18926,14 @@ The two sides are now equal.
\end_layout
\begin_layout Subsection
-The missing laws of
+The
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:The-missing-laws-of-foldMap-and-reduce"
+
+\end_inset
+
+ missing laws of
\family typewriter
foldMap
\family default
@@ -25486,7 +25504,7 @@ This definition uses a recursive call to
\end_inset
of
-\begin_inset Formula $S^{A,R}$
+\begin_inset Formula $S^{F^{A},R}$
\end_inset
.
diff --git a/sofp-src/lyx/sofp-typeclasses.lyx b/sofp-src/lyx/sofp-typeclasses.lyx
index cb81c30ee..bad2d7bb9 100644
--- a/sofp-src/lyx/sofp-typeclasses.lyx
+++ b/sofp-src/lyx/sofp-typeclasses.lyx
@@ -36261,10 +36261,7 @@ John de Goes.
\end_layout
\begin_layout Subsection
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses, their laws and structure
+FM-typeclasses, their laws and structure
\begin_inset CommandInset label
LatexCommand label
name "subsec:P-typeclasses"
@@ -36661,11 +36658,7 @@ pointed contrafunctor
\begin_inset Caption Standard
\begin_layout Plain Layout
-Structure of typeclass instance values for various
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses.
+Structure of typeclass instance values for various FM-typeclasses.
\begin_inset CommandInset label
LatexCommand label
name "tab:Types-of-typeclass-instance-values"
@@ -36803,19 +36796,12 @@ This motivates the definition of
status open
\begin_layout Plain Layout
-\begin_inset Formula $P$
-\end_inset
-
--typeclass|textit
+FM-typeclass|textit
\end_layout
\end_inset
- a
-\begin_inset Formula $P$
-\end_inset
-
--
+ an FM-
\series bold
typeclass
\series default
@@ -36853,6 +36839,23 @@ typeclass!structure functor
structure functor
\series default
of the typeclass.
+ (The name
+\begin_inset Quotes eld
+\end_inset
+
+FM
+\begin_inset Quotes erd
+\end_inset
+
+ stands for
+\begin_inset Quotes eld
+\end_inset
+
+functor/monad
+\begin_inset Quotes erd
+\end_inset
+
+ and will be justified later.)
\end_layout
\begin_layout Standard
@@ -36863,16 +36866,12 @@ status open
\begin_layout Plain Layout
-final case class PTypeclass[P[_]: Functor, A](methods: P[A] => A)
+final case class FMTypeclass[P[_]: Functor, A](methods: P[A] => A)
\end_layout
\end_inset
-The code allows us to declare any
-\begin_inset Formula $P$
-\end_inset
-
--typeclass.
+The code allows us to declare any FM-typeclass.
For example, the
\begin_inset listings
inline true
@@ -36921,7 +36920,7 @@ val functorMonoidSF: Functor[MonoidSF] = ...
\begin_layout Plain Layout
-type PMonoid[A] = PTypeclass[MonoidSF, A]
+type FMMonoid[A] = FMTypeclass[MonoidSF, A]
\end_layout
\end_inset
@@ -37016,11 +37015,8 @@ noprefix "false"
except for the additional type parameters.
The laws of type constructor typeclasses are also more complicated because
they often involve multiple type parameters and arbitrary functions.
- To simplify the presentation in this section, we will only consider
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses for simple types, such as
+ To simplify the presentation in this section, we will only consider FM-typeclas
+ses for simple types, such as
\begin_inset listings
inline true
status open
@@ -37064,7 +37060,7 @@ Monoid
\begin_inset Formula $P$
\end_inset
- and a function
+ and a function of type
\begin_inset Formula $P^{A}\rightarrow A$
\end_inset
@@ -37075,11 +37071,8 @@ Monoid
is useful for reasoning about general properties of typeclasses.
To illustrate that kind of reasoning, we will now show that the product-type,
- the function-type, and the recursive-type constructions work for all
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses.
+ the function-type, and the recursive-type constructions work for all FM-typecla
+sses.
\end_layout
@@ -37088,11 +37081,7 @@ Products
\end_layout
\begin_layout Standard
-Consider an arbitrary
-\begin_inset Formula $P$
-\end_inset
-
--typeclass
+Consider an arbitrary FM-typeclass
\begin_inset listings
inline true
status open
@@ -37188,11 +37177,11 @@ def productTC[A, B](u: P[A] => A, v: P[B] => B): P[(A, B)] => (A, B) = {
\end_layout
\begin_layout Standard
-This argument does
+This argument does not prove that the typeclass
\emph on
-not
+laws
\emph default
- prove that the typeclass laws will also hold for
+ will also hold for
\begin_inset Formula $A\times B$
\end_inset
@@ -37211,23 +37200,16 @@ noprefix "false"
\end_inset
- after developing some advanced techniques for formal reasoning about
-\begin_inset Formula $P$
-\end_inset
-
--typeclass laws.
+ after developing some advanced techniques for formal reasoning about FM-typecla
+ss laws.
\end_layout
\begin_layout Standard
-We note that the co-product construction does
+The co-product construction does
\emph on
not
\emph default
- work for arbitrary
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses: given evidence values of types
+ work for arbitrary FM-typeclasses: given evidence values of types
\begin_inset Formula $P^{A}\rightarrow A$
\end_inset
@@ -37240,14 +37222,10 @@ not
\end_inset
.
- Later we will see that some
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses, such as monads or applicative functors, do not support the
- co-product construction.
- The co-product of two monads is not always a lawful monad; the co-product
- of two applicative functors is not always an applicative functor.
+ Later we will see that some FM-typeclasses, such as monads or applicative
+ functors, do not support the co-product construction.
+ The co-product of two monads is not always a monad; the co-product of two
+ applicative functors is not always an applicative functor.
\end_layout
\begin_layout Paragraph
@@ -37255,11 +37233,8 @@ Functions
\end_layout
\begin_layout Standard
-The function-type construction creates a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass instance for the type
+The function-type construction creates an FM-typeclass instance for the
+ type
\begin_inset Formula $E\rightarrow A$
\end_inset
@@ -37267,11 +37242,7 @@ The function-type construction creates a
\begin_inset Formula $A$
\end_inset
- belongs to the
-\begin_inset Formula $P$
-\end_inset
-
--typeclass.
+ belongs to the FM-typeclass.
Using the fact that
\begin_inset Formula $P$
\end_inset
@@ -37339,11 +37310,7 @@ preserves
\begin_inset Quotes erd
\end_inset
-
-\begin_inset Formula $P$
-\end_inset
-
--typeclass instances: if
+ FM-typeclass instances: if
\begin_inset Formula $A$
\end_inset
@@ -37505,11 +37472,7 @@ def tcT: P[T] => T = p => T(tcS(tcT)(p.map(_.s))) // The recursive instance.
\end_inset
-In this way, the recursive-type construction works for any
-\begin_inset Formula $P$
-\end_inset
-
--typeclass.
+In this way, the recursive-type construction works for any FM-typeclass.
(We will prove in Section
\begin_inset space ~
\end_inset
@@ -37532,11 +37495,8 @@ Similar arguments can be made for type constructor typeclasses, although
their properties are more difficult to prove.
This book shows that the product-type, the function-type, and the recursive-typ
e constructions work for functors, contrafunctors, pointed functors, and
- pointed contrafunctors, as well as for other important
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses such as filterable functors (Chapter
+ pointed contrafunctors, as well as for other important FM-typeclasses such
+ as filterable functors (Chapter
\begin_inset space ~
\end_inset
@@ -37593,11 +37553,8 @@ noprefix "false"
\end_inset
- that another general construction also works for all
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses, — the
+ that another general construction also works for all FM-typeclasses, —
+ the
\begin_inset Quotes eld
\end_inset
@@ -37613,11 +37570,7 @@ Some typeclasses
\emph on
cannot
\emph default
- be viewed as
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses.
+ be viewed as FM-typeclasses.
The
\begin_inset listings
inline true
@@ -37738,24 +37691,16 @@ noprefix "false"
\series bold
co-
\series default
-
-\begin_inset Formula $P$
-\end_inset
-
-
+FM-
\series bold
--typeclasses
+typeclasses
\series default
.
\begin_inset Index idx
status open
\begin_layout Plain Layout
-co-
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses
+co-FM-typeclasses
\end_layout
\end_inset
@@ -37786,29 +37731,19 @@ co-product
\begin_inset Formula $A+B\rightarrow P^{A+B}$
\end_inset
-, i.e., a
-\begin_inset Formula $P$
-\end_inset
-
--typeclass evidence for the co-product
+, i.e., an FM-typeclass evidence for the co-product
\begin_inset Formula $A+B$
\end_inset
.
- Similarly to
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses, the typeclass laws will hold automatically for the type
+ Similarly to FM-typeclasses, the typeclass laws will hold automatically
+ for the type
\begin_inset Formula $A+B$
\end_inset
.
- A detailed description of co-
-\begin_inset Formula $P$
-\end_inset
-
--typeclasses is beyond the scope of this book.
+ A detailed description of co-FM-typeclasses is beyond the scope of this
+ book.
\end_layout
\begin_layout Standard
@@ -37837,7 +37772,11 @@ Eq
\begin_inset Formula $A\rightarrow P^{A}$
\end_inset
-.
+ (where
+\begin_inset Formula $P$
+\end_inset
+
+ must be a covariant functor).
\end_layout
\begin_layout Subsection
@@ -37845,10 +37784,9 @@ Typeclasses, object-oriented interfaces, and algebraic data types
\end_layout
\begin_layout Standard
-Typeclasses can be viewed as a way of managing various sets of methods that
- a data type must support.
- Scala supports two other features for managing data methods: object-oriented
- interfaces
+Typeclasses can be viewed as a way of managing the methods that various
+ data types must support.
+ Scala has two other features for managing methods: object-oriented interfaces
\begin_inset Index idx
status open
@@ -37871,7 +37809,7 @@ algebraic data types
(ADTs).
We will now compare the expressive power of all those features.
We will find that typeclasses can be seen as a generalization of both OOIs
- and ADTs, transcending their specific limitations.
+ and ADTs, overcoming their specific limitations.
\end_layout
\begin_layout Standard
@@ -38220,7 +38158,7 @@ size: Int
\end_inset
.
- To call that function, we use the syntax
+ We use that function with the syntax
\begin_inset listings
inline true
status open
@@ -38230,6 +38168,14 @@ status open
c.isSmallerThan(1000)
\end_layout
+\end_inset
+
+ to pass the arguments
+\begin_inset Formula $c$
+\end_inset
+
+ and
+\begin_inset Formula $1000$
\end_inset
.
@@ -38276,7 +38222,7 @@ this
.
In some other object-oriented languages, method signatures must have an
- explicit first argument called
+ explicit first argument, usually called
\begin_inset listings
inline true
status open
@@ -38303,12 +38249,8 @@ this
, or similar.
When we analyze OOIs as types, we must make all argument types explicit,
even though the Scala syntax does not do that.
- For convenience, let us therefore assume that each method in an OOI definition
- has an additional
-\emph on
-first
-\emph default
- argument (corresponding to Scala's
+ For this reason, we will view the types of methods in an OOI definition
+ as having an additional first argument (corresponding to Scala's
\begin_inset listings
inline true
status open
@@ -38325,7 +38267,7 @@ this
\begin_layout Standard
We have expressed the type of an interface as a tuple of some function types.
- The first argument of each function is the type of a class that will later
+ The first argument of each function has the type of a class that will later
implement that interface.
That type is unknown within the scope of an interface definition, and so
we have to denote that type by a type parameter
@@ -38347,8 +38289,13 @@ We have expressed the type of an interface as a tuple of some function types.
\begin_inset Formula $T$
\end_inset
- a curried first argument and we obtain a description of an OOI type as
- a tuple of types of the form
+ a
+\emph on
+curried
+\emph default
+ first argument.
+ Then we obtain a description of an OOI type as a tuple of types of the
+ form
\begin_inset Formula $T\rightarrow U_{1}$
\end_inset
@@ -38368,7 +38315,7 @@ We have expressed the type of an interface as a tuple of some function types.
\begin_inset Formula $U_{n}$
\end_inset
- are some type expressions that might also use
+ are some type expressions that might also depend on
\begin_inset Formula $T$
\end_inset
@@ -38377,8 +38324,8 @@ We have expressed the type of an interface as a tuple of some function types.
\begin_inset Formula $U_{i}$
\end_inset
- correspond to the type expressions as seen in the Scala interface definition,
- where the first argument of type
+ exactly correspond to the type expressions specified in the Scala interface
+ definition, where the first argument of type
\begin_inset Formula $T$
\end_inset
@@ -38394,11 +38341,7 @@ Using a standard type equivalence such as:
\end_inset
-and similarly for other
-\begin_inset Formula $U_{i}$
-\end_inset
-
-, we can simplify the type of an OOI to a single function:
+we can simplify the type of an OOI to a single function:
\begin_inset Formula
\[
(T\rightarrow U_{1})\times...\times(T\rightarrow U_{n})\cong T\rightarrow U_{1}\times...\times U_{n}=T\rightarrow U^{T}\quad,
@@ -38505,7 +38448,7 @@ isSmallerThan
\end_inset
- in the interface definition, where the first argument (of type
+ in the Scala interface definition, where the first argument (of type
\begin_inset Formula $T$
\end_inset
@@ -38571,7 +38514,7 @@ extension methods
\begin_inset Quotes erd
\end_inset
- whose first argument has type
+ since their first arguments have type
\begin_inset Formula $T$
\end_inset
@@ -39058,12 +39001,22 @@ es whose method signature has the form
\begin_inset Quotes eld
\end_inset
+FM-typeclasses
+\begin_inset Quotes erd
+\end_inset
-\begin_inset Formula $P$
+ for reasons explained in Chapter
+\begin_inset space ~
\end_inset
--typeclasses
-\begin_inset Quotes erd
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "chap:Free-type-constructions"
+plural "false"
+caps "false"
+noprefix "false"
+
\end_inset
.)
@@ -39092,26 +39045,21 @@ Eq
\end_inset
with any definition of
-\begin_inset Formula $T$
+\begin_inset Formula $P$
\end_inset
.
\end_layout
\begin_layout Paragraph
-Summary
-\end_layout
-
-\begin_layout Standard
-Object-oriented interfaces and algebraic data types are particular cases
- of typeclasses, if we consider only the type signatures of the required
- methods.
+Inheritance
\end_layout
\begin_layout Standard
-At that level of abstraction, we can also show that the inheritance of typeclass
-es corresponds to the object-oriented inheritance of interfaces.
- Let us describe inheritance in the language of method signatures.
+We have been reasoning about typeclasses and OOIs purely in terms of type
+ signatures.
+ At that level of abstraction, the inheritance of typeclasses corresponds
+ to the object-oriented inheritance of interfaces, as we will now show.
\end_layout
@@ -39137,14 +39085,13 @@ A typeclass with signature
\begin_inset Formula $Q$
\end_inset
- describes the additional methods that the new typeclass has.) So, typeclass
+ describes all the additional methods that the new typeclass has.) So, typeclass
inheritance corresponds to taking products of method signatures.
\end_layout
\begin_layout Standard
-Object-oriented inheritance of interfaces turns out to be exactly of the
- same nature.
+Object-oriented inheritance of interfaces turns out to be exactly similar.
To see that, consider a first OOI with method signature
\begin_inset Formula $T\rightarrow U^{T}$
\end_inset
@@ -39154,8 +39101,8 @@ Object-oriented inheritance of interfaces turns out to be exactly of the
\end_inset
.
- The first OOI may not change any type signatures that it inherited; it
- may only add new methods.
+ The first OOI may not change any type signatures that it inherits; it may
+ only add new methods.
Recall that the interface declarations
\begin_inset Formula $U^{T}$
\end_inset
@@ -39182,12 +39129,11 @@ T\rightarrow U^{T}=T\rightarrow V^{T}\times W^{T}\cong(T\rightarrow V^{T})\times
\end_inset
-We see that inheritance of OOIs involves products of method signatures,
- just as inheritance of typeclasses does.
+We see that inheritance of OOIs also involves products of method signatures.
\end_layout
\begin_layout Standard
-A similar situation exists when ADTs are extended by new constructors.
+Let us now turn to ADTs.
Given an ADT with method signature
\begin_inset Formula $P^{T}\rightarrow T$
\end_inset
@@ -39197,12 +39143,12 @@ A similar situation exists when ADTs are extended by new constructors.
\end_inset
.
- The result is the ADT with method signature
+ The result is an ADT with method signature
\begin_inset Formula $P^{T}+Q^{T}\rightarrow T$
\end_inset
-, because adding new constructors corresponds to adding another part of
- a disjunctive type.
+, because adding new constructors corresponds to adding more parts to a
+ disjunctive type.
Then we use a standard type equivalence:
\begin_inset Formula
\[
@@ -39218,15 +39164,24 @@ So, the ADTs expressed as typeclasses with signatures
have the same inheritance mechanism, based on products of method signatures.
\end_layout
+\begin_layout Paragraph
+Summary
+\end_layout
+
+\begin_layout Standard
+Object-oriented interfaces and algebraic data types are particular cases
+ of typeclasses, if we consider only the type signatures of the required
+ methods.
+\end_layout
+
\begin_layout Standard
-Keep in mind that this description is only at the level of method types.
- There are other important differences in how the Scala compiler works with
- typeclasses, OOIs, and ADTs:
+If we look beyond just method types, there are important differences in
+ how the Scala compiler works with typeclasses, OOIs, and ADTs:
\end_layout
\begin_layout Itemize
-For OOIs, the compiler provides automatic subtyping for interfaces, via
- the object-oriented inheritance mechanism.
+For OOIs, the compiler provides automatic subtyping for interfaces via the
+ object-oriented inheritance mechanism.
If a class (or an interface)
\begin_inset Formula $A$
\end_inset
@@ -39279,9 +39234,8 @@ transitive
.
The compiler will construct an inheritance tree automatically, extending
the tree each time a new interface or class is defined.
- However, one cannot add or remove inherited interfaces once a class definition
- is given.
- For example, if it is declared that
+ However, one cannot add or remove inherited interfaces later in the code.
+ For example,
\begin_inset Formula $A$
\end_inset
@@ -39289,11 +39243,7 @@ transitive
\begin_inset Formula $B$
\end_inset
- and
-\begin_inset Formula $C$
-\end_inset
-
- (this needs to be declared together with the definition of
+ (this must be declared together with the definition of
\begin_inset Formula $A$
\end_inset
@@ -39301,7 +39251,11 @@ transitive
\begin_inset Formula $A$
\end_inset
- should inherit additionally from some other interface, or that
+ should inherit additionally from some other interface
+\begin_inset Formula $C$
+\end_inset
+
+; or that
\begin_inset Formula $A$
\end_inset
@@ -39311,22 +39265,27 @@ transitive
.
Typeclasses are more flexible in this respect: additional evidence values
- for typeclass membership can be defined in any scope, not necessarily together
- with the declaration of a type.
+ for typeclass membership can be defined in any scope, not necessarily at
+ the declaration site.
Typeclasses may be implemented via OOIs, which will enable features of
inheritance and subtyping.
This will make typeclass inheritance behave like object-oriented interface
- inheritance, with all its benefits and shortcomings.
+ inheritance with all its benefits and shortcomings.
As we have seen, typeclasses and their inheritance may be also implemented
- without using object-oriented interfaces or inheritance.
+ without OOIs.
\end_layout
\begin_layout Itemize
-For typeclasses, the compiler provides rich features for automatic computation
- of typeclass evidence values via the mechanism of implicit values and implicit
- functions.
- These features enable automatic typeclass derivation, which works independently
- of and in parallel with typeclass inheritance.
+For typeclasses, the Scala compiler provides a rich mechanism known as
+\begin_inset Quotes eld
+\end_inset
+
+typeclass derivation
+\begin_inset Quotes erd
+\end_inset
+
+: an automatic computation of typeclass evidence values, which works independent
+ly of typeclass inheritance.
The programmer can tell the compiler how to compute (via custom code) a
typeclass evidence value for, say, any pair type
\begin_inset listings
@@ -39365,8 +39324,21 @@ B
\end_inset
.
+ Similarly, a custom derivation rule for
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Either[A, B]
+\end_layout
+
+\end_inset
+
+ may be specified.
The compiler will use that custom code to determine automatically whether
- any given pair type
+
\begin_inset listings
inline true
status open
@@ -39378,8 +39350,7 @@ status open
\end_inset
- belongs to the typeclass.
- Similarly, a typeclass derivation rule for
+ or
\begin_inset listings
inline true
status open
@@ -39391,9 +39362,7 @@ Either[A, B]
\end_inset
- could be specified.
- The compiler will compute and use the new typeclass evidence values automatical
-ly for
+ belongs to the typeclass, for
\emph on
all
\emph default
@@ -39435,7 +39404,7 @@ status open
\end_inset
- to all case classes, and from the disjunctive type
+ to all case classes, and from
\begin_inset listings
inline true
status open
@@ -39449,7 +39418,7 @@ Either[A, B]
to all disjunctive types.
In this way, typeclass membership can be provided automatically by the
- compiler for a wide range of types, which reduces boilerplate code.
+ compiler (with no boilerplate code) for a wide range of user-defined types.
But there are no comparable facilities for object-oriented
\begin_inset Quotes eld
\end_inset
@@ -39463,9 +39432,9 @@ interface derivation
\end_layout
\begin_layout Itemize
-The compiler's treatment of ADTs in Scala (and in other functional languages)
- is significantly different from the treatment of typeclasses and interfaces.
- An ADT is not an arbitrary type
+The compilers of Scala and other functional languages treat ADTs and typeclasses
+ in rather different ways.
+ An ADT is not just an arbitrary type
\begin_inset Formula $T$
\end_inset
@@ -39474,7 +39443,7 @@ The compiler's treatment of ADTs in Scala (and in other functional languages)
\end_inset
.
- Instead, the Scala compiler interprets an ADT as the
+ In fact, the Scala compiler interprets an ADT as the
\emph on
smallest unique
\emph default
@@ -39516,6 +39485,78 @@ noprefix "false"
.
\end_layout
+\begin_layout Standard
+How to decide whether to use typeclasses, ADTs, or OOIs in practice? One
+ approach is to look at the type signatures of functions that one needs
+ to use in a given problem domain.
+ If one most often needs to construct new domain values, most type signatures
+ will be of the form
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+Something => T
+\end_layout
+
+\end_inset
+
+, where
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+T
+\end_layout
+
+\end_inset
+
+ is the type of a domain entity.
+ This is of the general form
+\begin_inset Formula $P^{T}\rightarrow T$
+\end_inset
+
+ and is modeled well by ADTs.
+ If one most often needs to work with existing domain entities, type signatures
+ will be of the form
+\begin_inset listings
+inline true
+status open
+
+\begin_layout Plain Layout
+
+T => Something
+\end_layout
+
+\end_inset
+
+.
+ This is of the general form
+\begin_inset Formula $T\rightarrow P^{T}$
+\end_inset
+
+ and is modeled well by OOIs.
+
+\end_layout
+
+\begin_layout Standard
+So, the decision of whether to use ADTs or OOIs depends on the prevalence
+ of method signatures of the form
+\begin_inset Formula $P^{T}\rightarrow T$
+\end_inset
+
+ or
+\begin_inset Formula $T\rightarrow P^{T}$
+\end_inset
+
+ in the problem domain.
+ Typeclasses support method signatures of either form and can be used to
+ implement both ADTs and OOIs, overcoming their limitations.
+\end_layout
+
\begin_layout Standard
\begin_inset Note Comment
status collapsed
diff --git a/sofp-src/lyx/sofp.lyx b/sofp-src/lyx/sofp.lyx
index b6370a52a..b41fd1f48 100644
--- a/sofp-src/lyx/sofp.lyx
+++ b/sofp-src/lyx/sofp.lyx
@@ -370,7 +370,7 @@ literal "false"
\series default
- in 2024
+ in 2025
\end_layout
\begin_layout Uppertitleback
@@ -391,7 +391,7 @@ copyright
\end_inset
- 2018-2024 by Sergei Winitzki
+ 2018-2025 by Sergei Winitzki
\begin_inset Newline newline
\end_inset
diff --git a/sofp-src/tex/chapter3-picture.pdf b/sofp-src/tex/chapter3-picture.pdf
index ddcb6fb7f..84c33229d 100644
Binary files a/sofp-src/tex/chapter3-picture.pdf and b/sofp-src/tex/chapter3-picture.pdf differ
diff --git a/sofp-src/tex/sofp-appendices.tex b/sofp-src/tex/sofp-appendices.tex
index f8af1db96..55a82cd11 100644
--- a/sofp-src/tex/sofp-appendices.tex
+++ b/sofp-src/tex/sofp-appendices.tex
@@ -705,14 +705,14 @@ \section{How the term \textquotedblleft algebra\textquotedblright{} is used
theory, least fixpoints of a type equation $F^{T}\cong T$ is the
\textsf{``}initial $F$-algebra\textsf{''}.\footnote{See \texttt{\href{https://homepages.inf.ed.ac.uk/wadler/papers/free-rectypes/free-rectypes.txt}{https://homepages.inf.ed.ac.uk/wadler/papers/free-rectypes/free-rectypes.txt}} }
-Another use of $F$-algebras is in formulating properties of $P$-typeclasses.\index{$P$-typeclass}
-A $P$-typeclass is a $P$-algebra with (usually) additional laws
-imposed. This book prefers the term \textsf{``}$P$-typeclass\textsf{''} for brevity,
+Another use of $F$-algebras is in formulating properties of $FM$-typeclasses.\index{$FM$-typeclass}
+An $FM$-typeclass is a $P$-algebra with (usually) additional laws
+imposed. This book prefers the term \textsf{``}$FM$-typeclass\textsf{''} for brevity,
although those typeclasses could also be called \textsf{``}$P$-algebraic\textsf{''}.
The \textsf{``}algebra\textsf{''} defined in this sense is also relevant to the Church
encoding of a free monad (also known as the \textsf{``}tagless final\index{tagless final}\textsf{''}
-pattern), or more generally to Church encodings of free $P$-typeclasses
+pattern), or more generally to Church encodings of free $FM$-typeclasses
that involve functions of type $\forall E^{\bullet}.\,(S^{E}\leadsto E)\leadsto E$.
That type uses a higher-order type $S^{E}$ parameterized by a \emph{type
constructor} parameter $E^{\bullet}$. In this context, a value of
@@ -763,7 +763,7 @@ \section{How the term \textquotedblleft algebra\textquotedblright{} is used
book, the word \textsf{``}algebra\textsf{''} always means a branch of mathematics,
as in \textsf{``}high-school algebra\textsf{''}. Instead of \textsf{``}algebras\textsf{''} as in Definitions~1
to~3, this book talks about \textsf{``}polynomial types\textsf{''} or \textsf{``}recursive
-polynomial types\textsf{''}, \textsf{``}equations\textsf{''} or \textsf{``}laws\textsf{''}, and $P$-typeclasses.\index{$P$-typeclass}
+polynomial types\textsf{''}, \textsf{``}equations\textsf{''} or \textsf{``}laws\textsf{''}, and $FM$-typeclasses.\index{$FM$-typeclass}
\chapter{Parametricity theorem and naturality laws\label{app:Proofs-of-naturality-parametricity}}
@@ -1448,8 +1448,7 @@ \subsubsection{Statement \label{subsec:Proof-of-the-profunctor-commutativity-law
This equation is exactly the same as the commutativity law~(\ref{eq:profunctor-commutativity-law})
that we need to prove. $\square$
-Similarly, we can prove the commutativity laws for bifunctors and
-bi-contrafunctors.
+Similarly, we can prove the commutativity laws for bifunctors:
\subsubsection{Statement \label{subsec:Proofs-of-commutativity-for-bifunctor}\ref{subsec:Proofs-of-commutativity-for-bifunctor}}
@@ -1485,13 +1484,13 @@ \subsubsection{Statement \label{subsec:Proofs-of-commutativity-for-bifunctor}\re
The commutativity law~(\ref{eq:bi-contrafunctor-commutativity-law})
of bi-contrafunctors is the same as the naturality law of $\text{cmap}_{P^{A,\bullet}}$
with respect to the type parameter $A$. That naturality law holds
-by assumption.$\square$
+by assumption. $\square$
The same techniques and proofs apply to type constructors with more
than two type parameters. Liftings with respect to separate type
parameters always commute.
-\section{Relational formulation of parametricity\label{sec:Parametricity-theorem-for-relations}\label{subsec:Relations-between-types}}
+\section{Relational formulation of parametricity\label{sec:Parametricity-theorem-for-relations}}
Naturality laws are formulated using arbitrary functions $f^{:A\rightarrow B}$
between arbitrary types $A$ and $B$. Typically, a naturality law
@@ -1554,7 +1553,7 @@ \section{Relational formulation of parametricity\label{sec:Parametricity-theorem
\end{lstlisting}
must be an identity function.
-\subsection{Relations between values of different types}
+\subsection{Relations between values of different types\label{subsec:Relations-between-types}}
Programmers are familiar with \textsf{``}relations\textsf{''} as tables in relational
databases. A simple table has two columns with values of some fixed
@@ -3314,13 +3313,13 @@ \subsection{Strong dinaturality: definition and general properties\label{subsec:
\paragraph{Remark}
-Strong dinaturality does \emph{not} hold when the type signature involves
-deeply nested functions such as $F^{R}\triangleq\forall A.\,(\left(A\rightarrow R\right)\rightarrow A)\rightarrow A$.
+Strong dinaturality does \emph{not} hold when the type contains deeply
+nested higher-order functions such as $F^{R}\triangleq\forall A.\,(\left(A\rightarrow R\right)\rightarrow A)\rightarrow A$.
It turns out that $F^{R}\cong R$ (see Exercise~\ref{par:Problem-Peirce-law}).
-To prove that, one needs to use more advanced techniques that use
-the relational naturality law in its full generality. The wedge law
-still holds for functions of type $F^{R}$ but does not provide enough
-information for proving the type equivalence $F^{R}\cong R$. $\square$
+To prove that, one needs to use more advanced techniques. The wedge
+law still holds for functions of type $F^{R}$ but does not provide
+enough information for proving the type equivalence $F^{R}\cong R$.
+$\square$
As motivation, we begin by looking at the wedge law~(\ref{eq:wedge-law-for-profunctors})
in more detail.
@@ -4317,8 +4316,8 @@ \subsubsection{Statement \label{subsec:Statement-post-wedge-entails-strong-dinat
This is the strong dinaturality law of $t$. $\square$
We will now do structural analysis to describe the profunctors with
-the post-wedge property.\footnote{The following derivations are adapted from these unpublished talk
-slides by V.~Vene:\index{Varmo Vene} \texttt{\href{https://www.ioc.ee/~tarmo/tday-voore/vene-slides.pdf}{https://www.ioc.ee/$\sim$tarmo/tday-voore/vene-slides.pdf}}}
+the post-wedge property.\footnote{The following derivations are adapted from the following unpublished
+talk slides by V.~Vene:\index{Varmo Vene} \texttt{\href{https://www.ioc.ee/~tarmo/tday-voore/vene-slides.pdf}{https://www.ioc.ee/$\sim$tarmo/tday-voore/vene-slides.pdf}}}
\subsubsection{Statement \label{subsec:Statement-post-wedge}\ref{subsec:Statement-post-wedge}}
@@ -4510,8 +4509,9 @@ \subsubsection{Example \label{subsec:Example-strong-dinaturality-for-some-type-s
to show that strong dinaturality holds for all fully parametric functions
with the following type signatures:
-\textbf{(a)} $\forall A.\,F^{A}\rightarrow L^{A,A}\quad.$\textbf{$\quad$(b)}
-$\forall A.\,(F^{A}\rightarrow G^{A})\rightarrow L^{A,A}\quad.$
+\textbf{(a)} $\forall A.\,F^{A}\rightarrow L^{A,A}\quad.$
+
+\textbf{(b)} $\forall A.\,(F^{A}\rightarrow G^{A})\rightarrow L^{A,A}\quad.$
\subparagraph{Solution}
@@ -4524,13 +4524,13 @@ \subsubsection{Example \label{subsec:Example-strong-dinaturality-for-some-type-s
$K$ will have the post-wedge property. Strong dinaturality will then
follow from Statement~\ref{subsec:Statement-post-wedge-entails-strong-dinaturality}.
-\textbf{(b)} The type signature $\forall A.\,(F^{A}\rightarrow G^{A})\rightarrow L^{A,A}$
-needs to be expressed as $\forall A.\,K^{A,A}\rightarrow L^{A,A}$
-with some profunctor $K$. We define $K^{X,Y}\triangleq M^{Y,X}\rightarrow N^{X,Y}$
-with suitably chosen profunctors $M$ and $N$. Reasoning as before,
-we find that the profunctors $M$ and $N$ will depend only on one
-of their type parameters. So, they will have the post-wedge property.
-In addition, Example~\ref{subsec:Example-weak-pullback-property-1}(a)
+\textbf{(b)} The type signature $(F^{A}\rightarrow G^{A})\rightarrow L^{A,A}$
+needs to be expressed as $K^{A,A}\rightarrow L^{A,A}$ with some profunctor
+$K$. Then we can write $K^{X,Y}\triangleq M^{Y,X}\rightarrow N^{X,Y}$
+with the profunctors $M$ and $N$ chosen appropriately. Reasoning
+as before, we find that the profunctors $M$ and $N$ will depend
+only on one of their type parameters. So, they will have the post-wedge
+property. In addition, Example~\ref{subsec:Example-weak-pullback-property-1}(a)
shows that $M$ has the pushout property. The post-wedge property
of $K$ is then established via Statement~\ref{subsec:Statement-post-wedge}(d).
So, the profunctor $K$ satisfies the conditions of Statement~\ref{subsec:Statement-post-wedge-entails-strong-dinaturality}.
@@ -4896,7 +4896,7 @@ \subsubsection{Example \label{subsec:Example-strong-dinaturality-proof-of-foldFn
property. By Statement~\ref{subsec:Statement-post-wedge-entails-strong-dinaturality},
$f$ satisfies the strong dinaturality law.
-\subsection{Universal type quantifiers. Notation. Using Yoneda identities}
+\subsection{Universal type quantifiers. Notation. Using Yoneda identities\label{subsec:Universal-type-quantifiers}}
Throughout this book, we have been using type quantifiers to denote
type signatures of generic functions. For instance, the function \lstinline!pure!
@@ -4935,7 +4935,8 @@ \subsection{Universal type quantifiers. Notation. Using Yoneda identities}
We say that the type parameter $X$ is \textbf{bound}\index{bound type parameter}
within the type expression $\forall X.\,F^{X}$. But the type parameter
-$X$ is \emph{free} in the type expression $F^{X}$.
+$X$ is \emph{free} \index{free type parameter}in the type expression
+$F^{X}$.
Note that the type $\forall X.\,F^{X}$ is also different from just
the type constructor $F$. To clarify this point, consider again the
@@ -5127,11 +5128,11 @@ \subsubsection{Example \label{subsec:Example-complicated-type-equivalence-2}\ref
Simplify the type $\forall A.\,((A\rightarrow P)\rightarrow Q)\rightarrow(A\rightarrow S)\rightarrow R$.
-\subparagraph{Solution}
-
-\footnote{See \texttt{\href{https://cstheory.stackexchange.com/questions/51932}{https://cstheory.stackexchange.com/questions/51932}}.
+\subparagraph{Solution\protect\footnote{See \texttt{\protect\href{https://cstheory.stackexchange.com/questions/51932}{https://cstheory.stackexchange.com/questions/51932}}.
The author thanks Dan Doel\index{Dan Doel} for assistance with solving
-this example.}Swap the curried arguments in the given type and get:
+this example.}}
+
+Swap the curried arguments in the given type and get:
\begin{align*}
& \forall A.\,((A\rightarrow P)\rightarrow Q)\rightarrow(A\rightarrow S)\rightarrow R\\
& \cong\forall A.\,(A\rightarrow S)\rightarrow((A\rightarrow P)\rightarrow Q)\rightarrow R\\
@@ -5240,7 +5241,7 @@ \subsubsection{Statement \label{subsec:Statement-covariant-yoneda-identity-for-t
functor\index{functor!higher-order}\index{higher-order functor}.
That is, $S^{F}$ is a type that depends covariantly on an arbitrary
type constructor $F$. An example of such $S$ is $S^{F}\triangleq F^{\text{Int}}\times F^{\text{String}}$.
-Denote by $P\leadsto F$ the type $\forall A.\,P^{A}\rightarrow F^{A}$
+Denote by $P\leadsto F$ the function type $\forall A.\,P^{A}\rightarrow F^{A}$
that does \emph{not} require naturality law (and $P$ and $F$ are
not necessarily functors). Then the type $S^{P}$ is equivalent to
the function type $\forall F.\,(P\leadsto F)\rightarrow S^{F}$, where
@@ -5353,8 +5354,8 @@ \subsection{The Church encoding of recursive types: Proofs\label{subsec:The-Chur
\end{lstlisting}
In this section, we will study the type equivalence~(\ref{eq:Church-encoding-recursive-type}).
-Note that the Yoneda lemma cannot be used to prove Eq.~(\ref{eq:Church-encoding-recursive-type}).
-The Yoneda lemma only applies to types of the form $\forall X.\,(A\rightarrow X)\rightarrow F^{X}$,
+Note that the Yoneda identities cannot be used to prove Eq.~(\ref{eq:Church-encoding-recursive-type}).
+The covariant Yoneda identity only applies to types of the form $\forall X.\,(A\rightarrow X)\rightarrow F^{X}$,
where the type $A$ cannot depend on the quantified type $X$.
It turns out that the type $T$ is non-void if and only if $F^{\bbnum 0}$
@@ -5371,8 +5372,8 @@ \subsubsection{Statement \label{subsec:Statement-existence-of-church-encoding-ty
\subparagraph{Proof}
\textbf{(a)} To prove that $T\neq\bbnum 0$ when $F^{\bbnum 0}\neq\bbnum 0$,
-it is sufficient to implement any function $f$ of type $F^{\bbnum 0}\rightarrow T$.
-The code for that function is:
+it is sufficient to produce a function $f$ of type $F^{\bbnum 0}\rightarrow T$.
+Such a function exists:
\[
f:F^{\bbnum 0}\rightarrow T\quad,\quad\quad f(p^{:F^{\bbnum 0}})\triangleq\forall X.\,q^{:F^{X}\rightarrow X}\rightarrow q(p\triangleright\text{absurd}^{\uparrow F})\quad.
\]
@@ -5382,7 +5383,7 @@ \subsubsection{Statement \label{subsec:Statement-existence-of-church-encoding-ty
\textbf{(b)} To prove that $T=\bbnum 0$ when $F^{\bbnum 0}=\bbnum 0$,
we note that a type $A$ is void if and only if we can implement a
function of type $A\rightarrow\bbnum 0$ . So, we will prove item
-\textbf{(b)} if we implement any function $g$ of type:
+\textbf{(b)} if we implement a function $g$ of type:
\[
g:(F^{\bbnum 0}\rightarrow\bbnum 0)\rightarrow T\rightarrow\bbnum 0\quad.
\]
@@ -5723,7 +5724,7 @@ \subsubsection{Statement \label{subsec:Statement-catamorphism-church-encoding}\r
is also a fixpoint-preserving function from $T$ to $T$. So, $\text{cata}_{F}(\text{fix}_{T})$
must be equal to that identity function.
-\subsection{The Church-Yoneda identity and its applications}
+\subsection{The Church-Yoneda identity and its applications\label{subsec:The-Church-Yoneda-identity}}
We have seen in Section~\ref{subsec:The-Church-encoding-of-recursive-types}
that the least fixpoint of a functor $F$, which we denote by $\mu A.\,F^{A}$,
@@ -5834,8 +5835,8 @@ \subsubsection{Statement \label{subsec:Statement-Church-Yoneda-identity}\ref{sub
a fixpoint of a functor that itself involves a fixpoint. The following
statements show how to simplify nested fixpoints.
-\subsubsection{Statement \label{subsec:Statement-nested-fixpoints}\ref{subsec:Statement-nested-fixpoints}(nested
-fixpoint lemma)}
+\subsubsection{Statement \label{subsec:Statement-nested-fixpoints}\ref{subsec:Statement-nested-fixpoints}
+(nested fixpoint lemma)}
For any bifunctor $N$:
\[
@@ -6079,7 +6080,7 @@ \subsection{Least fixpoints of mutually recursive types\label{subsec:Least-fixpo
and then simplify those types via Statement~\ref{subsec:Statement-nested-fixpoint-under-functor}
and convert to Church encodings via the Church-Yoneda identity.
-\subsection{Non-disjunctive type constructors}
+\subsection{Non-disjunctive type constructors\label{subsec:Non-disjunctive-type-constructors}}
Generally, the type expression $P\rightarrow Q+R$ is not equivalent
to $(P\rightarrow Q)+(P\rightarrow R)$. However, the situation becomes
@@ -6407,9 +6408,8 @@ \subsubsection{Statement \label{subsec:Statement-undisjunctive-type-constructors
A type constructor $P$ is lifting-to-empty when:
-\textbf{(f)} $P^{A}\triangleq A$. (Compare with item \textbf{(b)}
-to see that a type constructor can be lifting-to-full and lifting-to-empty
-at the same time.)
+\textbf{(f)} $P^{A}\triangleq A$. (Item \textbf{(b)} shows that the
+same type constructor can be lifting-to-full and lifting-to-empty.)
\textbf{(g)} $P^{A}\triangleq K^{A}\times L^{A}$ where $K$ is lifting-to-empty
and $L$ is arbitrary.
@@ -6417,6 +6417,16 @@ \subsubsection{Statement \label{subsec:Statement-undisjunctive-type-constructors
\textbf{(h)} $P^{A}\triangleq K^{A}\rightarrow L^{A}$ where $K$
is \emph{not} lifting-to-empty and $L$ is lifting-to-empty.
+A type constructor $P$ is \emph{not} lifting-to-empty when:
+
+\textbf{(i)} $P^{A}\triangleq A\rightarrow A$.
+
+\textbf{(j)} $P^{A}\triangleq Z+K^{A}$ where $K$ is arbitrary and
+$Z\neq\bbnum 0$ is a fixed type.
+
+\textbf{(k)} $P^{A}\triangleq K^{A}\rightarrow L^{A}$ where $K$
+is arbitrary and $L$ is \emph{not} lifting-to-empty.
+
\subparagraph{Proof}
\textbf{(a)} Consider $P^{A}\triangleq K^{A}\times L^{A}$ where $K^{A}\triangleq A$
@@ -6433,12 +6443,12 @@ \subsubsection{Statement \label{subsec:Statement-undisjunctive-type-constructors
\bbnum 1 & \bbnum 0 & \_\rightarrow r(a)
\end{array}\quad,
\end{align*}
-where $q:A\rightarrow Q^{A}$ and $r:A\rightarrow R^{A}$ are some
-functions (that we could assume to exist, for the purpose of this
-example). The function $f$ returns different parts of the disjunction
-$Q^{A}+R^{A}$ depending on its input value (of type $P^{A}$). So,
-the type expression $P^{A}$ appears to contain \textsf{``}disjunctive information\textsf{''};
-that is, $P$ fails to be non-disjunctive.
+Here $q:A\rightarrow Q^{A}$ and $r:A\rightarrow R^{A}$ are some
+functions that will exist for some $Q$ and $R$. The function $f$
+returns different parts of the disjunctive type $Q^{A}+R^{A}$ depending
+on its input value (of type $P^{A}$). So, the type expression $P^{A}$
+appears to contain \textsf{``}disjunctive information\textsf{''}. We say that $P$
+fails to be non-disjunctive.
\textbf{(b)} The unit type ($\bbnum 1$) has only one distinct value.
So, any relation $r^{:A\leftrightarrow B}$ lifted to $P^{A}\triangleq\bbnum 1$
@@ -6477,25 +6487,64 @@ \subsubsection{Statement \label{subsec:Statement-undisjunctive-type-constructors
\textbf{(h)} By assumption, $K$ is \emph{not} lifting-to-empty, which
means that there exist types $A$, $B$ such that \emph{any} relation
-$r^{:A\leftrightarrow B}$ is lifted to a relation $r^{\updownarrow K}$
-that is non-empty. As $L$ is lifting-to-empty, we can choose $r^{:A\leftrightarrow B}$
+$r^{:A\leftrightarrow B}$ is lifted to a non-empty relation $r^{\updownarrow K}\neq\emptyset$.
+As $L$ is lifting-to-empty, we can choose $r^{:A\leftrightarrow B}$
such that $r^{\updownarrow L}=\emptyset^{:L^{A}\leftrightarrow L^{B}}$.
Now lift that relation $r$ to $P$ and obtain:
\[
r^{\updownarrow P}=r^{\updownarrow K}\ogreaterthan r^{\updownarrow L}=r^{\updownarrow K}\ogreaterthan\emptyset\quad.
\]
By Statement~\ref{subsec:Statement-full-empty-combinators}(f), we
-have $r^{\updownarrow K}\ogreaterthan\emptyset=\emptyset$. $\square$
+have $r^{\updownarrow K}\ogreaterthan\emptyset=\emptyset$.
+
+\textbf{(i)} To show that $P$ is not lifting-to-empty, we need to
+prove that for any relation $r^{:A\leftrightarrow B}$ there exist
+$x^{:P^{A}}$ and $y^{:P^{B}}$ such that $(x,y)\in r^{\updownarrow P}$.
+Write out the condition $(x,y)\in r^{\updownarrow P}$:
+\[
+(x,y)\in r^{\updownarrow P}\quad\text{means}\quad\text{if}\quad(a^{:A},b^{:B})\in r\quad\text{then}\quad(x(a),y(b))\in r\quad.
+\]
+If we choose $x\triangleq\text{id}^{:A\rightarrow A}$ and $y\triangleq\text{id}^{:B\rightarrow B}$,
+we will have $(x(a),y(b))=(a,b)$. Then the condition becomes: if
+$(a,b)\in r$ then $(a,b)\in r$. This holds for any $r$. So, for
+any $r$ there exist $x$, $y$ such that $(x,y)\in r^{\updownarrow P}$.
+
+\textbf{(j)} Lifting any relation $r^{:A\leftrightarrow B}$ to $P$,
+we find:
+\[
+r^{\updownarrow P}=\text{id}^{:Z\leftrightarrow Z}\boxplus r^{\updownarrow K}\quad.
+\]
+By assumption $Z\neq\bbnum 0$, so we may choose a value $z^{:Z}$
+and set $x^{:P^{A}}\triangleq z+\bbnum 0^{:A}$ and $y^{:P^{B}}\triangleq z+\bbnum 0^{:B}$.
+The values $x$, $y$ are always in the relation $\text{id}^{:Z\leftrightarrow Z}\boxplus r^{\updownarrow K}$
+for any $r$. It follows that $r^{\updownarrow P}$ is not empty for
+any $r$.
+
+\textbf{(k)} We need to show that for any types $A$, $B$ and for
+any $r^{:A\leftrightarrow B}$ there exist values $x^{:P^{A}}$, $y^{:P^{B}}$
+such that $(x,y)\in r^{\updownarrow P}$. By assumption, $L$ is \emph{not}
+lifting-to-empty, so for any types $A$, $B$ and for any $r^{:A\leftrightarrow B}$
+there exist values $p^{:L^{A}}$, $q^{:L^{B}}$ such that $(p,q)\in r^{\updownarrow L}$.
+We choose $x\triangleq\_^{:K^{A}}\rightarrow p$ and $y\triangleq\_^{:K^{B}}\rightarrow q$.
+We will now show that $(x,y)\in r^{\updownarrow P}$. Since $P^{A}=K^{A}\rightarrow L^{A}$,
+the lifting to $P$ is given via the pair mapper:
+\[
+(x,y)\in r^{\updownarrow P}\quad\text{means}\quad\forall(a^{:K^{A}},b^{:K^{B}}):\quad\text{if}\quad(a,b)\in r^{\updownarrow K}\quad\text{then}\quad(x(a),y(b))\in r^{\updownarrow L}\quad.
+\]
+We have defined $x$ and $y$ as constant functions that always return
+$p$ and $q$. So, we always have $(x(a),y(b))\in r^{\updownarrow L}$
+for any $a$, $b$. It follows that $(x,y)\in r^{\updownarrow P}$.
+$\square$
The following examples will help build up more intuition.
\subsubsection{Example \label{subsec:Example-undisjunctive-type-constructors}\ref{subsec:Example-undisjunctive-type-constructors}\index{examples}}
-\textbf{(a)} Show that $P^{A}\triangleq A\rightarrow A$ is lifting-to-full
-but \emph{not} lifting-to-empty.
+\textbf{(a)} Show that $P^{A}\triangleq A\times F^{A}\rightarrow A$
+is lifting-to-full for any $F$.
-\textbf{(b)} Show that $P^{A}\triangleq\bbnum 1+A\rightarrow A$ is
-both lifting-to-full and lifting-to-empty.
+\textbf{(b)} Show that $P^{A}\triangleq\bbnum 1+F^{A}\rightarrow A$
+is both lifting-to-full and lifting-to-empty for any $F$.
\textbf{(c)} Show that $P^{A}\triangleq F^{A}\rightarrow A$ is lifting-to-full
for any $F$.
@@ -6504,9 +6553,10 @@ \subsubsection{Example \label{subsec:Example-undisjunctive-type-constructors}\re
is both lifting-to-full and lifting-to-empty.
It follows from Statement~\ref{subsec:Statement-undisjunctive-type-constructors-relational}
-that all those type constructors denoted by $P$ are non-disjunctive.
-Then it follows that, for any type constructors $F$, $G$ (not necessarily
-covariant or contravariant):
+that all the above type constructors denoted by $P$ are non-disjunctive.
+
+For any type constructors $F$, $G$ (not necessarily covariant or
+contravariant):
\textbf{(e)} $\forall A.\,F^{A}+G^{A}\cong(\forall A.\,F^{A})+(\forall A.\,G^{A})$.
@@ -6516,41 +6566,27 @@ \subsubsection{Example \label{subsec:Example-undisjunctive-type-constructors}\re
\textbf{(a)} We know from Statement~\ref{subsec:Statement-undisjunctive-type-constructors-structural}(c)
that $L^{A}\triangleq A$ is lifting-to-full. It follows from Statement~\ref{subsec:Statement-undisjunctive-type-constructors-structural}(d)
-with $K^{A}\triangleq L^{A}\triangleq A$ that $P$ is also lifting-to-full.
-
-To show that $P$ is not lifting-to-empty, it is sufficient to demonstrate
-that for any relation $r^{:A\leftrightarrow B}$ there exist $x^{:P^{A}}$
-and $y^{:P^{B}}$ such that $(x,y)\in r^{\updownarrow P}$. Write
-out the condition $(x,y)\in r^{\updownarrow P}$:
-\[
-(x,y)\in r^{\updownarrow P}\quad\text{means}\quad\text{if}\quad(a^{:A},b^{:B})\in r\quad\text{then}\quad(x(a),y(b))\in r\quad.
-\]
-If we choose $x\triangleq\text{id}^{:A\rightarrow A}$ and $y\triangleq\text{id}^{:B\rightarrow B}$,
-we will have $(x(a),y(b))=(a,b)$. Then the condition becomes: if
-$(a,b)\in r$ then $(a,b)\in r$. This is true for any $r$. So, $(x,y)\in r^{\updownarrow P}$
-holds.
+with $K^{A}\triangleq A\times F^{A}$ and $L^{A}\triangleq A$ that
+$P$ is also lifting-to-full.
\textbf{(b)} We know from Statement~\ref{subsec:Statement-undisjunctive-type-constructors-structural}(c,f)
that $L^{A}\triangleq A$ is both lifting-to-full and lifting-to-empty.
By Statement~\ref{subsec:Statement-undisjunctive-type-constructors-structural}(d)
-with $K^{A}\triangleq\bbnum 1+A$ and $L^{A}\triangleq A$, we find
-that $K^{A}\rightarrow L^{A}$ is lifting-to-full. To show that $K^{A}\rightarrow L^{A}$
-is lifting-to-empty, we can use Statement~\ref{subsec:Statement-undisjunctive-type-constructors-structural}(h)
-if we prove that $K^{A}$ is \emph{not} lifting-to-empty. Lifting
-any relation $r^{:A\leftrightarrow B}$ to $K$, we find:
-\[
-r^{\updownarrow K}=\text{id}^{:\bbnum 1\leftrightarrow\bbnum 1}\boxplus r\quad.
-\]
-The pair of values $x^{:K^{A}}\triangleq1+\bbnum 0^{:A}$ and $y^{:K^{B}}\triangleq1+\bbnum 0^{:B}$
-are always in the relation $\text{id}\boxplus r$. In this way, we
-have shown that $r^{\updownarrow K}$ is not empty.
+with $K^{A}\triangleq\bbnum 1+F^{A}$ and $L^{A}\triangleq A$, we
+find that $K^{A}\rightarrow L^{A}$ is lifting-to-full. To show that
+$K^{A}\rightarrow L^{A}$ is lifting-to-empty, we can use Statement~\ref{subsec:Statement-undisjunctive-type-constructors-structural}(j)
+with $Z=\bbnum 1$ to see that $K^{A}$ is \emph{not} lifting-to-empty,
+while we know that $L^{A}$ is lifting-to-empty. It follows from Statement~\ref{subsec:Statement-undisjunctive-type-constructors-structural}(h)
+that $K$ is lifting-to-empty.
By Statement~\ref{subsec:Statement-undisjunctive-type-constructors-relational}(h),
the type constructor $P$ is non-disjunctive.
-Note that the type expression $\bbnum 1+A\rightarrow A$ contains
-a disjunctive type but can be rewritten equivalently as $P^{A}\cong(\bbnum 1\rightarrow A)\times(A\rightarrow A)$,
-which no longer contains a disjunctive type.
+Note that the type expression $\bbnum 1+F^{A}\rightarrow A$ appears
+to contain a disjunctive type but can be rewritten equivalently as
+$P^{A}\cong(\bbnum 1\rightarrow A)\times(F^{A}\rightarrow A)$, which
+no longer contains a disjunctive type. (If $F^{A}$ is disjunctive
+then $F^{A}\rightarrow A$ can be rewritten similarly.)
\textbf{(c)} We have shown in Statement~\ref{subsec:Statement-undisjunctive-type-constructors-structural}(c)
$L^{A}\triangleq A$ is lifting-to-full. It remains to use Statement~\ref{subsec:Statement-undisjunctive-type-constructors-structural}(d)
@@ -6575,12 +6611,42 @@ \subsubsection{Example \label{subsec:Example-undisjunctive-type-constructors}\re
is non-disjunctive because it is lifting-to-full, as we showed in
item (d). $\square$
+Table~\ref{tab:Non-disjunctive-type-constructions} shows some general
+formulas for non-disjunctive type constructors that follow from Statement~\ref{subsec:Statement-undisjunctive-type-constructors-structural}.
+
+\begin{table}
+\begin{centering}
+\begin{tabular}{|c|c|}
+\hline
+\textbf{\footnotesize{}Construction} & \textbf{\footnotesize{}Assumptions}\tabularnewline
+\hline
+\hline
+{\footnotesize{}$F^{A}\triangleq A$} & \tabularnewline
+\hline
+{\footnotesize{}$F^{A}\triangleq G^{A}\rightarrow A$} & {\footnotesize{}For any $G^{A}$}\tabularnewline
+\hline
+{\footnotesize{}$F^{A}\triangleq G^{A}\rightarrow H^{A}$} & {\footnotesize{}$H$ is lifting-to-full, $G$ is any type constructor}\tabularnewline
+\hline
+{\footnotesize{}$F^{A}\triangleq A\times G^{A}\rightarrow H^{A}$} & {\footnotesize{}For any $G^{A}$ and for any $H^{A}$}\tabularnewline
+\hline
+{\footnotesize{}$F^{A}\triangleq(Z+K^{A}\rightarrow A\times G^{A})\rightarrow H^{A}$} & {\footnotesize{}For any $G^{A}$, $H^{A}$, $K^{A}$, and a fixed
+type $Z\neq\bbnum 0$}\tabularnewline
+\hline
+{\footnotesize{}$F^{A}\triangleq((L^{A}\rightarrow Z+K^{A})\rightarrow A\times G^{A})\rightarrow H^{A}$} & {\footnotesize{}For any $G^{A}$, $H^{A}$, $K^{A}$, $L^{A}$, and
+$Z\neq\bbnum 0$}\tabularnewline
+\hline
+\end{tabular}
+\par\end{centering}
+\caption{Lifting-to-full type constructors.\label{tab:Non-disjunctive-type-constructions}}
+
+\end{table}
+
We will now show some application of these techniques.
\subsubsection{Statement \label{subsec:Statement-application-full-relation}\ref{subsec:Statement-application-full-relation}}
Suppose $F$ is any lifting-to-full type constructor that is not identically
-void ($F^{A}\neq0$ for some $A$). Under assumptions of parametricity,
+void ($F^{A}\neq\bbnum 0$ for some $A$). Under assumptions of parametricity,
we have the following type isomorphisms:
\textbf{(a)} For any fixed type $P$:
@@ -6669,7 +6735,7 @@ \subsubsection{Statement \label{subsec:Statement-advanced-type-equivalence}\ref{
\[
\forall A.\,((A\rightarrow A)\rightarrow A)\rightarrow A=T\cong\bbnum 1+\bbnum 2+\bbnum 3+...\quad.
\]
- The \textsf{``}infinite\textsf{''} type in the right-hand side is understood as the
+The \textsf{``}infinite\textsf{''} type in the right-hand side is understood as the
type of pairs of natural numbers $\left(n,k\right)$ such that $n\ge k\ge1$.
The value $n$ points to the part $\bbnum n$ of the disjunctive type;
the value $k$ is one of the values of type $\bbnum n$.
@@ -6681,7 +6747,7 @@ \subsubsection{Statement \label{subsec:Statement-advanced-type-equivalence}\ref{
\]
-\subparagraph{Proof}
+\subparagraph{Proof\protect\footnote{See \texttt{\protect\href{https://cstheory.stackexchange.com/questions/53855/}{https://cstheory.stackexchange.com/questions/53855/}}}}
Rewrite the given type using various type identities:
\begin{align*}
@@ -6831,8 +6897,8 @@ \subsubsection{Statement \label{subsec:Statement-general-identities-forall}\ref{
To get some intuition for items \textbf{(b)} and \textbf{(c)}, consider
how those types are written in the syntax of Scala 3. The type corresponding
to $\forall X.\,F^{X}\times G^{X}$ is written as \lstinline![X] => (F[X], G[X])!.
-If we imagine that {[}X{]} were an ordinary argument (not a type parameter),
-we would apply the standard type identities:
+If we imagine that \lstinline![X]! were an ordinary argument (not
+a type parameter), we would apply the standard type identities:
\begin{align*}
& A\rightarrow B\times C\cong(A\rightarrow B)\times(A\rightarrow C)\quad,\\
& A\rightarrow R\rightarrow B\cong R\rightarrow A\rightarrow B\quad,
@@ -6850,13 +6916,14 @@ \subsubsection{Statement \label{subsec:Statement-general-identities-forall}\ref{
\end{lstlisting}
These type formulas are exactly similar to the isomorphisms \textbf{(b)}
and \textbf{(c)}. However, \lstinline!X! is a type parameter, not
-a value parameter, so it is invalid to use ordinary type identities
+a value parameter, and it is invalid to use ordinary type identities
such as $A\rightarrow R\rightarrow B\cong R\rightarrow A\rightarrow B$
and assign $A=$ \lstinline![X]!. We need a new proof.
\subparagraph{Proof}
-\textbf{(a)} This isomorphism is shown in Example~\ref{subsec:Example-undisjunctive-type-constructors}(e).
+\textbf{(a)} This isomorphism is proved in Example~\ref{subsec:Example-undisjunctive-type-constructors}(e).
+
It is a \textsf{``}non-constructive\textsf{''} isomorphism, in the following sense.
We can define a function \lstinline!outS! that transforms the left-hand
side into the right-hand side:
@@ -7002,7 +7069,7 @@ \subsubsection{Statement \label{subsec:Statement-quantifier-across-functor}\ref{
For any strictly positive bifunctor $S$ and any type constructors
$P$, $Q$, we have:
\[
-\forall A.\,S^{P^{A},Q^{A}}\cong S^{\forall A.\,P^{A},\forall A.\,Q^{A}}\quad.
+\forall A.\,S^{P^{A},\,Q^{A}}\cong S^{\forall A.\,P^{A},\,\forall A.\,Q^{A}}\quad.
\]
Similar identities hold for strictly positive $3$-functors, $4$-functors,
etc.
@@ -7050,9 +7117,9 @@ \subsubsection{Statement \label{subsec:Statement-quantifier-across-functor}\ref{
that the statement is already true for recursive usages of $F$ under
$S$.) We get:
\begin{align*}
- & \forall A.\,F^{P^{A}}=\forall A.\,S^{P^{A},F^{P^{A}}}\\
-{\color{greenunder}\text{inductive assumption}:}\quad & \cong S^{\forall A.\,P^{A},\gunderline{\forall A.\,F^{P^{A}}}}\\
-{\color{greenunder}\text{inductive assumption}:}\quad & \cong S^{\forall A.\,P^{A},F^{\forall A.\,P^{A}}}=F^{\forall A.\,P^{A}}\quad.
+ & \forall A.\,F^{P^{A}}=\forall A.\,S^{P^{A},\,F^{P^{A}}}\\
+{\color{greenunder}\text{inductive assumption}:}\quad & \cong S^{\forall A.\,P^{A},\,\gunderline{\forall A.\,F^{P^{A}}}}\\
+{\color{greenunder}\text{inductive assumption}:}\quad & \cong S^{\forall A.\,P^{A},\,F^{\forall A.\,P^{A}}}=F^{\forall A.\,P^{A}}\quad.
\end{align*}
The identities for bifunctors, $3$-functors, etc., are proved in
@@ -7061,7 +7128,7 @@ \subsubsection{Statement \label{subsec:Statement-quantifier-across-functor}\ref{
We will now prove some statements showing miscellaneous additional
techniques for simplifying universally quantified types.
-\subsubsection{Statement \label{subsec:Statement-Fubini-theorem-1}\ref{subsec:Statement-Fubini-theorem-1} }
+\subsubsection{Statement \label{subsec:Statement-Fubini-theorem-1}\ref{subsec:Statement-Fubini-theorem-1}}
If any type constructor $F$ is such that $F^{\bbnum 0}\cong\bbnum 0$
then:
@@ -7233,7 +7300,9 @@ \subsubsection{Example \label{subsec:Example-complicated-type-equivalence-3}\ref
\subsubsection{Example \label{subsec:Example-simplify-quantifier-A-A}\ref{subsec:Example-simplify-quantifier-A-A}}
\textbf{(a)} Show that $\forall A.\,F^{A\rightarrow A}\cong F^{\bbnum 1}$
-for any strictly positive functor $F$.
+for any strictly positive functor $F$. (See Definition~\ref{subsec:Definition-strictly-positive-functor}.)
+It is unknown if this holds for covariant functors $F$ that are not
+strictly positive; see Problem~\ref{par:Problem-Peirce-law-1}.
\textbf{(b)} Show that for any contrafunctor $F$, the same holds:
$\forall A.\,F^{A\rightarrow A}\cong F^{\bbnum 1}$.
@@ -7266,1637 +7335,1790 @@ \subsubsection{Example \label{subsec:Example-simplify-quantifier-A-A}\ref{subsec
which is equivalent to the type of natural numbers. That type is \emph{not}
equivalent to $F^{\bbnum 1}$. $\square$
-\subsection{The Jaskelioff-O\textsf{'}Connor theorem for simple types}
+\subsection{Existential type quantifiers. Co-Yoneda identities\label{subsec:Existential-type-quantifiers}}
-The Jaskelioff-O\textsf{'}Connor theorem\footnote{See \texttt{\href{https://arxiv.org/abs/1402.1699}{https://arxiv.org/abs/1402.1699}}}
-is a type equivalence between certain type constructors quantified
-over a typeclass. This section proves a version of that theorem that
-holds for simple types belonging to a $P$-typeclass. Then the theorem
-gives a general type formula for the free construction of any $P$-typeclass.
+The Yoneda identities allow us in many cases to simplify type expressions
+with universal quantifiers. Similar identities hold for existentially
+quantified types.
-\subsubsection{Statement \label{subsec:Statement-JOC-theorem-simple-types}\ref{subsec:Statement-JOC-theorem-simple-types}}
+For the purposes of this and the following sections, we define the
+existential quantifier via Eq.~(\ref{eq:existential-via-universal-Yoneda}):
+\[
+\exists C.\,F^{C}\cong\forall D.\,\big(\forall C.\,(F^{C}\rightarrow D)\big)\rightarrow D\quad.
+\]
+Here $F$ is any type constructor (not necessarily covariant or contravariant).
+
+\subsubsection{Statement \label{subsec:Statement-co-Yoneda-two-identities}\ref{subsec:Statement-co-Yoneda-two-identities}}
+
+For any functor $F$ and any contrafunctor $H$, the following identities
+hold:
+\begin{align*}
+{\color{greenunder}\text{\textbf{(a)} }\text{covariant co-Yoneda identity}:}\quad & \exists A.\,(A\rightarrow R)\times F^{A}\cong F^{R}\quad,\\
+{\color{greenunder}\text{\textbf{(b)} }\text{contravariant co-Yoneda identity}:}\quad & \exists A.\,(R\rightarrow A)\times H^{A}\cong H^{R}\quad.
+\end{align*}
-The free $P$-typeclass instance $E^{T}$ generated by a type $T$
-is equivalent to the type defined by:
-\begin{equation}
-E^{T}\cong\forall(A\in P\text{-typeclass}).\,(T\rightarrow A)\rightarrow A\quad.\label{eq:free-typeclass-via-church-encoding}
-\end{equation}
-Here the quantifier goes only over the types $A$ that belong to the
-$P$-typeclass. It is also assumed that the type in the right-hand
-side of Eq.~(\ref{eq:free-typeclass-via-church-encoding}) admits
-only functions that satisfy the naturality law with respect to $A$.
\subparagraph{Proof}
-One of the defining properties of the free typeclass constructor $E$
-is the one-to-one correspondence between functions of type $T\rightarrow A$
-and $P$-typeclass morphisms of type $E^{T}\rightarrow A$. Denoting
-by $E^{T}\overset{P}{\rightarrow}A$ the type of those morphisms,
-we have:
-\[
-\forall(A\in P\text{-typeclass}).\,(T\rightarrow A)\rightarrow A\cong\forall(A\in P\text{-typeclass}).\,(E^{T}\overset{P}{\rightarrow}A)\rightarrow A\quad.
-\]
+We use Eq.~(\ref{eq:existential-via-universal-Yoneda}) to express
+$\exists A$ via $\forall A$.
-All types $A$ belonging to the $P$-typeclass are $E$-monad algebras,
-and those algebras form a category. Now we use the Yoneda identity
-in that category:
-\[
-\forall(A\in P\text{-typeclass}).\,(X\overset{P}{\rightarrow}A)\rightarrow A\cong X\quad,
-\]
-where $X$ is any fixed type that also belongs to the $P$-typeclass.
-We use this identity with $X=E^{T}$ and obtain:
-\[
-\forall(A\in P\text{-typeclass}).\,(E^{T}\overset{P}{\rightarrow}A)\rightarrow A\cong E^{T}\quad,
-\]
-as required. $\square$
+\textbf{(a)} We write:
+\begin{align*}
+{\color{greenunder}\text{expect to equal }F^{R}:}\quad & \exists A.\,(A\rightarrow R)\times F^{A}\\
+{\color{greenunder}\text{definition of }\exists\text{ in Eq.~}(\ref{eq:existential-via-universal-Yoneda}):}\quad & \cong\forall B.\,\big(\forall A.\,\gunderline{(A\rightarrow R)\times F^{A}}\rightarrow B\big)\rightarrow B\\
+{\color{greenunder}\text{uncurry arguments}:}\quad & \cong\forall B.\,\big(\gunderline{\forall A.\,(A\rightarrow R)\rightarrow F^{A}\rightarrow B}\big)\rightarrow B\\
+{\color{greenunder}\text{contravariant Yoneda identity}:}\quad & \cong\gunderline{\forall B.\,\big(F^{R}\rightarrow B\big)\rightarrow B}\\
+{\color{greenunder}\text{covariant Yoneda identity}:}\quad & \cong F^{R}\quad.
+\end{align*}
-\subsection{The Jaskelioff-O\textsf{'}Connor theorem for type constructors}
+\textbf{(b)} We write:
+\begin{align*}
+{\color{greenunder}\text{expect to equal }H^{R}:}\quad & \exists A.\,(R\rightarrow A)\times H^{A}\\
+{\color{greenunder}\text{definition of }\exists\text{ in Eq.~}(\ref{eq:existential-via-universal-Yoneda}):}\quad & \cong\forall B.\,\big(\forall A.\,\gunderline{(R\rightarrow A)\times H^{A}}\rightarrow B\big)\rightarrow B\\
+{\color{greenunder}\text{uncurry arguments}:}\quad & \cong\forall B.\,\big(\gunderline{\forall A.\,(R\rightarrow A)\rightarrow H^{A}\rightarrow B}\big)\rightarrow B\\
+{\color{greenunder}\text{covariant Yoneda identity}:}\quad & \cong\gunderline{\forall B.\,\big(H^{R}\rightarrow B\big)\rightarrow B}\\
+{\color{greenunder}\text{covariant Yoneda identity}:}\quad & \cong H^{R}\quad.
+\end{align*}
+$\square$
-The full formulation of the theorem involves functor typeclasses instead
-of typeclasses for simple types. The theorem applies to all $P$-typeclasses
-for functors. Those typeclasses have method signatures of the form
-$\forall A.\,(P^{F})^{A}\rightarrow F^{A}$, where $P$ is a functor
-on functors (the kind of $P$ is $(*\rightarrow*)\rightarrow*\rightarrow*$)
-and functions of type $(P^{F})^{A}\rightarrow F^{A}$ are restricted
-to natural transformations between functors $P^{F}$ and $F$. Examples
-of well-known $P$-typeclasses of that form are pointed functors,
-filterable functors, applicative functors, and monads.
+To build up intuition, let us substitute $R=\bbnum 0$ and $R=\bbnum 1$
+into the co-Yoneda identities:
-\subsubsection{Statement \label{subsec:Statement-Jaskelioff-OConnor}\ref{subsec:Statement-Jaskelioff-OConnor}
-(Jaskelioff-O\textsf{'}Connor)}
+\subsubsection{Statement \label{subsec:Statement-co-Yoneda-two-identities-1}\ref{subsec:Statement-co-Yoneda-two-identities-1}}
+
+The following type equivalences hold:
+\begin{align*}
+{\color{greenunder}\text{\textbf{(a)} for any functor }F:}\quad & \exists A.\,F^{A}\cong F^{\bbnum 1}\quad,\\
+{\color{greenunder}\text{\textbf{(b)} for any contrafunctor }F:}\quad & \exists A.\,H^{A}\cong H^{\bbnum 0}\quad.
+\end{align*}
-Given any fixed $P$-typeclass for functors, denote by $E$ the constructor
-of free instances of that typeclass: if $T$ is any functor then the
-functor $E^{T}$ is guaranteed to be an instance of the $P$-typeclass.
-Suppose $A$, $B$, $C$ are some fixed types. Then the following
-type equivalence holds:
-\begin{align}
- & \forall(F\in P\text{-typeclass}).\,(A\rightarrow F^{B})\rightarrow F^{C}\cong(E^{R})^{C}\quad,\label{eq:jaskelioff-o-connor-theorem}\\
-{\color{greenunder}\text{where }R\text{ is defined by}:}\quad & R^{T}\triangleq A\times(B\rightarrow T)\quad.\nonumber
-\end{align}
-Here, it is assumed that the type $(A\rightarrow F^{B})\rightarrow F^{C}$
-is restricted to functions satisfying the naturality law with respect
-to $F$.
\subparagraph{Proof}
-Denote by $K\overset{P}{\rightarrow}L$ the type of $P$-typeclass
-morphisms between functors $K$ and $L$ that belong to the typeclass.
-(The full type signature of a $P$-typeclass morphism is $\forall A.\,K^{A}\overset{P}{\rightarrow}L^{A}$.)
+For \textbf{(a)}, set $R=\bbnum 1$ in the covariant co-Yoneda identity:
+\begin{align*}
+{\color{greenunder}\text{left-hand side}:}\quad & \exists A.\,(\gunderline{A\rightarrow\bbnum 1})\times F^{A}\cong\exists A.\,\bbnum 1\times F^{A}\cong\exists A.\,F^{A}\quad,\\
+{\color{greenunder}\text{right-hand side}:}\quad & F^{\bbnum 1}\quad.
+\end{align*}
-We will prove the type equivalence~(\ref{eq:jaskelioff-o-connor-theorem})
-in three steps.
+For \textbf{(b)}, set $R=\bbnum 0$ in the contravariant co-Yoneda
+identity:
+\begin{align*}
+{\color{greenunder}\text{left-hand side}:}\quad & \exists A.\,(\gunderline{\bbnum 0\rightarrow A})\times H^{A}\cong\exists A.\,\bbnum 1\times H^{A}\cong\exists A.\,H^{A}\quad,\\
+{\color{greenunder}\text{right-hand side}:}\quad & H^{\bbnum 0}\quad.
+\end{align*}
+ $\square$
-\textbf{(1)} Use the Yoneda identity to obtain this type equivalence:
-\[
-A\rightarrow F^{B}\cong\forall X.\,R^{X}\rightarrow F^{X}\quad.
-\]
-To derive this formula, write:
+With these properties, we get the following examples of type equivalences:
\begin{align*}
- & A\rightarrow F^{B}\\
-{\color{greenunder}\text{covariant Yoneda identity}:}\quad & \cong A\rightarrow\forall X.\,(B\rightarrow X)\rightarrow F^{X}\\
-{\color{greenunder}\text{move }\forall X\text{ to front}:}\quad & \cong\forall X.\,A\rightarrow(B\rightarrow X)\rightarrow F^{X}\\
-{\color{greenunder}\text{uncurry the function}:}\quad & \cong\forall X.\,A\times(B\rightarrow X)\rightarrow F^{X}=\forall X.\,R^{X}\rightarrow F^{X}\quad.
+ & \exists A.\,A\cong\bbnum 1\quad,\quad\quad\exists A.\,A\rightarrow R\cong\bbnum 1\quad,\quad\quad\exists A.\,A+R\cong\bbnum 1+R\quad,\\
+ & \exists A.\,(R\rightarrow A)\times(A\rightarrow S)\cong R\rightarrow S\quad,\quad\quad\exists A.\,(A\rightarrow R)\times A\times A\cong R\times R\quad.
\end{align*}
-In the first line of this derivation, we have used the assumption
-that $F$ is a (covariant) functor.
-\textbf{(2)} By the universal property of the free $P$-typeclass
-runner, for any functor $F$ that belongs to the $P$-typeclass and
-for any functor $R$ (not necessarily a member of the $P$-typeclass)
-there is a one-to-one correspondence between $P$-typeclass morphisms
-$E^{R}\overset{P}{\rightarrow}F$ and natural transformations $R\leadsto F$.
-In other words, there is a type equivalence between the following
-types (where we wrote out the full type signatures):
+
+\paragraph{Remarks}
+
+\textbf{(1)} The Scala type \lstinline!Any! closely corresponds to
+the type $\exists X.\,X$, which is equivalent to \lstinline!Unit!.
+The advantage of using \lstinline!Any! instead of \lstinline!Unit!
+is that \lstinline!Any! is understood by the Scala compiler as a
+supertype of \emph{all} Scala types (while \lstinline!Unit! is not).
+Indeed, for any type $T$ there is an injective function $T\rightarrow\exists X.\,X$,
+which corresponds to a function of type \lstinline!T => Any! in Scala:
+\begin{lstlisting}
+def toAny[T](t: T): Any = t
+\end{lstlisting}
+ This is just an identity function that relabels the types. So, this
+function establishes the subtyping relation \lstinline!T <: Any!.
+
+\textbf{(2)} The type equivalence $\exists X.\,X\cong\bbnum 1$ may
+appear counterintuitive. The unit type has only one distinct value;
+but there are infinitely many ways of creating a value of type $\exists X.\,X$.
+We may take any value $t:T$ of any type $T$ and \textsf{``}pack\textsf{''} that
+value into a value of type $\exists X.\,X$ by hiding the type $T$,
+similarly to the function \lstinline!toAny!.
+\begin{lstlisting}[mathescape=true]
+sealed trait ExistsX // Implements the type $\color{dkgreen}\exists X.\,X$.
+final case class ExistsX0[X](x: X)
+def hide[T](t: T): ExistsX = ExistsX0[T](t)
+val x1: ExistsX = hide(123)
+val x2: ExistsX = hide(124)
+val x3: ExistsX = hide("abc")
+\end{lstlisting}
+This code may suggest that we are able to create many different values
+of type \lstinline!ExistsX!. How can it be that \lstinline!ExistsX!
+is equivalent to a unit type with a single distinct value? The reason
+is that no fully parametric functions will be able to detect any difference
+between all those values. A fully parametric function may pattern-match
+on \lstinline!ExistsX0(x)! but must treat the type of \lstinline!x!
+as arbitrary and unknown, with no operations available for computing
+anything out of \lstinline!x!. So, there will be no way to determine
+the actual type and value of \lstinline!x! and to make any decisions
+based on them. A computer\textsf{'}s memory will probably store different bit
+patterns when representing \lstinline!hide(123)! and \lstinline!hide(124)!.
+But that difference remains unobservable in fully parametric code.
+$\square$
+
+We may use Eq.~(\ref{eq:existential-via-universal-Yoneda}) to replace
+the existential quantifier by the universal one when proving properties
+of existentially quantified types.
+
+\subsubsection{Example \label{subsec:Example-simple-existential-derivation}\ref{subsec:Example-simple-existential-derivation}\index{examples}}
+
+Show that $\exists A.\,F^{A}\rightarrow A\cong\bbnum 1$ for any type
+constructor $F$.
+
+\subparagraph{Solution}
+
+Use Eq.~(\ref{eq:existential-via-universal-Yoneda}) and write:
\[
-\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X}\cong\forall X.\,R^{X}\rightarrow F^{X}\quad.
+\exists A.\,F^{A}\rightarrow A=\forall B.\,(\forall A.\,(F^{A}\rightarrow A)\rightarrow B)\rightarrow B\quad.
\]
-Now we set $R^{T}\triangleq A\times(B\rightarrow T)$ and obtain:
+Statement~\ref{subsec:Statement-application-full-relation} with
+$P^{A}\triangleq F^{A}\rightarrow A$ and $K\triangleq B$ shows that
+$\forall A.\,(F^{A}\rightarrow A)\rightarrow B\cong B$ as the type
+constructor $F^{A}\rightarrow A$ is \textsf{``}lifting-to-full\textsf{''} by Statement~\ref{subsec:Statement-undisjunctive-type-constructors-structural}(c,
+d). So, we get:
\[
-(A\rightarrow F^{B})\rightarrow F^{C}\cong(\forall X.\,R^{X}\rightarrow F^{X})\rightarrow F^{C}\cong(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\quad.
+\exists A.\,F^{A}\rightarrow A=\forall B.\,B\rightarrow B\cong\bbnum 1\quad.
\]
-So, the left-hand side of Eq.~(\ref{eq:jaskelioff-o-connor-theorem})
-is equivalent to:
+
+
+\subsubsection{Example \label{subsec:Example-simple-existential-derivation-1-1}\ref{subsec:Example-simple-existential-derivation-1-1}}
+
+Let $P$ and $Q$ be any type constructors.
+
+\textbf{(a)} If $P^{A}\cong Q^{A}$ for all $A$ then $\exists A.\,P^{A}\cong\exists A.\,Q^{A}$.
+
+\textbf{(b)} For arbitrary $P$ and $Q$:
\[
-\forall(F\in P\text{-typeclass}).\,(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\quad.
+\exists A.\,P^{A}+Q^{A}\cong(\exists A.\,P^{A})+(\exists A.\,Q^{A})\quad.
\]
-\textbf{(3)} We use the covariant Yoneda identity in the category
-of functors that belong to the $P$-typeclass. As we have found in
-Section~\ref{subsec:Imposing-laws-of-P-typeclasses-via-monad-algebras},
-all those functors are $E$-monad algebras, which form a category.
-The $P$-typeclass morphisms are in one-to-one correspondence with
-the $E$-monad algebra morphisms. Therefore, we may write the covariant
-Yoneda identity for that category as:
-\[
-\forall(F\in P\text{-typeclass}).\,(\forall X.\,Q^{X}\overset{P}{\rightarrow}F^{X})\rightarrow S^{F}\cong S^{Q}\quad,
-\]
-where $Q$ is any fixed functor from the $P$-typeclass, $S^{F}$
-is any type expression that is covariant in $F$, and the naturality
-law with respect to $F$ is assumed to hold. We will use this Yoneda
-identity with $Q=E^{R}$, and set $S^{F}$ to just $F^{C}$ (the application
-of $F$ to the fixed type $C$). Then we get:
-\[
-\forall(F\in P\text{-typeclass}).\,(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\cong(E^{R})^{C}\quad.
-\]
-The last type is the right-hand side of Eq.~(\ref{eq:jaskelioff-o-connor-theorem}).
-So, Eq.~(\ref{eq:jaskelioff-o-connor-theorem}) holds.
+\textbf{(c)} Show that following type identities do \emph{not} hold
+in general:
+\begin{align*}
+ & \exists A.\,P^{A}\times Q^{A}\not\cong(\exists A.\,P^{A})\times(\exists A.\,Q^{A})\quad,\\
+ & R\rightarrow(\exists A.\,P^{A})\not\cong\exists A.\,R\rightarrow P^{A}\quad.
+\end{align*}
+(Similar identities do hold for the universal quantifiers; see Statement~\ref{subsec:Statement-general-identities-forall}.)
-Let us now derive the code that implements the type equivalence~(\ref{eq:jaskelioff-o-connor-theorem})
-in the direction of right-to-left. Suppose we are given a value $q$
-of the type in the right-hand side of Eq.~(\ref{eq:jaskelioff-o-connor-theorem}):
-\[
-q:(E^{R})^{C}\quad.
-\]
-We need to retrace step \textbf{(3)} above and convert this $q$ to
-a function $f$ of type:
-\[
-f:\forall(F\in P\text{-typeclass}).\,(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\quad.
-\]
-The required function $f$ is defined by:
-\[
-f^{F}\big(k^{:\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X}}\big)\triangleq k^{C}(q)\quad.
-\]
+\subparagraph{Solution}
-Continue by retracing step \textbf{(2)}, converting $f$ to a function
-$g$ of type:
+\textbf{(a)} Suppose we have an isomorphism:
\[
-g:\forall(F\in P\text{-typeclass}).\,(\forall X.\,R^{X}\rightarrow F^{X})\rightarrow F^{C}\quad.
+f^{A}:P^{A}\rightarrow Q^{A}\quad,\quad\quad g^{A}:Q^{A}\rightarrow P^{A}\quad.
\]
-The function $g$ is defined by:
+The types $\exists A.\,P^{A}$ and $\exists A.\,Q^{A}$ are equivalent
+to some type expressions involving only universal quantifiers and
+the type constructors $P$, $Q$.
+\begin{align*}
+ & \exists A.\,P^{A}\cong\exists A.\,Q^{A}\\
+{\color{greenunder}\text{is the same as}:}\quad & \forall D.\,(\forall A.\,P^{A}\rightarrow D)\rightarrow D\cong\forall D.\,(\forall A.\,Q^{A}\rightarrow D)\rightarrow D\quad.
+\end{align*}
+Then we can apply Statement~\ref{subsec:Statement-isomorphism-under-type-constructor}
+repeatedly to show that those type expressions are isomorphic as types:
+\begin{align*}
+ & \forall A.\,P^{A}\rightarrow D\cong\forall A.\,Q^{A}\rightarrow D\quad,\\
+ & (\forall A.\,P^{A}\rightarrow D)\rightarrow D\cong(\forall A.\,Q^{A}\rightarrow D)\rightarrow D\quad,\\
+ & \forall D.\,(\forall A.\,P^{A}\rightarrow D)\rightarrow D\cong\forall D.\,(\forall A.\,Q^{A}\rightarrow D)\rightarrow D\quad.
+\end{align*}
+
+\textbf{(b)} Use Eq.~(\ref{eq:existential-via-universal-Yoneda})
+and write:
+\begin{align*}
+ & \exists A.\,P^{A}+Q^{A}=\forall B.\,(\forall A.\,\gunderline{P^{A}+Q^{A}\rightarrow B})\rightarrow B\\
+ & =\forall B.\,(\forall A.\,(P^{A}\rightarrow B)\times(Q^{A}\rightarrow B))\rightarrow B\\
+ & =\forall B.\,(\gunderline{\forall A.\,P^{A}\rightarrow B})\times(\gunderline{\forall A.\,Q^{A}\rightarrow B})\rightarrow B\\
+{\color{greenunder}\text{use Eq.\,(\ref{eq:existential-via-universal})}:}\quad & =\forall B.\,(\gunderline{(\exists A.\,P^{A})\rightarrow B)\times((\exists A.\,Q^{A})\rightarrow B})\rightarrow B\\
+ & =\forall B.\,\big((\exists A.\,P^{A})+(\exists A.\,Q^{A})\,\gunderline{\rightarrow B\big)\rightarrow B}\\
+{\color{greenunder}\text{Yoneda identity}:}\quad & =(\exists A.\,P^{A})+(\exists A.\,Q^{A})\quad.
+\end{align*}
+
+\textbf{(c)} The first counter-example is found via the co-Yoneda
+identity itself:
\[
-g^{F}\big(k^{:\forall X.\,R^{X}\rightarrow F^{X}}\big)\triangleq f^{F}\big(\forall Y.\,r^{:(E^{R})^{Y}}\rightarrow\text{run}_{E}^{R,Y}(k)(r)\big)\quad,
+\exists A.\,(A\rightarrow R)\times F^{A}\cong F^{R}\quad.
\]
-where the universal runner ($\text{run}_{E}^{T,Y}$) has type:
+Splitting the left-hand side into a product of two existential types,
+we get:
\[
-\text{run}_{E}^{T,Y}:(\forall X.\,T^{X}\rightarrow F^{X})\rightarrow(E^{T})^{Y}\rightarrow F^{Y}\quad.
+(\exists A.\,(A\rightarrow R))\times(\exists A.\,F^{A})\cong\bbnum 1\times F^{\bbnum 1}\cong F^{\bbnum 1}\quad.
\]
+But the last type is not equivalent to $F^{R}$.
-It remains to retrace step \textbf{(1)} and define a function $h$
-of type:
+The second counter-example is with the following type:
\[
-h:\forall(F\in P\text{-typeclass}).\,(A\rightarrow F^{B})\rightarrow F^{C}\quad.
+P^{A}\triangleq(A\rightarrow Q)\times A\quad.
\]
-We implement $h$ via this code:
+Here $Q$ is a fixed type. By the co-Yoneda identity, we have $\exists A.\,P^{A}\cong Q$
+and so $R\rightarrow(\exists A.\,P^{A})\cong R\rightarrow Q$. Now
+let us simplify the other side:
+\begin{align*}
+ & \exists A.\,R\rightarrow P^{A}=\exists A.\,R\rightarrow(A\rightarrow Q)\times A\\
+ & \quad\cong\exists A.\,(R\rightarrow A\rightarrow Q)\times(R\rightarrow A)\\
+{\color{greenunder}\text{co-Yoneda identity}:}\quad & \quad\cong R\rightarrow R\rightarrow Q\quad.
+\end{align*}
+The last type is not equivalent to $R\rightarrow Q$. $\square$
+
+\subsubsection{Statement \label{subsec:Statement-commute-existential}\ref{subsec:Statement-commute-existential}
+(co-Fubini theorem)}
+
+For any type constructor $P$ with two parameters (not necessarily
+covariant or contravariant):
\[
-h^{F}(k^{:A\rightarrow F^{B}})\triangleq g^{F}\big(\forall X.\,a^{:A}\times t^{:B\rightarrow X}\rightarrow k(a)\triangleright t^{\uparrow F}\big)\quad.
+\exists A.\,\exists B.\,P^{A,B}\cong\exists B.\,\exists A.\,P^{A,B}\quad.
\]
-This completes the code that transforms $q$ into $h$. $\square$
-We will now apply the Jaskelioff-O\textsf{'}Connor theorem to prove some useful
-type equivalences.
-
-\subsubsection{Statement \label{subsec:Statement-identity-monad-morphism}\ref{subsec:Statement-identity-monad-morphism}}
-Denote by $F\xrightarrow{\text{Monad}}G$ (more verbosely, $\forall X.\,F^{X}\xrightarrow{\text{Monad}}G^{X}$)
-the type of monad morphisms between monads $F$ and $G$. Those are
-natural transformations of type $\forall X.\,F^{X}\rightarrow G^{X}$
-that additionally satisfy the laws of monad morphisms. Denote by $\text{Id}$
-the identity monad ($\text{Id}^{A}\triangleq A$).
+\subparagraph{Proof}
-\textbf{(a)} The standard monad method $\text{pu}_{M}:\forall A.\,A\rightarrow M^{A}$
-is the only monad morphism of type $\text{Id}\xrightarrow{\text{Monad}}M$
-that works in the same way for all monads $M$.\footnote{See \texttt{\href{https://cstheory.stackexchange.com/questions/53389/}{https://cstheory.stackexchange.com/questions/53389/}}}
-We can express this as a type equivalence:
+We rewrite $\exists A.\,\exists B.\,P^{A,B}$ via universal quantifiers:
+\begin{align*}
+ & \gunderline{\exists A.}\,\exists B.\,P^{A,B}\\
+{\color{greenunder}\text{use Eq.\,(\ref{eq:existential-via-universal-Yoneda})}:}\quad & \cong\forall D.\,\big(\forall A.\,\gunderline{(\exists B.\,P^{A,B})\rightarrow D})\rightarrow D\\
+{\color{greenunder}\text{use Eq.\,(\ref{eq:existential-via-universal})}:}\quad & \cong\forall D.\,\big(\forall A.\,\forall B.\,P^{A,B}\rightarrow D)\rightarrow D\quad.
+\end{align*}
+If we rewrite $\exists B.\,\exists A.\,P^{A,B}$ similarly, we will
+get:
\[
-\forall M^{:\text{Monad}}.\,\text{Id}\xrightarrow{\text{Monad}}M\cong\bbnum 1\quad.
+\exists B.\,\exists A.\,P^{A,B}\cong\forall D.\,\big(\forall B.\,\forall A.\,P^{A,B}\rightarrow D)\rightarrow D\quad.
\]
+Statement~\ref{subsec:Statement-Fubini-theorem} gives $\forall A.\,\forall B.\,P^{A,B}\cong\forall B.\,\forall A.\,P^{A,B}$,
+completing the proof. $\square$
-\textbf{(b)} The identity function of type $\forall X.\,M^{X}\rightarrow M^{X}$
-is the only monad morphism of type $M\xrightarrow{\text{Monad}}M$
-that works in the same way for all monads $M$.\footnote{See \texttt{\href{https://stackoverflow.com/questions/61444425/}{https://stackoverflow.com/questions/61444425/}}}
-We can express this as a type equivalence:
+Now we will prove some more technical properties of existential types.
+
+In the next two statements, we work with a fixed type constructor
+$P$, which is not assumed to be covariant or contravariant. For brevity,
+we denote:
\[
-\forall M^{:\text{Monad}}.\,M\xrightarrow{\text{Monad}}M\cong\bbnum 1\quad.
+E\triangleq\forall B.\,(\forall A.\,P^{A}\rightarrow B)\rightarrow B\quad.
\]
-\subparagraph{Proof}
+\subsubsection{Statement \label{subsec:Statement-identity-law-of-pack}\ref{subsec:Statement-identity-law-of-pack}}
-The \lstinline!Monad! typeclass has methods in the form of a $P$-typeclass
-for functors $K$ if we define $P$ by $(P^{K})^{A}\triangleq A+K^{K^{A}}$.
-Then the methods of the \lstinline!Monad! typeclass are represented
-by a single value of type:
-\[
-\forall A.\,(P^{K})^{A}\rightarrow K^{A}=\forall A.\,A+K^{K^{A}}\rightarrow K^{A}\cong(\forall A.\,A\rightarrow K^{A})\times(\forall A.\,K^{K^{A}}\rightarrow K^{A})\quad.
-\]
-This is a tuple type describing the type signatures of $K$\textsf{'}s \lstinline!pure!
-and \lstinline!flatten! methods when $K$ is a monad. So, the Jaskelioff-O\textsf{'}Connor
-theorem applies to the \lstinline!Monad! typeclass. The free monad
-constructor ($E$) is defined recursively as $(E^{F})^{A}\triangleq A+F^{(E^{F})^{A}}$,
-making $E^{F}$ a monad when $F$ is any functor. The free monad\textsf{'}s
-universal runner is defined by:
+Values of type $E$ are constructed via the standard function \lstinline!pack!
+that has the following type signature:
\begin{align*}
- & \text{run}_{E}^{F,A}:(\forall X.\,F^{X}\rightarrow M^{X})\rightarrow(E^{F})^{A}\rightarrow M^{A}\quad,\\
- & \text{run}_{E}^{F,A}\big(k^{:\forall X.\,F^{X}\rightarrow M^{X}}\big)\triangleq\,\begin{array}{|c||c|}
- & M^{A}\\
-\hline A & \text{pu}_{M}\\
-F^{(E^{F})^{A}} & k^{(E^{F})^{A}}\bef\text{flm}_{M}\big(\overline{\text{run}}_{E}^{F,A}(k)\big)
-\end{array}\quad.
+ & \text{pack}:\forall T.\,P^{T}\rightarrow E\quad,\\
+{\color{greenunder}\text{or equivalently}:}\quad & \text{pack}:\forall T.\,P^{T}\rightarrow\forall B.\,(\forall A.\,P^{A}\rightarrow B)\rightarrow B\quad,\\
+ & \text{pack}^{T}(p^{:P^{T}})\triangleq\forall B.\,\big(k^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow k^{T}(p)\quad.
\end{align*}
+Then the \textbf{identity law} of\index{identity laws!of pack@of \lstinline!pack!}
+\lstinline!pack! holds: for any value $e:E$,
+\begin{equation}
+e^{E}(\text{pack})=e\quad.\label{eq:identity-law-of-pack}
+\end{equation}
+It is assumed that all values $e^{:E}$ obey their naturality law:
+\begin{equation}
+\text{for all }f^{:B\rightarrow C},k^{:\forall A.\,P^{A}\rightarrow B}:\quad f(e^{B}(k))=e^{C}(\forall A.\,k^{A}\bef f)\quad.\label{eq:naturality-law-of-e-derivation1}
+\end{equation}
-\textbf{(a)} Monad morphisms are natural transformations that satisfy
-additional laws. We first consider the given type without restricting
-the functions of type $A\rightarrow M^{A}$ to monad morphisms but
-still assuming that they are natural transformations:
+
+\subparagraph{Proof\protect\footnote{The author thanks \index{Dan Doel}Dan Doel for assistance with the
+proof of this statement. See the discussion at \texttt{\protect\href{https://cstheory.stackexchange.com/questions/54124}{https://cstheory.stackexchange.com/questions/54124}}}}
+
+Both sides of Eq.~(\ref{eq:identity-law-of-pack}) have type $E$.
+Since $E$ is a type of functions with a type parameter, the two sides
+can be applied to an arbitrary type $U$ and an arbitrary value $u:\forall A.\,P^{A}\rightarrow U$
+to get two values of type $U$:
+\begin{align*}
+{\color{greenunder}\text{both sides of}:}\quad & e^{E}(\text{pack})\overset{?}{=}e\\
+{\color{greenunder}\text{can be applied to }U\text{ and }u\text{ and yield}:}\quad & \big(e^{E}(\text{pack})\big)^{U}(u)\overset{?}{=}e^{U}(u)\quad.
+\end{align*}
+
+So, let us prove that for all types $U$ and all values $u:\forall A.\,P^{A}\rightarrow U$,
+\begin{equation}
+\big(e^{E}(\text{pack})\big)^{U}(u)\overset{?}{=}e^{U}(u)\quad.\label{eq:identity-law-of-pack-derivation1}
+\end{equation}
+To prove the last equation, we will rewrite it in the form of the
+naturality law~(\ref{eq:naturality-law-of-e-derivation1}) by finding
+suitable parameters $B$, $C$, $f$, and $k$. Once we manage to
+do that, the proof of Eq.~(\ref{eq:identity-law-of-pack}) will be
+completed.
+
+The left-hand side of Eq.~(\ref{eq:identity-law-of-pack-derivation1})
+will match the left-hand side of Eq.~(\ref{eq:naturality-law-of-e-derivation1})
+if we assign $B=E$, $k=\text{pack}$, and $f(e)\triangleq e^{U}(u)$.
+The type of $f$ must be $B\rightarrow C$; since $f(e)$ has type
+$U$, we need to set $C=U$. With these assignments, the right-hand
+side of Eq.~(\ref{eq:naturality-law-of-e-derivation1}) becomes:
\[
-\forall M^{:\text{Monad}}.\,\forall A.\,A\rightarrow M^{A}\quad.
+e^{C}(k\bef f)=e^{U}(\forall A.\,\text{pack}^{A}\bef f)\quad.
\]
-By the Yoneda identity, we get the type equivalence:
+This will be equal to the right-hand side $e^{U}(u)$ of Eq.~(\ref{eq:identity-law-of-pack-derivation1})
+if we show that:
\[
-\forall A.\,A\rightarrow M^{A}\cong M^{\bbnum 1}\quad.
+\forall A.\,\text{pack}^{A}\bef f\overset{?}{=}u\quad.
\]
-So, we have reduced the type to $\forall M^{:\text{Monad}}.\,M^{\bbnum 1}$.
-This type will be in the form suitable for the Jaskelioff-O\textsf{'}Connor
-theorem~(\ref{eq:jaskelioff-o-connor-theorem}) if we set $F=M$,
-$A=\bbnum 0$, $C=\bbnum 1$; the parameter $B$ remains unused since
-$A\rightarrow M^{B}=\bbnum 0\rightarrow M^{B}\cong\bbnum 1$. Then
-Eq.~(\ref{eq:jaskelioff-o-connor-theorem}) gives:
+Substitute the definitions of \lstinline!pack! and $f$, renaming
+$A$ to $T$:
\[
-\forall M^{:\text{Monad}}.\,M^{\bbnum 1}\cong\forall M^{:\text{Monad}}.\,(\bbnum 0\rightarrow M^{B})\rightarrow M^{\bbnum 1}\cong(E^{R})^{\bbnum 1}\quad,
+\forall T.\,\text{pack}^{T}\bef f=\forall T.\,p^{:P^{T}}\rightarrow f\big(\forall B.\,\big(q^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow q^{T}(p)\big)\quad.
\]
-where we must define $R^{X}=A\times(B\rightarrow X)$. However, setting
-$A=\bbnum 0$ gives also $R=\bbnum 0$. Then the free monad $E^{R}$
-is the identity functor:
+The function $f$ substitutes $B=U$ and $q=u$ into its function
+parameter:
\[
-(E^{R})^{C}=C+R^{(E^{R})^{C}}=C+\bbnum 0\cong C\quad.
+f\big(\forall B.\,\big(q^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow q^{T}(p)\big)=\big(\forall B.\,\big(q^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow q^{T}(p)\big)^{U}(u)=u^{T}(p)\quad.
\]
-Finally, we obtain $(E^{R})^{\bbnum 1}=\bbnum 1$, and so:
+So, we find:
\[
-\forall M^{:\text{Monad}}.\,\forall A.\,A\rightarrow M^{A}\cong\bbnum 1\quad.
+\forall T.\,\text{pack}^{T}\bef f=\forall T.\,p^{:P^{T}}\rightarrow u^{T}(p)=\forall T.\,u^{T}=u\quad.
\]
+This completes the proof. $\square$
-We conclude that \emph{without} restricting to monad morphisms there
-is only a single function of the given type. It remains to derive
-the code for that function and to verify that it is indeed a monad
-morphism.
+Finally, here is the key property required for proving the equivalence
+of two formulations of existential types, Eq.~(\ref{eq:existential-via-universal})
+and Eq.~(\ref{eq:existential-via-universal-Yoneda}).
-We begin with a unit value (that we denote by $1$) viewed as a value
-of type $(E^{R})^{C}$ in the right-hand side of Eq.~(\ref{eq:jaskelioff-o-connor-theorem}).
-We follow the proof of Statement~\ref{subsec:Statement-Jaskelioff-OConnor}.
-The first step is to convert the value of type $(E^{R})^{C}$ into
-a function $f$ of type:
-\[
-f:\forall M^{:\text{Monad}}.\,\big(\forall X.\,(E^{R})^{X}\xrightarrow{\text{Monad}}M^{X}\big)\rightarrow M^{C}\quad.
-\]
-In our case, this function is simplified to:
+\subsubsection{Statement \label{subsec:Statement-function-extension-rule}\ref{subsec:Statement-function-extension-rule}}
+
+The following type isomorphism holds:
\begin{align*}
- & f:\forall M^{:\text{Monad}}.\,\big(\forall X.\,\text{Id}^{X}\xrightarrow{\text{Monad}}M^{X}\big)\rightarrow M^{\bbnum 1}\quad,\\
- & f^{M}\big(k^{:\forall X.\,\text{Id}^{X}\xrightarrow{\text{Monad}}M^{X}}\big)\triangleq k^{\bbnum 1}(1)\quad.
+ & E\rightarrow R=(\exists A.\,P^{A})\rightarrow R\cong\forall C.\,P^{C}\rightarrow R\quad,\\
+{\color{greenunder}\text{or equivalently}:}\quad & \big(\forall B.\,(\forall A.\,P^{A}\rightarrow B)\rightarrow B\big)\rightarrow R\cong\forall C.\,P^{C}\rightarrow R\quad,
\end{align*}
-The next step is to convert $f$ to a function $g$ of type:
-\[
-g:\forall M^{:\text{Monad}}.\,(\forall X.\,R^{X}\rightarrow M^{X})\rightarrow M^{C}\quad.
-\]
-In our case, $R^{X}=\bbnum 0$ and $R^{X}\rightarrow M^{X}\cong\bbnum 1$,
-so this function is simplified to:
+where $R$ is a fixed type. In this isomorphism, it is assumed that
+the type $E$ contains only functions $e^{:E}$ that obey the naturality
+law~(\ref{eq:naturality-law-of-e-derivation1}).
+
+This isomorphism can be also formulated via code like this:
+\begin{equation}
+\text{for all }e^{:E}\text{ and }r^{:E\rightarrow R}:\quad r(e)=e^{R}(\forall C.\,\text{pack}^{C}\bef r)\quad,\label{eq:surjectivity-of-pack}
+\end{equation}
+where the standard function \lstinline!pack! was defined in the proof
+of Statement~\ref{subsec:Statement-identity-law-of-pack}. Any function
+$r$ that consumes values of type $e$ can be expressed via application
+of $r$ to values constructed via \lstinline!pack!.
+
+\subparagraph{Proof}
+
+The isomorphism is shown by defining two functions (\lstinline!inF!
+and \lstinline!outF!):
\begin{align*}
- & g:\forall M^{:\text{Monad}}.\,\bbnum 1\rightarrow M^{\bbnum 1}\quad,\\
- & g^{M}(k^{:\bbnum 1})\triangleq f^{M}\big(\forall Y.\,r^{:(E^{R})^{Y}}\rightarrow\text{run}_{E}^{R,Y}(k)(r)\big)\\
- & \quad=f^{M}(\forall Y.\,r^{:Y}\rightarrow\text{pu}_{M}^{Y}(r))=\text{pu}_{M}^{\bbnum 1}(1)\quad.
+ & \text{inF}:(\forall C.\,P^{C}\rightarrow R)\rightarrow E\rightarrow R\quad,\\
+ & \text{inF}\triangleq k^{:\forall C.\,P^{C}\rightarrow R}\rightarrow e^{:E}\rightarrow e^{R}(k)\quad,\\
+ & \text{outF}:(E\rightarrow R)\rightarrow\forall C.\,P^{C}\rightarrow R\quad,\\
+ & \text{outF}\triangleq r^{:E\rightarrow R}\rightarrow\forall C.\,p^{:P^{C}}\rightarrow r(\text{pack}^{C}(p))=r^{:E\rightarrow R}\rightarrow\forall C.\,\text{pack}^{C}\bef r\quad,
\end{align*}
-Finally, we convert $g$ to a function $h$ of type:
+and by proving that those functions are inverses of each other.
+
+Without the type annotations, the code of \lstinline!inF! and \lstinline!outF!
+is:
+\[
+\text{inF}=k\rightarrow q\rightarrow q(k)\quad,\quad\quad\text{outF}=r\rightarrow p\rightarrow r(k\rightarrow k(p))\quad.
+\]
+Now it is quick to prove one direction of isomorphism ($\text{inF}\bef\text{outF}\overset{?}{=}\text{id}$):
\begin{align*}
- & h:\forall M^{:\text{Monad}}.\,(A\rightarrow M^{B})\rightarrow M^{C}\\
- & =\forall M^{:\text{Monad}}.\,(\bbnum 0\rightarrow M^{B})\rightarrow M^{\bbnum 1}\quad.\\
- & \cong\forall M^{:\text{Monad}}.\,\bbnum 1\rightarrow M^{\bbnum 1}\cong\forall M^{:\text{Monad}}.\,M^{\bbnum 1}\quad.
+{\color{greenunder}\text{expect to equal }\text{id}:}\quad & \text{inF}\bef\text{outF}=k\rightarrow\text{outF}\,(q\rightarrow q(k))\\
+ & =k\rightarrow p\rightarrow(q\rightarrow q(k))(k\rightarrow k(p))\\
+ & =k\rightarrow\gunderline{p\rightarrow k(p)}=k\rightarrow k=\text{id}\quad.
\end{align*}
- There exists only one value of type $\forall M^{:\text{Monad}}.\,M^{\bbnum 1}$,
-and that value is $\text{pu}_{M}(1)$. Converting that to the type
-signature $\forall A.\:A\rightarrow M^{A}$, we recover just the standard
-monad method $\text{pu}_{M}$. We know that $\text{pu}_{M}$ gives
-a monad morphism between the identity monad and $M$ (see Statement~\ref{subsec:Statement-pure-M-is-monad-morphism}).
-So, we have proved that there exists a unique monad morphism of type
-$\forall M^{:\text{Monad}}.\,\text{Id}\xrightarrow{\text{Monad}}M$.
-\textbf{(b)} Again, we first consider the given type without restricting
-the functions of type $M^{X}\rightarrow M^{X}$ to monad morphisms
-(but still assuming that they are natural transformations):
+The other direction ($\text{outF}\bef\text{inF}\overset{?}{=}\text{id}$)
+requires more work. The argument of the function $\text{outF}\bef\text{inF}$
+has type $E\rightarrow R$, and we need to show that for any function
+$r^{:E\rightarrow R}$ the following equation holds:
\[
-\forall M^{:\text{Monad}}.\,\forall X.\,M^{X}\rightarrow M^{X}\quad.
+\text{inF}\,(\text{outF}\,(r))\overset{?}{=}r\quad,\quad\text{or equivalently}:\quad r\triangleright\text{outF}\triangleright\text{inF}\overset{?}{=}r\quad.
\]
-This type will be in the form suitable for the Jaskelioff-O\textsf{'}Connor
-theorem~(\ref{eq:jaskelioff-o-connor-theorem}) if we set $F=M$,
-$A=\bbnum 1$, and $B=C=X$. The functor $R$ is then defined by:
+The last equation is between functions of type $E\rightarrow R$;
+we may apply both sides to an arbitrary value $e^{:E}$ and require
+that the results (of type $R$) should be equal:
\[
-R^{T}\triangleq A\times(B\rightarrow T)\cong X\rightarrow T\quad,
+\big(r\triangleright\text{outF}\triangleright\text{inF}\big)(e)\overset{?}{=}r(e)\quad.
\]
-and the functor $E^{R}$ (the free monad on $R$) is defined recursively
-by:
+We begin by subtituting the definitions of \lstinline!inF! and \lstinline!outF!:
+\begin{align*}
+{\color{greenunder}\text{expect to equal }r(e):}\quad & e\triangleright\big(r\triangleright\text{outF}\triangleright\text{inF}\big)=e\triangleright\big((\forall A.\,p^{:P^{A}}\rightarrow r(\text{pack}^{A}(p)))\triangleright\text{inF}\big)\\
+ & =e^{R}\big(\forall A.\,p^{:P^{A}}\rightarrow r(\text{pack}^{A}(p))\big)=e^{R}(\forall A.\,\text{pack}^{A}\bef r)\quad.
+\end{align*}
+Since $e$ is unknown and arbitrary, we can make progress in the proof
+only if we use the naturality law of $e$ as given by Eq.~(\ref{eq:naturality-law-of-e-derivation1}).
+We assign $B=E$, $C=R$, $f=r$, $k=\text{pack}$ in that law and
+obtain:
\[
-(E^{R})^{T}\triangleq T+\big(X\rightarrow(E^{R})^{T}\big)\quad.
+r(e^{E}(\text{pack}))=e^{R}(\forall A.\,\text{pack}^{A}\bef r)\quad.
\]
- With these definitions, Eq.~(\ref{eq:jaskelioff-o-connor-theorem})
-gives:
+By the identity law of pack (Statement~\ref{subsec:Statement-identity-law-of-pack}),
+$e^{E}(\text{pack})=e$. So, we conclude the derivation:
+\begin{align*}
+{\color{greenunder}\text{expect to equal }r(e):}\quad & e\triangleright\big(r\triangleright\text{outF}\triangleright\text{inF}\big)=\gunderline{e^{R}(\forall A.\,\text{pack}^{A}\bef r)}\\
+{\color{greenunder}\text{naturality law of }e:}\quad & =r(\gunderline{e^{E}(\text{pack})})\\
+{\color{greenunder}\text{identity law of }\text{pack}:}\quad & =r(e)\quad.
+\end{align*}
+We have proved the isomorphism and also verified Eq.~(\ref{eq:surjectivity-of-pack}).
+$\square$
+
+\subsection{Greatest fixpoints and the Church-co-Yoneda identity\label{subsec:The-greatest-fixpoints-and-Church-co-Yoneda}}
+
+We have seen that the least fixpoints of functors are expressed via
+the Church encoding type that involves a universally quantified higher-order
+function. An analogous encoding (with an existentially quantified
+type) exists for greatest fixpoints. We will now prove some properties
+of that encoding.\footnote{This section follows the logic given in P.~Wadler\textsf{'}s paper \textsf{``}Recursive
+types for free\textsf{''}, except that we \emph{define} existential types
+by Eq.~(\ref{eq:existential-via-universal-Yoneda}) via the universal
+quantifier.}
+
+We work with a fixed covariant functor $F$ and denote by $C$ the
+following Church-encoded type:
\[
-\forall M^{:\text{Monad}}.\,\forall X.\,M^{X}\rightarrow M^{X}\cong\forall X.\,(E^{R})^{X}\quad.
+C\triangleq\exists A.\,(A\rightarrow F^{A})\times A\quad.
\]
-We are using the functor $(E^{R})^{T}$ with the type parameter $T=X$;
-however, $E^{R}$ also contains $X$ through the definition of $R$.
-To avoid confusion and to simplify notation, let us write $G^{X}$
-instead of $(E^{R})^{X}$, where the type constructor $G$ is defined
-recursively by:
+We will prove that $C$ is the greatest fixpoint of the type equation
+$X\cong F^{X}$; that is, $C=\nu X.\,F^{X}$.
+
+First, we define some auxiliary functions that work with the type
+$C$ and prove their properties.
+
+The function \lstinline!unfold! constructs values of type $C$:
+\begin{align*}
+ & \text{unfold}:\forall T.\,(T\rightarrow F^{T})\times T\rightarrow C\quad,\\
+ & \text{unfold}^{T}(u^{:T\rightarrow F^{T}}\times t^{:T})\triangleq\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R}\rightarrow p^{T}(u\times t)\quad.
+\end{align*}
+Note that \lstinline!unfold! is the same as the function \lstinline!pack!
+from Statement~\ref{subsec:Statement-identity-law-of-pack} if we
+set $E=C$ and $P^{A}\triangleq(A\rightarrow F^{A})\times A$ in the
+definition of \lstinline!pack!.
+
+By parametricity, the function \lstinline!unfold! satisfies a relational
+naturality law: for all types $A$, $B$ and all functions $f^{:A\rightarrow B}$,
+\begin{equation}
+\text{if}\quad u\bef f^{\uparrow F}=f\bef v\quad\text{then}\quad\text{unfold}^{A}(u^{:A\rightarrow F^{A}}\times a^{:A})=\text{unfold}^{B}(v^{:B\rightarrow F^{B}}\times f(a))\quad.\label{eq:relational-naturality-law-of-unfold}
+\end{equation}
+In category theory, the precondition $u\bef f^{\uparrow F}=f\bef v$
+is known as the \textsf{``}$F$-coalgebra morphism law\textsf{''} of $f$. Let us
+give some definitions for reference:
+
+\subsubsection{Definition \label{subsec:Definition-F-coalgebra}\ref{subsec:Definition-F-coalgebra}}
+
+Given a functor $F$, a type $A$ together with a function $u:A\rightarrow F^{A}$
+is called an $F$\textbf{-coalgebra}.\index{$F$-coalgebra} The type
+$A$ is called the \textbf{carrier} of the $F$-coalgebra, and the
+function $u$ is called the \textbf{structure map} of the $F$-coalgebra.
+(Keep in mind that $u$ is not universally quantified over $A$; it
+is a function that only works with a single, specified type $A$.
+For a given type $A$, there could be several different structure
+maps $u$, $u^{\prime}$, and so on; each of them will then define
+a different $F$-coalgebra.)
+
+If $A$ and $B$ are two $F$-coalgebras with structure maps $u:A\rightarrow F^{A}$
+and $v:B\rightarrow F^{B}$ then a function $f:A\rightarrow B$ is
+called an $F$-coalgebra morphism if this law holds:
\[
-G^{X}\triangleq X+(X\rightarrow G^{X})\quad.
+\xymatrix{\xyScaleY{2.3pc}\xyScaleX{2.5pc}A\ar[d]\sb(0.4){u}\ar[r]\sp(0.5){f} & B\ar[d]\sp(0.4){v}\\
+F^{A}\ar[r]\sp(0.5){f^{\uparrow F}} & F^{B}
+}
\]
-(Note that $G$ is neither covariant nor contravariant.) With this
-definition, we obtain:
\[
-\forall M^{:\text{Monad}}.\,\forall X.\,M^{X}\rightarrow M^{X}\cong\forall X.\,G^{X}\quad.
+u\bef f^{\uparrow F}=f\bef v\quad.
\]
+This is the $F$-coalgebra morphism law of $f$. $\square$
-To simpify the type $\forall X.\,G^{X}$, begin by expanding the recursive
-type $G^{X}$:
+It is also helpful to define a function \lstinline!unfoldF! that
+constructs values of type $F^{C}$:
\begin{align*}
- & \forall X.\,G^{X}\cong\forall X.\,X+(X\rightarrow G^{X})\\
-{\color{greenunder}\text{non-disjunctivity}:}\quad & \cong(\forall X.\,X)+(\forall X.\,X\rightarrow G^{X})\\
-{\color{greenunder}\text{use }\forall X.\,X\cong\bbnum 0:}\quad & \cong\forall X.\,X\rightarrow G^{X}\quad.
+ & \text{unfoldF}:\forall T.\,(T\rightarrow F^{T})\times T\rightarrow F^{C}\quad,\\
+ & \text{unfoldF}^{T}(u^{:T\rightarrow F^{T}}\times t^{:T})\triangleq t\triangleright u\triangleright\big(a^{:T}\rightarrow\text{unfold}^{T}(u\times a)\big)^{\uparrow F}\quad.
\end{align*}
-Here we used the non-disjunctivity property from Example~\ref{subsec:Example-undisjunctive-type-constructors}(e).
-Continue expanding the recursive type:
-\begin{align*}
- & \forall X.\,X\rightarrow G^{X}\cong\forall X.\,X\rightarrow(X+(X\rightarrow G^{X}))\\
-{\color{greenunder}\text{non-disjunctivity}:}\quad & \cong(\gunderline{\forall X.\,X\rightarrow X})+\big(\forall X.\,X\rightarrow X\rightarrow G^{X}\big)\\
- & \cong\bbnum 1+\forall X.\,X\times X\rightarrow G^{X}\quad.
-\end{align*}
-The relevant non-disjunctivity property was shown in Example~\ref{subsec:Example-undisjunctive-type-constructors}(f).
-Expand further, using the same non-disjunctivity property:
-\begin{align*}
- & \forall X.\,G^{X}\cong\bbnum 1+\forall X.\,X\times X\rightarrow G^{X}\\
- & \cong\bbnum 1+\forall X.\,X\times X\rightarrow(X+(X\rightarrow G^{X}))\\
-{\color{greenunder}\text{non-disjunctivity}:}\quad & \cong\bbnum 1+(\gunderline{\forall X.\,X\times X\rightarrow X})+\big(\forall X.\,X\times X\rightarrow X\rightarrow G^{X}\big)\\
- & \cong\bbnum 1+\bbnum 2+\forall X.\,X\times X\times X\rightarrow G^{X}\quad.
-\end{align*}
-Proceeding similarly, we obtain:
-\[
-\forall X.\,\underbrace{X\times...\times X}_{n\text{ times}}\rightarrow G^{X}\cong\underbrace{\bbnum 1+...+\bbnum 1}_{n\text{ times}}+\forall X.\,\underbrace{X\times...\times X}_{n+1\text{ times}}\rightarrow G^{X}\quad.
-\]
-It follows by induction that $\forall X.\,G^{X}$ is equivalent to
-an \textsf{``}infinite\textsf{''} sum type:
+The isomorphism $C\cong F^{C}$ will be implemented via two functions:
\[
-\forall X.\,G^{X}\cong\bbnum 1+\bbnum 2+\bbnum 3+...
+\text{fix}:F^{C}\rightarrow C\quad,\quad\quad\text{unfix}:C\rightarrow F^{C}\quad,
\]
-Values of that type may be described by pairs $\left(n,k\right)$
-of natural numbers such that $1\le k\le n$. The number $n$ chooses
-the part \textsf{``}$\bbnum n$\textsf{''} within the disjunctive type $\bbnum 1+\bbnum 2+\bbnum 3+...$,
-where we denoted by \textsf{``}$\bbnum n$\textsf{''} the type $\underbrace{\bbnum 1+...+\bbnum 1}_{n\text{ times}}$.
-The number $k$ chooses a specific unit value within $\underbrace{\bbnum 1+...+\bbnum 1}_{n\text{ times}}$.
+which we define via \lstinline!unfold! and \lstinline!unfoldF! like
+this:
+\begin{align*}
+ & \text{unfix}:C\rightarrow F^{C}\quad,\quad\quad\text{unfix}\triangleq c^{:C}\rightarrow c^{F^{C}}(\forall A.\,\text{unfoldF}^{A})=c^{:C}\rightarrow c^{F^{C}}(\text{unfoldF})\quad,\\
+ & \text{fix}:F^{C}\rightarrow C\quad,\quad\quad\text{fix}\triangleq p^{:F^{C}}\rightarrow\text{unfold}^{F^{C}}(\text{unfix}^{\uparrow F}\times p)\quad.
+\end{align*}
+Because of these functions, $C$ is at the same time an $F$-algebra
+and an $F$-coalgebra.
-The next step is to convert values $\left(n,k\right)$ of that type
-into functions of type $M^{X}\rightarrow M^{X}$ that work in the
-same way for all monads $M$ and all types $X$. We have to find out
-whether any of those functions obey the laws of monad morphisms. For
-that, we need to derive the specific code of those functions. We follow
-the steps outlined in the proof of Statement~\ref{subsec:Statement-Jaskelioff-OConnor}.
+\subsubsection{Statement \label{subsec:Statement-coalgebra-morphism-unfold}\ref{subsec:Statement-coalgebra-morphism-unfold}}
-First, we translate pairs $\left(n,k\right)$ into values of type
-$\forall X.\,G^{X}$ that we will denote by $q_{n,k}$. To achieve
-that, we need to retrace the way we expanded the recursive type $G^{X}$.
-As an example, consider the pair $\left(n=2,k=1\right)$. The value
-$n=2$ corresponds to the type $\bbnum 2$, which was obtained from
-$\forall X.\,X\rightarrow X\rightarrow X$ during expansion of $\forall X.\,G^{X}$.
-The type $\forall X.\,X\rightarrow X\rightarrow X$ has only two distinct
-values, which are functions that return the first or the second argument
-of type $X$. The index $k=1$ selects the first of those values,
-which is a function whose code is written as $x_{1}^{:X}\rightarrow x_{2}^{:X}\rightarrow x_{1}$.
+For any $F$-coalgebra $A$ with a structure map $u:A\rightarrow F^{A}$,
+denote by $\psi_{u}^{A}$ the following function of type $A\rightarrow C$:
+\[
+\psi_{u}^{A}:A\rightarrow C\quad,\quad\quad\psi_{u}^{A}\triangleq a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\quad.
+\]
+Then $\psi_{u}^{A}$ is an $F$-coalgebra morphism of type $A\rightarrow C$.
-To simplify notation, let us temporarily fix the type parameter $X$;
-we will restore the quantifier $\forall X$ at the end of the derivation.
+\subparagraph{Proof}
-The type $X\rightarrow X\rightarrow X$ was found during expansion
-of the recursive type $G^{X}$ as:
+Write the $F$-coalgebra morphism law for that function:
\[
-G^{X}=X+(X\rightarrow(X+(X\rightarrow(X+...))))\quad.
+u\bef\big(a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\big)^{\uparrow F}\overset{?}{=}\big(a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\big)\bef v\quad.
\]
-So, the pair $\left(n=2,k=1\right)$ corresponds to the function $q_{2,1}^{X}:G^{X}$
-written as:
-\begin{align*}
- & q_{2,1}^{X}:X+(X\rightarrow(X+(X\rightarrow(X+(X\rightarrow G^{X})))))\quad,\\
- & q_{2,1}^{X}\triangleq\bbnum 0^{:X}+(x_{1}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{2}^{:X}\rightarrow(x_{1}+\bbnum 0^{:X\rightarrow G^{X}}))))\quad.
-\end{align*}
-In a similar way, we define the functions $q_{n,k}$ for any $1\le k\le n$:
+Apply both sides to an arbitrary value $t^{:A}$ and obtain:
\[
-q_{n,k}^{X}\triangleq\bbnum 0^{:X}+(x_{1}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{2}^{:X}\rightarrow...\rightarrow(\bbnum 0^{:X}+(x_{n}^{:X}\rightarrow(x_{k}+\bbnum 0^{:X\rightarrow G^{X}})))...)))\quad.
+t\triangleright u\triangleright(a\rightarrow\text{unfold}^{A}(u\times a))^{\uparrow F}\overset{?}{=}\text{unfix}\,(\text{unfold}^{A}(u\times t))\quad.
\]
-To make this code description rigorous, let us define $u_{i,n,k}$
-and $v_{i,n}$ like this:
+Begin with the right-hand side:
\begin{align*}
- & u_{i,n,k}\triangleq\bbnum 0^{:X}+(x_{i}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{i+1}^{:X}\rightarrow...\rightarrow(x_{n}^{:X}\rightarrow(x_{k}+\bbnum 0^{:X\rightarrow G^{X}}))...))),\\
- & v_{i,n}(x_{0})\triangleq\bbnum 0^{:X}+(x_{i}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{i+1}^{:X}\rightarrow...\rightarrow(x_{n}^{:X}\rightarrow(x_{0}+\bbnum 0^{:X\rightarrow G^{X}}))...))).
-\end{align*}
-These formulas hold for $1\le i\le k\le n$. An inductive definition
-of $q_{n,k}^{X}$, $u_{i,n,k}$, and $v_{i,n}$ is:
-\begin{align*}
- & q_{n,k}^{X}=u_{1,n,k}\quad,\quad\quad u_{i,n,k}:G^{X}\quad,\quad\quad v_{i,n}:X\rightarrow G^{X}\quad,\\
-{\color{greenunder}\text{for }1\le i m.flatMap { x_2 => pure(x_1) } }
-\end{lstlisting}
-This code can be rewritten as a functor block, making its logic more
-visually clear:
-\begin{lstlisting}
-def h_2_1(m: M[X]): M[X] = for {
- x_1 <- m
- x_2 <- m
-} yield x_1
-\end{lstlisting}
-The code runs two effects of \lstinline!m! but returns the first
-value (\lstinline!x_1!), ignoring \lstinline!x_2!.
-Now we can generalize the code pattern from $h_{2,1}$ to $h_{n,k}$
-and write symbolically:
-\begin{lstlisting}
-def h_n_k(m: M[X]): M[X] = for {
- x_1 <- m
- x_2 <- m
- ...
- x_n <- m
-} yield x_k
-\end{lstlisting}
+\subsubsection{Statement \label{subsec:Statement-greatest-fixpoint-church-encoding}\ref{subsec:Statement-greatest-fixpoint-church-encoding}}
-To prove that this is indeed the correct code for $h_{n,k}^{M}(m)$,
-we need to use induction in $n$. We rewrite $q_{n,k}^{X}=u_{1,n,k}$
-and compute $\text{run}_{E}^{R,X}(p)(q_{n,k})=\text{run}_{E}^{R,X}(p)(u_{1,n,k})$.
-Using the code of $\text{run}_{E}$, we obtain the following inductive
-code definitions:
-\begin{align*}
-{\color{greenunder}\text{for }1\le i (A, Int)
-val q: M[M[Unit]] = { s => ( { t => ((), s + 1) }, s) }
-\end{lstlisting}
+\subparagraph{Proof}
+
+Translate the existential quantifier via Eq.~(\ref{eq:existential-via-universal-Yoneda})
+and write $C$ as:
\[
-M^{A}\triangleq\text{Int}\rightarrow A\times\text{Int}\quad,\quad\quad q:M^{M^{\bbnum 1}}\quad,\quad q\triangleq s^{:\text{Int}}\rightarrow(\_^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}})\times s\quad.
+C\triangleq\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R)\rightarrow R\quad.
\]
-For more intuition, let us express \lstinline!q! via the \lstinline!State!
-monad operations \lstinline!get! and \lstinline!set!:
-\begin{lstlisting}
-val get: M[Int] = s => (s, s)
-val set: Int => M[Unit] = x => s => ((), x)
-// Assuming that map and flatMap are defined for M:
-val q: M[M[Unit]] = for {
- s <- get
-} yield set(s + 1)
-\end{lstlisting}
-Now we compute the two sides of the composition law, step by step.
-First, we will use Scala\textsf{'}s functor block syntax. The \lstinline!flatten!
-method can be written as:
-\begin{lstlisting}
-def flatten[A](mm: M[M[A]]): M[A] = for {
- m <- mm
- x <- m
-} yield x
-\end{lstlisting}
-Substituting the value \lstinline!q! defined above, we get:
-\begin{lstlisting}
-val flatten_q: M[Unit] = for { // This is flatten(q).
- m <- for {
- s <- get
- } yield set(s + 1)
- x <- m
-} yield x
-\end{lstlisting}
-Eliminate the nested \lstinline!for! and obtain:
-\begin{lstlisting}
-val flatten_q: M[Unit] = for {
- s <- get
- m = set(s + 1)
- x <- m
-} yield x
-\end{lstlisting}
-Or equivalently (as the returned value is always a unit value):
-\begin{lstlisting}
-val flatten_q: M[Unit] = for {
- s <- get
- _ <- set(s + 1)
-} yield ()
-\end{lstlisting}
-Applying \lstinline!h_n_k! to this value means writing code of the
-form:
-\begin{lstlisting}
-val h_flatten_q: M[Unit] = for {
- x_1 <- flatten_q
- ...
- x_n <- flatten_q
-} yield x_k
-\end{lstlisting}
-The returned value in \lstinline!x_k! is in any case the unit value,
-so let us focus on the state updates. Each \lstinline!flatten_q!
-has the effect of reading the state value \lstinline!s! and storing
-the incremented value \lstinline!s + 1!. The function \lstinline!h_n_k!
-repeats $n$ times the effect of \lstinline!flatten_q!. This increments
-the internal state $n$ times. So, the left-hand side of the law is
-equivalent to:
-\begin{lstlisting}
-val lhs: M[Unit] = for { // This is h_flatten_q === h_n_k(flatten(q)).
- s <- get
- _ <- set(s + n)
-} yield ()
-\end{lstlisting}
-
-Turning now to the right-hand side of the law, we write the first
-sub-expression ($q\triangleright h_{n,k}^{\uparrow M}$, or in Scala,
-\lstinline!q.map(h_n_k)!) as the following Scala code:
-\begin{lstlisting}
-val q_map_h: M[M[Unit]] = for {
- m <- q
-} yield h_n_k(m)
-\end{lstlisting}
-Substituting the code of \lstinline!q! (but not yet expanding \lstinline!h_n_k!),
-we find:
-\begin{lstlisting}
-val q_map_h: M[M[Unit]] = for {
- s <- get
-} yield h_n_k(set(s + 1))
-\end{lstlisting}
-The function call \lstinline!h_n_k(set(s + 1))! repeats $n$ times
-the effect of \lstinline!set(s + 1)!, but \lstinline!s! is a fixed
-value in that scope, so the result is equal to just a single effect:
-\begin{lstlisting}
-val q_map_h: M[M[Unit]] = for {
- s <- get
-} yield set(s + 1)
-\end{lstlisting}
-This is the same value as \lstinline!q! itself.
-
-The next sub-expression is \lstinline!h_n_k(q_map_h)!, which equals
-\lstinline!h_n_k(q)!:
-\begin{lstlisting}
-val h_q_map_h: M[M[Unit]] = for {
- x_1 <- q
- ...
- x_n <- q
-} yield x_k
-\end{lstlisting}
-Substituting the code for \lstinline!q!, we get:
-\begin{lstlisting}
-val h_q_map_h: M[M[Unit]] = for {
- x_1 <- for {
- s <- get
- } yield set(s + 1)
- ...
- x_n <- for {
- s <- get
- } yield set(s + 1)
-} yield x_k
-\end{lstlisting}
-Eliminate the nested \lstinline!for! and obtain:
-\begin{lstlisting}
-val h_q_map_h: M[M[Unit]] = for {
- s <- get
- x_1 = set(s + 1)
- ...
- s <- get
- x_n = set(s + 1)
-} yield x_k
-\end{lstlisting}
-The code runs $n$ times the effect of \lstinline!get! but actually
-never runs the effect of \lstinline!set!; the unevaluated effectful
-value \lstinline!set(s + 1)! is merely assigned to each \lstinline!x_i!
-and then returned. So, the code is equivalent to:
-\begin{lstlisting}
-val h_q_map_h: M[M[Unit]] = for {
- s <- get
-} yield set(s + 1)
-\end{lstlisting}
-This is again just equal to \lstinline!q!.
-
-It remains to apply \lstinline!flatten! to \lstinline!h_q_map_h!,
-which is the same as \lstinline!flatten(q)! and was already computed
-as \lstinline!flatten_q! above:
-\begin{lstlisting}
-val rhs: M[Unit] = for { // This is flatten(h_q_map_h) === flatten(q).
- s <- get
- _ <- set(s + 1)
-} yield ()
-\end{lstlisting}
+We need to verify that:
-The left-hand side and the right-hand side of the law differ only
-in the \lstinline!set! operation (\lstinline!set(s + n)! vs.~\lstinline!set(s + 1)!).
-So, they are equal only when $n=1$ (that is, for \lstinline!h_1_1!).
-It follows that, for all $n\ge2$ and for all $1\le k\le n$, the
-function $h_{n,k}$ of type $M^{X}\rightarrow M^{X}$ violates the
-composition law of monad morphisms when applied to the chosen value
-$q:M^{M^{X}}$.
+\textbf{(1)} For any $c:C$ we have $\text{fix}\,(\text{unfix}\,(c))=c$.
-Let us now summarize this derivation in code notation. The left-hand
-side of the composition law is:
-\begin{align*}
- & \text{ftn}_{M}(q)=s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}}\quad,\\
- & h_{n,k}(\text{ftn}_{M}(q))=s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+n)^{:\text{Int}}\quad.
-\end{align*}
-Here we used the fact that $h_{n,k}(m)$ repeats $n$ times the effect
-of $m$ (and that effect increments the value $s$).
+\textbf{(2)} For any $q:F^{C}$ we have $\text{unfix}\,(\text{fix}\,(q))=q$.
-Turn to the right-hand side of the law and calculate:
+To prove item \textbf{(1)}:
\begin{align*}
- & q\triangleright h_{n,k}^{\uparrow M}=s^{:\text{Int}}\rightarrow(\_^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}})\times s=q\quad,\\
- & h_{n,k}(q\triangleright h_{n,k}^{\uparrow M})=s^{:\text{Int}}\rightarrow(\_^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}})\times s=q\quad,\\
- & \text{ftn}_{M}(q)=s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}}\quad.
+{\color{greenunder}\text{expect to equal }c:}\quad & \gunderline{\text{fix}}\,(\text{unfix}\,(c))\\
+{\color{greenunder}\text{definition of }\text{fix}:}\quad & =\text{unfold}^{F^{C}}(\text{unfix}^{\uparrow F}\times\text{unfix}\,(c))\\
+{\color{greenunder}\text{naturality law of }\text{unfold}:}\quad & =\text{unfold}^{C}(\text{unfix}\times c)\\
+{\color{greenunder}\text{identity law of }\text{unfold}:}\quad & =c\quad.
\end{align*}
-The condition for the two sides of the law to be equal is:
+Here we applied the naturality law~(\ref{eq:relational-naturality-law-of-unfold})
+with $A=C$, $B=F^{C}$, $a=c$, $f=\text{unfix}$, $u=\text{unfix}$,
+and $v=\text{unfix}^{\uparrow F}$. To verify the precondition of
+that law, write:
\[
-s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+n)^{:\text{Int}}\overset{?}{=}s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}}\quad.
+u\bef f^{\uparrow F}\overset{?}{=}f\bef v\quad,\quad\text{or equivalently:}\quad\text{unfix}\bef\text{unfix}^{\uparrow F}\overset{?}{=}\text{unfix}\bef\text{unfix}^{\uparrow F}\quad.
\]
-This holds only if $n=1$.
+This holds trivially.
-It follows that $h_{1,1}$ (which is an identity function of type
-$M^{X}\rightarrow M^{X}$) is the only monad morphism that fits the
-required type. $\square$
+To prove item \textbf{(2)}, write:
+\begin{align*}
+{\color{greenunder}\text{expect to equal }q:}\quad & \text{unfix}\,(\gunderline{\text{fix}\,(q)})\\
+{\color{greenunder}\text{definition of }\text{fix}:}\quad & =\gunderline{\text{unfix}}\,\big(\text{unfold}^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\big)\\
+{\color{greenunder}\text{definition of }\text{unfold}:}\quad & =\text{unfix}\,\big(\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R}\rightarrow p^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\big)\\
+{\color{greenunder}\text{definition of }\text{unfix}:}\quad & =\big(\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R}\rightarrow p^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\big)^{F^{C}}(\text{unfoldF})\\
+{\color{greenunder}\text{apply function}:}\quad & =\text{unfoldF}^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\\
+{\color{greenunder}\text{definition of }\text{unfoldF}:}\quad & =q\triangleright\gunderline{\text{unfix}^{\uparrow F}\bef\big(a^{:F^{C}}\rightarrow\text{unfold}\,(\text{unfix}^{\uparrow F}\times a)\big)^{\uparrow F}}\\
+{\color{greenunder}\text{composition under }^{\uparrow F}:}\quad & =q\triangleright\big(x^{:C}\rightarrow\gunderline{\text{unfold}\,(\text{unfix}^{\uparrow F}\times\text{unfix}\,(x))}\big)^{\uparrow F}\\
+{\color{greenunder}\text{definition of }\text{fix}:}\quad & =q\triangleright\big(x^{:C}\rightarrow\gunderline{\text{fix}\,(\text{unfix}\,(x))}\big)^{\uparrow F}\\
+{\color{greenunder}\text{item \textbf{(1)}}:}\quad & =q\triangleright\gunderline{(x^{:C}\rightarrow x)^{\uparrow F}}=x\triangleright\text{id}=q\quad.
+\end{align*}
+$\square$
-\subsection{Existential type quantifiers. Co-Yoneda identities}
+It follows that $C$ is a fixpoint of the type equation $C\cong F^{C}$.
+To show that $C$ is indeed the \emph{greatest} fixpoint, we need
+to prove that for any other fixpoint $T$ there exists a unique fixpoint-preserving
+morphism $\psi^{T}:T\rightarrow C$. Similarly to what we saw in Statement~\ref{subsec:Statement-fixpoint-preserving-fix},
+it is sufficient to check that $\psi^{T}$ is an $F$-coalgebra morphism.
-The Yoneda identities allow us in many cases to simplify type expressions
-with universal quantifiers. Similar identities hold for existentially
-quantified types.
+\subsubsection{Statement \label{subsec:Statement-greatest-fixpoint-Church-encoding-morphism}\ref{subsec:Statement-greatest-fixpoint-Church-encoding-morphism}}
-For the purposes of this and the following sections, we define the
-existential quantifier via Eq.~(\ref{eq:existential-via-universal-Yoneda}):
+For any $F$-coalgebra $A$ with a structure map $u:A\rightarrow F^{A}$,
+there exists a unique $F$-algebra morphism $\psi_{u}^{A}$ of type
+$A\rightarrow C$. The function $\psi_{u}^{A}$ is known as an \textbf{anamorphism}\index{anamorphism}
+and was defined as in Statement~\ref{subsec:Statement-coalgebra-morphism-unfold}:
\[
-\exists C.\,F^{C}\cong\forall D.\,\big(\forall C.\,(F^{C}\rightarrow D)\big)\rightarrow D\quad.
+\psi_{u}^{A}:A\rightarrow C\quad,\quad\quad\psi_{u}^{A}\triangleq a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\quad.
\]
-Here $F$ is any type constructor (not necessarily covariant or contravariant).
-\subsubsection{Statement \label{subsec:Statement-co-Yoneda-two-identities}\ref{subsec:Statement-co-Yoneda-two-identities}}
-For any functor $F$ and any contrafunctor $H$, the following identities
-hold:
+\subparagraph{Proof}
+
+We know from Statement~\ref{subsec:Statement-coalgebra-morphism-unfold}
+that $\psi_{u}^{A}$ satisfies the law of $F$-coalgebra morphisms.
+Let $f:A\rightarrow C$ be any other $F$-coalgebra morphism; we need
+to prove that $f=\psi_{u}^{A}$.
+
+We know that $f$ satisfies the $F$-coalgebra morphism law:
+\[
+u\bef f^{\uparrow F}=f\bef\text{unfix}\quad.
+\]
+This is the precondition of the relational naturality law~(\ref{eq:relational-naturality-law-of-unfold})
+of \lstinline!unfold! if we set $B=C$ and $v=\text{unfix}$. So,
+the conclusion of that law holds. We use that equation as well as
+Statement~\ref{subsec:Statement-identity-law-of-unfold} and get:
\begin{align*}
-{\color{greenunder}\text{\textbf{(a)} }\text{covariant co-Yoneda identity}:}\quad & \exists A.\,(A\rightarrow R)\times F^{A}\cong F^{R}\quad,\\
-{\color{greenunder}\text{\textbf{(b)} }\text{contravariant co-Yoneda identity}:}\quad & \exists A.\,(R\rightarrow A)\times H^{A}\cong H^{R}\quad.
+{\color{greenunder}\text{for any }a^{:A}:}\quad & \psi_{u}^{A}(a)=\text{unfold}^{A}(u^{:A\rightarrow F^{A}}\times a^{:A})\\
+{\color{greenunder}\text{naturality law of }\text{unfold}:}\quad & =\text{unfold}^{C}(\text{unfix}\times f(a))\\
+{\color{greenunder}\text{identity law of }\text{unfold}:}\quad & =f(a)\quad.
\end{align*}
+It follows that $\psi_{u}^{A}=f$. $\square$
+We conclude this Appendix with the proof of a type identity dual to
+the Church-Yoneda identity\index{Church-co-Yoneda identity} shown
+in Statement~\ref{subsec:Statement-Church-Yoneda-identity}. That
+identity has no accepted name, and this book calls it the \textsf{``}Church-co-Yoneda\textsf{''}
+identity.
-\subparagraph{Proof}
+\subsubsection{Statement \label{subsec:Statement-Church-co-Yoneda}\ref{subsec:Statement-Church-co-Yoneda}}
-We use Eq.~(\ref{eq:existential-via-universal-Yoneda}) to express
-$\exists A$ via $\forall A$.
+For any covariant functors $F$ and $G$:
+\[
+G^{\nu X.\,F^{X}}\cong\exists A.\,(A\rightarrow F^{A})\times G^{A}\quad.
+\]
-\textbf{(a)} We write:
+
+\subparagraph{Proof}
+
+Denote for brevity $C\triangleq\nu X.\,F^{X}$. The existential type
+is rewritten as:
+\[
+\exists A.\,(A\rightarrow F^{A})\times G^{A}=\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R\quad.
+\]
+We will demonstrate the isomorphism if we define functions \lstinline!toG!
+and \lstinline!fromG! that are mutual inverses, with type signatures:
+\[
+\text{toG}:(\exists A.\,(A\rightarrow F^{A})\times G^{A})\rightarrow G^{C}\quad,\quad\quad\text{fromG}:G^{C}\rightarrow\exists A.\,(A\rightarrow F^{A})\times G^{A}\quad.
+\]
+The first type signature can be implemented as:
\begin{align*}
-{\color{greenunder}\text{expect to equal }F^{R}:}\quad & \exists A.\,(A\rightarrow R)\times F^{A}\\
-{\color{greenunder}\text{definition of }\exists\text{ in Eq.~}(\ref{eq:existential-via-universal-Yoneda}):}\quad & \cong\forall B.\,\big(\forall A.\,\gunderline{(A\rightarrow R)\times F^{A}}\rightarrow B\big)\rightarrow B\\
-{\color{greenunder}\text{uncurry arguments}:}\quad & \cong\forall B.\,\big(\gunderline{\forall A.\,(A\rightarrow R)\rightarrow F^{A}\rightarrow B}\big)\rightarrow B\\
-{\color{greenunder}\text{contravariant Yoneda identity}:}\quad & \cong\gunderline{\forall B.\,\big(F^{R}\rightarrow B\big)\rightarrow B}\\
-{\color{greenunder}\text{covariant Yoneda identity}:}\quad & \cong F^{R}\quad.
+ & \text{toG}:\big(\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R\big)\rightarrow G^{C}\quad,\\
+ & \text{toG}\triangleq k^{:\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R}\rightarrow k^{G^{C}}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)\quad,
\end{align*}
+where $\psi_{u}^{A}$ is the anamorphism of type $A\rightarrow C$
+defined in Statement~\ref{subsec:Statement-coalgebra-morphism-unfold}.
-\textbf{(b)} We write:
+The function \lstinline!fromG! is implemented as:
\begin{align*}
-{\color{greenunder}\text{expect to equal }H^{R}:}\quad & \exists A.\,(R\rightarrow A)\times H^{A}\\
-{\color{greenunder}\text{definition of }\exists\text{ in Eq.~}(\ref{eq:existential-via-universal-Yoneda}):}\quad & \cong\forall B.\,\big(\forall A.\,\gunderline{(R\rightarrow A)\times H^{A}}\rightarrow B\big)\rightarrow B\\
-{\color{greenunder}\text{uncurry arguments}:}\quad & \cong\forall B.\,\big(\gunderline{\forall A.\,(R\rightarrow A)\rightarrow H^{A}\rightarrow B}\big)\rightarrow B\\
-{\color{greenunder}\text{covariant Yoneda identity}:}\quad & \cong\gunderline{\forall B.\,\big(H^{R}\rightarrow B\big)\rightarrow B}\\
-{\color{greenunder}\text{covariant Yoneda identity}:}\quad & \cong H^{R}\quad.
+ & \text{fromG}:G^{C}\rightarrow\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R\quad,\\
+ & \text{fromG}\triangleq g^{:G^{C}}\rightarrow\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R}\rightarrow p^{C}(\text{unfix}\times g)\quad.
\end{align*}
-$\square$
-To build up intuition, let us substitute $R=\bbnum 0$ and $R=\bbnum 1$
-into the co-Yoneda identities:
+It remains to prove the two directions of the isomorphism roundtrip:
-\subsubsection{Statement \label{subsec:Statement-co-Yoneda-two-identities-1}\ref{subsec:Statement-co-Yoneda-two-identities-1}}
+\textbf{(1)} For any $g:G^{C}$ we have: $\text{toG}\,(\text{fromG}\,(g))=g$.
-The following type equivalences hold:
+\textbf{(2)} For any $k:\exists A.\,(A\rightarrow F^{A})\times G^{A}$
+we have: $\text{fromG}\,(\text{toG}\,(k))=k$.
+
+To prove item \textbf{(1)}:
\begin{align*}
-{\color{greenunder}\text{\textbf{(a)} for any functor }F:}\quad & \exists A.\,F^{A}\cong F^{\bbnum 1}\quad,\\
-{\color{greenunder}\text{\textbf{(b)} for any contrafunctor }F:}\quad & \exists A.\,H^{A}\cong H^{\bbnum 0}\quad.
+ & \text{toG}\,(\gunderline{\text{fromG}}\,(g))=\gunderline{\text{toG}}\,\big(\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R}\rightarrow p^{C}(\text{unfix}\times g)\big)\\
+ & =\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)^{C}(\text{unfix}\times g)\\
+ & =g\triangleright(\psi_{\text{unfix}}^{C})^{\uparrow F}\quad.
\end{align*}
+We note that $\psi_{\text{unfix}}^{C}$ is the identity function ($\text{id}^{:C\rightarrow C}$)
+because it is the unique $F$-coalgebra morphism of type $C\rightarrow C$
+by Statement~\ref{subsec:Statement-greatest-fixpoint-Church-encoding-morphism}.
+It follows that:
+\[
+\text{toG}\,(\text{fromG}\,(g))=g\triangleright(\psi_{\text{unfix}}^{C})^{\uparrow F}=g\triangleright\text{id}^{\uparrow F}=g\quad.
+\]
-
-\subparagraph{Proof}
-
-For \textbf{(a)}, set $R=\bbnum 1$ in the covariant co-Yoneda identity:
+To prove item \textbf{(2)}, apply both sides to a type $R$ and a
+value $p^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R}$:
\begin{align*}
-{\color{greenunder}\text{left-hand side}:}\quad & \exists A.\,(\gunderline{A\rightarrow\bbnum 1})\times F^{A}\cong\exists A.\,\bbnum 1\times F^{A}\cong\exists A.\,F^{A}\quad,\\
-{\color{greenunder}\text{right-hand side}:}\quad & F^{\bbnum 1}\quad.
+{\color{greenunder}\text{expect to equal }k^{R}(p):}\quad & \big(\text{fromG}\,(\text{toG}\,(k))\big)^{R}(p)=p^{C}(\text{unfix}\times\text{toG}\,(k))\\
+ & =p^{C}\big(\text{unfix}\times k^{G^{C}}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)\big)\quad.
\end{align*}
-
-For \textbf{(b)}, set $R=\bbnum 0$ in the contravariant co-Yoneda
-identity:
+To proceed, we need to use the naturality law of $k$:
+\[
+\text{for all }Q,R,f^{:Q\rightarrow R},q^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow Q}:\quad k^{R}(\forall A.\:q^{A}\bef f)=f(k^{Q}(q))\quad.
+\]
+Setting the following parameters in this law:
+\[
+Q=G^{C}\quad,\quad\quad f=t^{:G^{C}}\rightarrow p^{C}(\text{unfix}\times t)\quad,\quad q=\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\quad,
+\]
+we obtain:
\begin{align*}
-{\color{greenunder}\text{left-hand side}:}\quad & \exists A.\,(\gunderline{\bbnum 0\rightarrow A})\times H^{A}\cong\exists A.\,\bbnum 1\times H^{A}\cong\exists A.\,H^{A}\quad,\\
-{\color{greenunder}\text{right-hand side}:}\quad & H^{\bbnum 0}\quad.
+ & k^{R}(\forall A.\:u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F}))\\
+ & =p^{C}\big(\text{unfix}\times k^{G^{C}}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)\big)\quad.
\end{align*}
- $\square$
-
-With these properties, we get the following examples of type equivalences:
+We expect the left-hand side to equal $k^{R}(p)$, so the remaining
+difference is:
\begin{align*}
- & \exists A.\,A\cong\bbnum 1\quad,\quad\quad\exists A.\,A\rightarrow R\cong\bbnum 1\quad,\quad\quad\exists A.\,A+R\cong\bbnum 1+R\quad,\\
- & \exists A.\,(R\rightarrow A)\times(A\rightarrow S)\cong R\rightarrow S\quad,\quad\quad\exists A.\,(A\rightarrow R)\times A\times A\cong R\times R\quad.
+ & p\overset{?}{=}\forall A.\:u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F})\quad,\\
+{\color{greenunder}\text{or equivalently}:}\quad & p^{A}(u^{:A\rightarrow F^{A}}\times g^{:G^{A}})\overset{?}{=}p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F})\quad.
\end{align*}
-
-
-\paragraph{Remarks}
-
-\textbf{(1)} The Scala type \lstinline!Any! closely corresponds to
-the type $\exists X.\,X$, which is equivalent to \lstinline!Unit!.
-The advantage of using \lstinline!Any! instead of \lstinline!Unit!
-is that \lstinline!Any! is understood by the Scala compiler as a
-supertype of \emph{all} Scala types (while \lstinline!Unit! is not).
-Indeed, for any type $T$ there is an injective function $T\rightarrow\exists X.\,X$,
-which corresponds to a function of type \lstinline!T => Any! in Scala:
-\begin{lstlisting}
-def toAny[T](t: T): Any = t
-\end{lstlisting}
- This is just an identity function that relabels the types. So, this
-function establishes the subtyping relation \lstinline!T <: Any!.
-
-\textbf{(2)} The type equivalence $\exists X.\,X\cong\bbnum 1$ may
-appear counterintuitive. The unit type has only one distinct value;
-but there are infinitely many ways of creating a value of type $\exists X.\,X$.
-We may take any value $t:T$ of any type $T$ and \textsf{``}pack\textsf{''} that
-value into a value of type $\exists X.\,X$ by hiding the type $T$,
-similarly to the function \lstinline!toAny!.
-\begin{lstlisting}[mathescape=true]
-sealed trait ExistsX // Implements the type $\color{dkgreen}\exists X.\,X$.
-final case class ExistsX0[X](x: X)
-def hide[T](t: T): ExistsX = ExistsX0[T](t)
-val x1: ExistsX = hide(123)
-val x2: ExistsX = hide(124)
-val x3: ExistsX = hide("abc")
-\end{lstlisting}
-This code may suggest that we are able to create many different values
-of type \lstinline!ExistsX!. How can it be that \lstinline!ExistsX!
-is equivalent to a unit type with a single distinct value? The reason
-is that no fully parametric functions will be able to detect any difference
-between all those values. A fully parametric function may pattern-match
-on \lstinline!ExistsX0(x)! but must treat the type of \lstinline!x!
-as arbitrary and unknown, with no operations available for computing
-anything out of \lstinline!x!. So, there will be no way to determine
-the actual type and value of \lstinline!x! and to make any decisions
-based on them. A computer\textsf{'}s memory will probably store different bit
-patterns when representing \lstinline!hide(123)! and \lstinline!hide(124)!.
-But that difference remains unobservable in fully parametric code.
-$\square$
-
-We may use Eq.~(\ref{eq:existential-via-universal-Yoneda}) to replace
-the existential quantifier by the universal one when proving properties
-of existentially quantified types.
-
-\subsubsection{Example \label{subsec:Example-simple-existential-derivation}\ref{subsec:Example-simple-existential-derivation}\index{examples}}
-
-Show that $\exists A.\,F^{A}\rightarrow A\cong\bbnum 1$ for any type
-constructor $F$.
-
-\subparagraph{Solution}
-
-Use Eq.~(\ref{eq:existential-via-universal-Yoneda}) and write:
+This should hold for all types $A$ and for all $g^{:G^{A}}$, $u^{:A\rightarrow F^{A}}$,
+$p:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R$. We
+may assume that all such $p$ obey their relational naturality law:
\[
-\exists A.\,F^{A}\rightarrow A=\forall B.\,(\forall A.\,(F^{A}\rightarrow A)\rightarrow B)\rightarrow B\quad.
+\forall A,B,f^{:A\rightarrow B}:\quad\text{if}\quad u^{:A\rightarrow F^{A}}\bef f^{\uparrow F}=f\bef v^{:B\rightarrow F^{B}}\quad\text{then}\quad p^{A}(u\times a)=p^{B}(v\times a\triangleright f^{\uparrow F})\quad.
\]
-Statement~\ref{subsec:Statement-application-full-relation} with
-$P^{A}\triangleq F^{A}\rightarrow A$ and $K\triangleq B$ shows that
-$\forall A.\,(F^{A}\rightarrow A)\rightarrow B\cong B$ as the type
-constructor $F^{A}\rightarrow A$ is \textsf{``}lifting-to-full\textsf{''} by Statement~\ref{subsec:Statement-undisjunctive-type-constructors-structural}(c,
-d). So, we get:
+We set the following parameters in this law,
\[
-\exists A.\,F^{A}\rightarrow A=\forall B.\,B\rightarrow B\cong\bbnum 1\quad.
+B=C\quad,\quad a=g\quad,\quad f=\psi_{u}^{A}\quad,\quad v=\text{unfix}\quad,
\]
+and obtain:
+\[
+p^{A}(u\times g)=p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F})\quad.
+\]
+This will complete the proof of item \textbf{(2)} as long as the precondition
+holds:
+\begin{align*}
+ & u^{:A\rightarrow F^{A}}\bef f^{\uparrow F}\overset{?}{=}f\bef v^{:B\rightarrow F^{B}}\quad,\\
+{\color{greenunder}\text{or equivalently}:}\quad & u\bef(\psi_{u}^{A})^{\uparrow F}\overset{?}{=}\psi_{u}^{A}\bef\text{unfix}\quad.
+\end{align*}
+This holds by Statement~\ref{subsec:Statement-coalgebra-morphism-unfold}:
+it is the $F$-coalgebra morphism law of $\psi_{u}^{A}$. $\square$
+The Church-co-Yoneda identity can be used to prove the Church encoding
+formula for simultaneous greatest fixpoints of several functors, similarly
+to what we did in Section~\ref{subsec:Least-fixpoints-of-mutually-recursive-types}.
+For simplicity, we will now show a proof for just two mutually recursive
+types; the proof can be extended to any number of types.
-\subsubsection{Example \label{subsec:Example-simple-existential-derivation-1-1}\ref{subsec:Example-simple-existential-derivation-1-1}}
-
-Let $P$ and $Q$ be any type constructors.
+We will first prove a property of nested fixpoints.
-\textbf{(a)} If $P^{A}\cong Q^{A}$ for all $A$ then $\exists A.\,P^{A}\cong\exists A.\,Q^{A}$.
+\subsubsection{Statement \label{subsec:Statement-nested-greatest-fixpoints}\ref{subsec:Statement-nested-greatest-fixpoints}}
-\textbf{(b)} For arbitrary $P$ and $Q$:
+For any bifunctor $F$, the following equivalence holds:
\[
-\exists A.\,P^{A}+Q^{A}\cong(\exists A.\,P^{A})+(\exists A.\,Q^{A})\quad.
+\nu A.\,(\nu B.\,F^{A,B})\cong\nu B.\,F^{B,B}\quad.
\]
-\textbf{(c)} Show that following type identities do \emph{not} hold
-in general:
-\begin{align*}
- & \exists A.\,P^{A}\times Q^{A}\not\cong(\exists A.\,P^{A})\times(\exists A.\,Q^{A})\quad,\\
- & R\rightarrow(\exists A.\,P^{A})\not\cong\exists A.\,R\rightarrow P^{A}\quad.
-\end{align*}
-(Similar identities do hold for the universal quantifiers; see Statement~\ref{subsec:Statement-general-identities-forall}.)
-\subparagraph{Solution}
+\subparagraph{Proof}
-\textbf{(a)} Suppose we have an isomorphism:
+Denote $G^{A,C}\triangleq(A\rightarrow C)\times A$ and write the
+Church encoding for the fixpoints:
\[
-f^{A}:P^{A}\rightarrow Q^{A}\quad,\quad\quad g^{A}:Q^{A}\rightarrow P^{A}\quad.
+\nu A.\,(\nu B.\,F^{A,B})=\exists A.\,(A\rightarrow\nu B.\,F^{A,B})\times A=\exists A.\,G^{A,\,\nu B.\,F^{A,B}}\quad.
\]
-The types $\exists A.\,P^{A}$ and $\exists A.\,Q^{A}$ are equivalent
-to some type expressions involving only universal quantifiers and
-the type constructors $P$, $Q$.
+View $A$ as fixed and use the Church-co-Yoneda identity (Statement~\ref{subsec:Statement-Church-co-Yoneda}):
\begin{align*}
- & \exists A.\,P^{A}\cong\exists A.\,Q^{A}\\
-{\color{greenunder}\text{is the same as}:}\quad & \forall D.\,(\forall A.\,P^{A}\rightarrow D)\rightarrow D\cong\forall D.\,(\forall A.\,Q^{A}\rightarrow D)\rightarrow D\quad.
+ & G^{A,\,\nu B.\,F^{A,B}}\cong\exists B.\,(B\rightarrow F^{A,B})\times\gunderline{G^{A,B}}\\
+ & =\exists B.\,(B\rightarrow F^{A,B})\times(A\rightarrow B)\times A\\
+ & =\exists B.\,(A\rightarrow B)\times H^{A,B}\quad,
\end{align*}
-Then we can apply Statement~\ref{subsec:Statement-isomorphism-under-type-constructor}
-repeatedly to show that those type expressions are isomorphic as types:
+where we defined $H$ by:
+\[
+H^{A,B}\triangleq(B\rightarrow F^{A,B})\times A\quad.
+\]
+Now we can simplify the nested fixpoints:
\begin{align*}
- & \forall A.\,P^{A}\rightarrow D\cong\forall A.\,Q^{A}\rightarrow D\quad,\\
- & (\forall A.\,P^{A}\rightarrow D)\rightarrow D\cong(\forall A.\,Q^{A}\rightarrow D)\rightarrow D\quad,\\
- & \forall D.\,(\forall A.\,P^{A}\rightarrow D)\rightarrow D\cong\forall D.\,(\forall A.\,Q^{A}\rightarrow D)\rightarrow D\quad.
+{\color{greenunder}\text{expect }\nu B.\,F^{B,B}:}\quad & \nu A.\,(\nu B.\,F^{A,B})=\gunderline{\exists A.\,\exists B.}\,(A\rightarrow B)\times H^{A,B}\\
+{\color{greenunder}\text{co-Fubini theorem (Statement~\ref{subsec:Statement-commute-existential})}:}\quad & \cong\exists B.\,\exists A.\,(A\rightarrow B)\times H^{A,B}\\
+{\color{greenunder}\text{co-Yoneda identity}:}\quad & \cong\exists B.\,\gunderline{H^{B,B}}=\exists B.\,(B\rightarrow F^{B,B})\times B\\
+{\color{greenunder}\text{Church encoding}:}\quad & \cong\nu B.\,F^{B,B}\quad.
\end{align*}
-\textbf{(b)} Use Eq.~(\ref{eq:existential-via-universal-Yoneda})
-and write:
-\begin{align*}
- & \exists A.\,P^{A}+Q^{A}=\forall B.\,(\forall A.\,\gunderline{P^{A}+Q^{A}\rightarrow B})\rightarrow B\\
- & =\forall B.\,(\forall A.\,(P^{A}\rightarrow B)\times(Q^{A}\rightarrow B))\rightarrow B\\
- & =\forall B.\,(\gunderline{\forall A.\,P^{A}\rightarrow B})\times(\gunderline{\forall A.\,Q^{A}\rightarrow B})\rightarrow B\\
-{\color{greenunder}\text{use Eq.\,(\ref{eq:existential-via-universal})}:}\quad & =\forall B.\,(\gunderline{(\exists A.\,P^{A})\rightarrow B)\times((\exists A.\,Q^{A})\rightarrow B})\rightarrow B\\
- & =\forall B.\,\big((\exists A.\,P^{A})+(\exists A.\,Q^{A})\,\gunderline{\rightarrow B\big)\rightarrow B}\\
-{\color{greenunder}\text{Yoneda identity}:}\quad & =(\exists A.\,P^{A})+(\exists A.\,Q^{A})\quad.
-\end{align*}
-\textbf{(c)} The first counter-example is found via the co-Yoneda
-identity itself:
-\[
-\exists A.\,(A\rightarrow R)\times F^{A}\cong F^{R}\quad.
-\]
-Splitting the left-hand side into a product of two existential types,
-we get:
-\[
-(\exists A.\,(A\rightarrow R))\times(\exists A.\,F^{A})\cong\bbnum 1\times F^{\bbnum 1}\cong F^{\bbnum 1}\quad.
-\]
-But the last type is not equivalent to $F^{R}$.
+\subsubsection{Statement \label{subsec:Statement-mutually-recursive-greatest-fixpoints}\ref{subsec:Statement-mutually-recursive-greatest-fixpoints}}
-The second counter-example is with the following type:
+Given any bifunctors $F$, $G$, define $T$ and $U$ as the simultaneous
+greatest fixpoints of two type equations:
\[
-P^{A}\triangleq(A\rightarrow Q)\times A\quad.
+T=F^{T,U}\quad,\quad\quad U=G^{T,U}\quad.
\]
-Here $Q$ is a fixed type. By the co-Yoneda identity, we have $\exists A.\,P^{A}\cong Q$
-and so $R\rightarrow(\exists A.\,P^{A})\cong R\rightarrow Q$. Now
-let us simplify the other side:
+Then the types $T$ and $U$ can be expressed as:
\begin{align*}
- & \exists A.\,R\rightarrow P^{A}=\exists A.\,R\rightarrow(A\rightarrow Q)\times A\\
- & \quad\cong\exists A.\,(R\rightarrow A\rightarrow Q)\times(R\rightarrow A)\\
-{\color{greenunder}\text{co-Yoneda identity}:}\quad & \quad\cong R\rightarrow R\rightarrow Q\quad.
+ & T\cong\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times A\quad,\\
+ & U\cong\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times B\quad.
\end{align*}
-The last type is not equivalent to $R\rightarrow Q$. $\square$
-
-\subsubsection{Statement \label{subsec:Statement-commute-existential}\ref{subsec:Statement-commute-existential}(co-Fubini
-theorem)}
-
-For any type constructor $P$ with two parameters (not necessarily
-covariant or contravariant):
-\[
-\exists A.\,\exists B.\,P^{A,B}\cong\exists B.\,\exists A.\,P^{A,B}\quad.
-\]
\subparagraph{Proof}
-We rewrite $\exists A.\,\exists B.\,P^{A,B}$ via universal quantifiers:
+If $T$ and $U$ are fixed (and equal to the correct greatest fixpoints)
+then we can write:
+\[
+T=\nu A.\,F^{A,U}\quad,\quad\quad U=\nu B.\,G^{T,B}\quad.
+\]
+Now we can substitute $U$ into the equation for $T$:
+\[
+T=\nu A.\,F^{A,\,\nu B.\,G^{T,B}}\quad.
+\]
+The last line is a fixpoint equation involving only $T$, so we may
+express $T$ as the greatest fixpoint of that equation. Then we get:
\begin{align*}
- & \gunderline{\exists A.}\,\exists B.\,P^{A,B}\\
-{\color{greenunder}\text{use Eq.\,(\ref{eq:existential-via-universal-Yoneda})}:}\quad & \cong\forall D.\,\big(\forall A.\,\gunderline{(\exists B.\,P^{A,B})\rightarrow D})\rightarrow D\\
-{\color{greenunder}\text{use Eq.\,(\ref{eq:existential-via-universal})}:}\quad & \cong\forall D.\,\big(\forall A.\,\forall B.\,P^{A,B}\rightarrow D)\rightarrow D\quad.
+ & T=\nu C.\,\nu A.\,F^{A,\,\nu B.\,G^{C,B}}\\
+{\color{greenunder}\text{use Statement~\ref{subsec:Statement-nested-greatest-fixpoints} and set }A=C:}\quad & \cong\gunderline{\nu A.}\,F^{A,\,\nu B.\,G^{A,B}}\\
+{\color{greenunder}\text{use Church encoding}:}\quad & \cong\exists A.\:(A\rightarrow F^{A,\,\nu B.\,G^{A,B}})\times A\\
+{\color{greenunder}\text{define }N^{A,C}\triangleq(A\rightarrow F^{A,C})\times A:}\quad & =\exists A.\:N^{A,\,\nu B.\,G^{A,B}}\\
+{\color{greenunder}\text{Church-co-Yoneda identity (Statement~\ref{subsec:Statement-Church-co-Yoneda})}:}\quad & \cong\gunderline{\exists A.\,\exists B.}\,(B\rightarrow G^{A,B})\times N^{A,B}\quad.
\end{align*}
-If we rewrite $\exists B.\,\exists A.\,P^{A,B}$ similarly, we will
-get:
+Writing out the definition of $N^{A,B}$, we obtain the claimed Church
+encoding for $T$:
\[
-\exists B.\,\exists A.\,P^{A,B}\cong\forall D.\,\big(\forall B.\,\forall A.\,P^{A,B}\rightarrow D)\rightarrow D\quad.
+T\cong\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times A\quad.
\]
-Statement~\ref{subsec:Statement-Fubini-theorem} gives $\forall A.\,\forall B.\,P^{A,B}\cong\forall B.\,\forall A.\,P^{A,B}$,
-completing the proof. $\square$
+ The formula for $U$ is derived similarly. $\square$
-Now we will prove some more technical properties of existential types.
+\subsection{Summary of type isomorphisms}
-In the next two statements, we work with a fixed type constructor
-$P$, which is not assumed to be covariant or contravariant. For brevity,
-we denote:
-\[
-E\triangleq\forall B.\,(\forall A.\,P^{A}\rightarrow B)\rightarrow B\quad.
-\]
+This Appendix has developed various parametricity techniques to prove
+a number of type isomorphisms. The results are summarized in Tables~\ref{tab:Type-identities-proved-by-Yoneda}\textendash \ref{tab:Type-identities-for-existential-types}.
+\begin{table}[h]
+\begin{centering}
+\begin{tabular}{|c|c|}
+\hline
+\textbf{\footnotesize{}Identity} & \textbf{\footnotesize{}Assumptions}\tabularnewline
+\hline
+\hline
+{\footnotesize{}$\forall A.\,A\rightarrow A\cong\bbnum 1$} & \tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,A\rightarrow F^{A}\cong F^{\bbnum 1}$} & {\footnotesize{}$F$ is any functor}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,A\times A\rightarrow F^{A}\cong F^{\bbnum 2}$} & {\footnotesize{}$F$ is any functor}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,A\cong\bbnum 0$} & \tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,F^{A}\cong F^{\bbnum 0}$} & {\footnotesize{}$F$ is any functor}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,H^{A}\cong H^{\bbnum 1}$} & {\footnotesize{}$H$ is any contrafunctor}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,(A\rightarrow P)\rightarrow A\rightarrow Q\cong P\rightarrow Q$} & {\footnotesize{}$P$, $Q$ are fixed types}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,(P\rightarrow A)\rightarrow Q\rightarrow A\cong Q\rightarrow P$} & {\footnotesize{}$P$, $Q$ are fixed types}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,((A\rightarrow P)\rightarrow Q)\rightarrow(A\rightarrow S)\rightarrow R\cong((S\rightarrow P)\rightarrow Q)\rightarrow R$} & {\footnotesize{}$P$, $Q$, $R$, $S$ are fixed types}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,(P\rightarrow A\times Q)\rightarrow(A+R)\times S\cong$$(P\rightarrow Q)\rightarrow(P+R)\times S$} & {\footnotesize{}$P$, $Q$, $R$, $S$ are fixed types}\tabularnewline
+\hline
+\end{tabular}
+\par\end{centering}
+\caption{Type isomorphisms proved via Yoneda identities.\label{tab:Type-identities-proved-by-Yoneda}}
+\end{table}
-\subsubsection{Statement \label{subsec:Statement-identity-law-of-pack}\ref{subsec:Statement-identity-law-of-pack}}
+\begin{table}
+\begin{centering}
+\begin{tabular}{|c|c|c|}
+\hline
+\textbf{\footnotesize{}Identity} & \textbf{\footnotesize{}Assumptions} & \textbf{\footnotesize{}Source}\tabularnewline
+\hline
+\hline
+{\footnotesize{}$\forall A.\,(F^{A}\rightarrow A)\rightarrow A\cong\mu A.\,F^{A}$} & {\footnotesize{}$F$ is any functor} & {\footnotesize{}Section~\ref{subsec:The-Church-encoding-of-recursive-types}}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,(H^{A}\rightarrow A)\rightarrow A\cong H^{\bbnum 1}$} & {\footnotesize{}$H$ is any contrafunctor} & {\footnotesize{}Statement~\ref{subsec:Example-simplify-quantifier-1-1}}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,(A\rightarrow A)\rightarrow H^{A}\cong H^{\bbnum 1}$} & {\footnotesize{}$H$ is any contrafunctor} & {\footnotesize{}Example~\ref{subsec:Example-strong-dinaturality-show-void}(b)}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,(F^{A}\rightarrow A)\rightarrow G^{A}\cong G^{\mu A.\,F^{A}}$} & {\footnotesize{}$F$, $G$ are any functors} & {\footnotesize{}Statement~\ref{subsec:Statement-Church-Yoneda-identity}}\tabularnewline
+\hline
+{\footnotesize{}$\mu A.\,\mu B.\,F^{A,B}\cong\mu B.\,F^{B,B}$} & {\footnotesize{}$F$ is any bifunctor} & {\footnotesize{}Statement~\ref{subsec:Statement-nested-fixpoints}}\tabularnewline
+\hline
+{\footnotesize{}}%
+\begin{minipage}[c][12mm][t]{0.1mm}%
+%
+\end{minipage}{\footnotesize{}}%
+\begin{minipage}[c]{0.43\columnwidth}%
+\begin{center}
+{\footnotesize{}$\mu A.\,P^{A,\,\mu B.\,Q^{A,B}}\cong$}\\
+{\footnotesize{}$\forall A.\,\forall B.\,(P^{A,B}\rightarrow A)\times(Q^{A,B}\rightarrow B)\rightarrow A$}
+\par\end{center}%
+\end{minipage} & {\footnotesize{}$P$, $Q$ are any bifunctors} & {\footnotesize{}Statement~\ref{subsec:Statement-nested-fixpoint-under-functor}}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,F^{A}\rightarrow P\cong P$} & {\footnotesize{}If $F^{A}\neq\bbnum 0$ for some $A$} & {\footnotesize{}Statement~\ref{subsec:Statement-application-full-relation}(a)}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,((A\rightarrow A)\rightarrow A)\rightarrow A\cong\bbnum 1+\bbnum 2+\bbnum 3+...$} & {\footnotesize{}~} & {\footnotesize{}Statement~\ref{subsec:Statement-advanced-type-equivalence}}\tabularnewline
+\hline
+{\footnotesize{}}%
+\begin{minipage}[c][17mm][t]{0.1mm}%
+%
+\end{minipage}{\footnotesize{}}%
+\begin{minipage}[c]{0.43\columnwidth}%
+\begin{center}
+{\footnotesize{}$\forall A.\,(H^{A}\rightarrow A)\rightarrow F^{A}+G^{A}\cong$}\\
+{\footnotesize{}$(\forall A.\:(H^{A}\rightarrow A)\rightarrow F^{A})\,+$}\\
+{\footnotesize{}$(\forall A.\:(H^{A}\rightarrow A)\rightarrow G^{A})$}
+\par\end{center}%
+\end{minipage} & {\footnotesize{}For any $F$, $G$, $H$} & {\footnotesize{}Example~\ref{subsec:Example-undisjunctive-type-constructors}(c)}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,\forall B.\,F^{A,B}\cong\forall B.\,\forall A.\,F^{A,B}$} & {\footnotesize{}For any $F$} & {\footnotesize{}Statement~\ref{subsec:Statement-Fubini-theorem-1}}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,(F^{A}+G^{A})\cong(\forall A.\,F^{A})+(\forall A.\,G^{A})$} & {\footnotesize{}For any $F$, $G$} & {\footnotesize{}Statement~\ref{subsec:Statement-general-identities-forall}(a)}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,(F^{A}\times G^{A})\cong(\forall A.\,F^{A})\times(\forall A.\,G^{A})$} & {\footnotesize{}For any $F$, $G$} & {\footnotesize{}Statement~\ref{subsec:Statement-general-identities-forall}(b)}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,R\rightarrow F^{A}\cong R\rightarrow(\forall A.\,F^{A})$} & {\footnotesize{}Any $F$, a fixed type $R$} & {\footnotesize{}Statement~\ref{subsec:Statement-general-identities-forall}(c)}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,F^{P^{A}}\cong F^{\forall A.\,P^{A}}$} & {\footnotesize{}$F$ is strictly positive} & {\footnotesize{}Statement~\ref{subsec:Statement-quantifier-across-functor}}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,F^{A}\cong\bbnum 0$ when $F^{\bbnum 0}\cong\bbnum 0$} & {\footnotesize{}$F$ is such that $F^{\bbnum 0}\cong\bbnum 0$} & {\footnotesize{}Statement~\ref{subsec:Statement-Fubini-theorem-1}}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,F^{A\rightarrow A}\cong F^{\bbnum 1}$} & {\footnotesize{}$F$ is strictly positive} & {\footnotesize{}Example~\ref{subsec:Example-simplify-quantifier-A-A}(a)}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,H^{A\rightarrow A}\cong H^{\bbnum 1}$} & {\footnotesize{}$H$ is a contrafunctor} & {\footnotesize{}Example~\ref{subsec:Example-simplify-quantifier-A-A}(b)}\tabularnewline
+\hline
+{\footnotesize{}$\forall A.\,((A\rightarrow P)\rightarrow A\rightarrow A\cong P$} & {\footnotesize{}$P$ is a fixed type} & {\footnotesize{}Exercise~\ref{par:Problem-Peirce-law}}\tabularnewline
+\hline
+\end{tabular}
+\par\end{centering}
+\caption{Type identities proved by other parametricity techniques.\label{tab:Type-identities-proved-by-parametricity}}
+\end{table}
-Values of type $E$ are constructed via the standard function \lstinline!pack!
-that has the following type signature:
-\begin{align*}
- & \text{pack}:\forall T.\,P^{T}\rightarrow E\quad,\\
-{\color{greenunder}\text{or equivalently}:}\quad & \text{pack}:\forall T.\,P^{T}\rightarrow\forall B.\,(\forall A.\,P^{A}\rightarrow B)\rightarrow B\quad,\\
- & \text{pack}^{T}(p^{:P^{T}})\triangleq\forall B.\,\big(k^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow k^{T}(p)\quad.
-\end{align*}
-Then the \textbf{identity law} of\index{identity laws!of pack@of \lstinline!pack!}
-\lstinline!pack! holds: for any value $e:E$,
-\begin{equation}
-e^{E}(\text{pack})=e\quad.\label{eq:identity-law-of-pack}
-\end{equation}
-It is assumed that all values $e^{:E}$ obey their naturality law:
-\begin{equation}
-\text{for all }f^{:B\rightarrow C},k^{:\forall A.\,P^{A}\rightarrow B}:\quad f(e^{B}(k))=e^{C}(\forall A.\,k^{A}\bef f)\quad.\label{eq:naturality-law-of-e-derivation1}
-\end{equation}
+\begin{table}[h]
+\begin{centering}
+\begin{tabular}{|c|c|c|}
+\hline
+\textbf{\footnotesize{}Identity} & \textbf{\footnotesize{}Assumptions} & \textbf{\footnotesize{}Source}\tabularnewline
+\hline
+\hline
+{\footnotesize{}$\exists C.\,F^{C}\cong\forall D.\,\big(\forall C.\,(F^{C}\rightarrow D)\big)\rightarrow D$} & {\footnotesize{}For any $F$} & {\footnotesize{}Equation~(\ref{eq:existential-via-universal-Yoneda})}\tabularnewline
+\hline
+{\footnotesize{}$(\exists C.\,F^{C})\rightarrow R\cong\forall C.\,(F^{C}\rightarrow R)$} & {\footnotesize{}For any $F$, $R$} & {\footnotesize{}Statement~\ref{subsec:Statement-function-extension-rule}}\tabularnewline
+\hline
+{\footnotesize{}$\exists A.\,A\cong\bbnum 1$} & & \tabularnewline
+\hline
+{\footnotesize{}$\exists A.\,F^{A}\cong F^{\bbnum 1}$} & {\footnotesize{}$F$ is any functor} & {\footnotesize{}Statement~\ref{subsec:Statement-co-Yoneda-two-identities-1}(a)}\tabularnewline
+\hline
+{\footnotesize{}$\exists A.\,H^{A}\cong H^{\bbnum 0}$} & {\footnotesize{}$H$ is any contrafunctor} & {\footnotesize{}Statement~\ref{subsec:Statement-co-Yoneda-two-identities-1}(b)}\tabularnewline
+\hline
+{\footnotesize{}$\exists A.\,F^{A}\rightarrow A\cong\bbnum 1$} & {\footnotesize{}For any $F$} & {\footnotesize{}Example~\ref{subsec:Example-simple-existential-derivation}}\tabularnewline
+\hline
+{\footnotesize{}$\exists A.\,(F^{A}+G^{A})\cong(\exists A.\,F^{A})+(\exists A.\,G^{A})$} & {\footnotesize{}For any $F$, $G$} & {\footnotesize{}Example~\ref{subsec:Example-simple-existential-derivation-1-1}(b)}\tabularnewline
+\hline
+{\footnotesize{}$\exists A.\,\exists B.\,F^{A,B}\cong\exists B.\,\exists A.\,F^{A,B}$} & {\footnotesize{}For any $F$} & {\footnotesize{}Statement~\ref{subsec:Statement-commute-existential}}\tabularnewline
+\hline
+{\footnotesize{}$\nu A.\,F^{A}\cong\exists A.\,(A\rightarrow F^{A})\times A$} & {\footnotesize{}$F$ is any functor} & {\footnotesize{}Section~\ref{subsec:The-greatest-fixpoints-and-Church-co-Yoneda}}\tabularnewline
+\hline
+{\footnotesize{}$G^{\nu A.\,F^{A}}\cong\exists A.\,(A\rightarrow F^{A})\times G^{A}$} & {\footnotesize{}$F$, $G$ are any functors} & {\footnotesize{}Statement~\ref{subsec:Statement-Church-co-Yoneda}}\tabularnewline
+\hline
+{\footnotesize{}$\nu A.\,\nu B.\,F^{A,B}\cong\nu B.\,F^{B,B}$} & {\footnotesize{}$F$ is any bifunctor} & {\footnotesize{}Statement~\ref{subsec:Statement-nested-greatest-fixpoints}}\tabularnewline
+\hline
+{\footnotesize{}}%
+\begin{minipage}[c][12mm][t]{0.1mm}%
+%
+\end{minipage}{\footnotesize{}}%
+\begin{minipage}[c]{0.43\columnwidth}%
+\begin{center}
+{\footnotesize{}$\nu A.\,F^{A,\,\nu B.\,G^{A,B}}\cong$}\\
+{\footnotesize{}$\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times A$}
+\par\end{center}%
+\end{minipage} & {\footnotesize{}$F$, $G$ are any bifunctors} & {\footnotesize{}Statement~\ref{subsec:Statement-mutually-recursive-greatest-fixpoints}}\tabularnewline
+\hline
+{\footnotesize{}$G^{\exists C.\,F^{C}}\cong\forall D.\,(\forall C.\,F^{C}\rightarrow D)\rightarrow G^{D}$} & {\footnotesize{}Any $F$, any functor $G$} & {\footnotesize{}Exercise~\ref{par:Exercise-additional-16-3}}\tabularnewline
+\hline
+\end{tabular}
+\par\end{centering}
+\caption{Type isomorphisms for existential types.\label{tab:Type-identities-for-existential-types}}
+\end{table}
-\subparagraph{Proof\protect\footnote{The author thanks \index{Dan Doel}Dan Doel for assistance with the
-proof of this statement. See the discussion at \texttt{\protect\href{https://cstheory.stackexchange.com/questions/54124}{https://cstheory.stackexchange.com/questions/54124}}}}
+\subsection{The Jaskelioff-O\textsf{'}Connor theorem for simple types}
-Both sides of Eq.~(\ref{eq:identity-law-of-pack}) have type $E$.
-Since $E$ is a type of functions with a type parameter, the two sides
-can be applied to an arbitrary type $U$ and an arbitrary value $u:\forall A.\,P^{A}\rightarrow U$
-to get two values of type $U$:
-\begin{align*}
-{\color{greenunder}\text{both sides of}:}\quad & e^{E}(\text{pack})\overset{?}{=}e\\
-{\color{greenunder}\text{can be applied to }U\text{ and }u\text{ and yield}:}\quad & \big(e^{E}(\text{pack})\big)^{U}(u)\overset{?}{=}e^{U}(u)\quad.
-\end{align*}
+The Jaskelioff-O\textsf{'}Connor theorem\footnote{See \texttt{\href{https://arxiv.org/abs/1402.1699}{https://arxiv.org/abs/1402.1699}}}
+is a type equivalence between certain type constructors quantified
+over a typeclass. This section proves a version of that theorem that
+holds for simple types belonging to an $FM$-typeclass. Then the theorem
+gives a general type formula for the free construction of any $FM$-typeclass.
-So, let us prove that for all types $U$ and all values $u:\forall A.\,P^{A}\rightarrow U$,
-\begin{equation}
-\big(e^{E}(\text{pack})\big)^{U}(u)\overset{?}{=}e^{U}(u)\quad.\label{eq:identity-law-of-pack-derivation1}
-\end{equation}
-To prove the last equation, we will rewrite it in the form of the
-naturality law~(\ref{eq:naturality-law-of-e-derivation1}) by finding
-suitable parameters $B$, $C$, $f$, and $k$. Once we manage to
-do that, the proof of Eq.~(\ref{eq:identity-law-of-pack}) will be
-completed.
+\subsubsection{Statement \label{subsec:Statement-JOC-theorem-simple-types}\ref{subsec:Statement-JOC-theorem-simple-types}}
-The left-hand side of Eq.~(\ref{eq:identity-law-of-pack-derivation1})
-will match the left-hand side of Eq.~(\ref{eq:naturality-law-of-e-derivation1})
-if we assign $B=E$, $k=\text{pack}$, and $f(e)\triangleq e^{U}(u)$.
-The type of $f$ must be $B\rightarrow C$; since $f(e)$ has type
-$U$, we need to set $C=U$. With these assignments, the right-hand
-side of Eq.~(\ref{eq:naturality-law-of-e-derivation1}) becomes:
-\[
-e^{C}(k\bef f)=e^{U}(\forall A.\,\text{pack}^{A}\bef f)\quad.
-\]
-This will be equal to the right-hand side $e^{U}(u)$ of Eq.~(\ref{eq:identity-law-of-pack-derivation1})
-if we show that:
-\[
-\forall A.\,\text{pack}^{A}\bef f\overset{?}{=}u\quad.
-\]
-Substitute the definitions of \lstinline!pack! and $f$, renaming
-$A$ to $T$:
+The free $FM$-typeclass instance $E^{T}$ generated by a type $T$
+is equivalent to the type defined by:
+\begin{equation}
+E^{T}\cong\forall(A\in P\text{-typeclass}).\,(T\rightarrow A)\rightarrow A\quad.\label{eq:free-typeclass-via-church-encoding}
+\end{equation}
+Here the quantifier goes only over the types $A$ that belong to the
+$FM$-typeclass. It is also assumed that the type in the right-hand
+side of Eq.~(\ref{eq:free-typeclass-via-church-encoding}) admits
+only functions that satisfy the naturality law with respect to $A$.
+
+\subparagraph{Proof}
+
+One of the defining properties of the free typeclass constructor $E$
+is the one-to-one correspondence between functions of type $T\rightarrow A$
+and $FM$-typeclass morphisms of type $E^{T}\rightarrow A$. Denoting
+by $E^{T}\overset{P}{\rightarrow}A$ the type of those morphisms,
+we have:
\[
-\forall T.\,\text{pack}^{T}\bef f=\forall T.\,p^{:P^{T}}\rightarrow f\big(\forall B.\,\big(q^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow q^{T}(p)\big)\quad.
+\forall(A\in P\text{-typeclass}).\,(T\rightarrow A)\rightarrow A\cong\forall(A\in P\text{-typeclass}).\,(E^{T}\overset{P}{\rightarrow}A)\rightarrow A\quad.
\]
-The function $f$ substitutes $B=U$ and $q=u$ into its function
-parameter:
+
+All types $A$ belonging to the $FM$-typeclass are $E$-monad algebras,
+and those algebras form a category. Now we use the Yoneda identity
+in that category:
\[
-f\big(\forall B.\,\big(q^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow q^{T}(p)\big)=\big(\forall B.\,\big(q^{:\forall A.\,P^{A}\rightarrow B}\big)\rightarrow q^{T}(p)\big)^{U}(u)=u^{T}(p)\quad.
+\forall(A\in P\text{-typeclass}).\,(X\overset{P}{\rightarrow}A)\rightarrow A\cong X\quad,
\]
-So, we find:
+where $X$ is any fixed type that also belongs to the $FM$-typeclass.
+We use this identity with $X=E^{T}$ and obtain:
\[
-\forall T.\,\text{pack}^{T}\bef f=\forall T.\,p^{:P^{T}}\rightarrow u^{T}(p)=\forall T.\,u^{T}=u\quad.
+\forall(A\in P\text{-typeclass}).\,(E^{T}\overset{P}{\rightarrow}A)\rightarrow A\cong E^{T}\quad,
\]
-This completes the proof. $\square$
+as required. $\square$
-Finally, here is the key property required for proving the equivalence
-of two formulations of existential types, Eq.~(\ref{eq:existential-via-universal})
-and Eq.~(\ref{eq:existential-via-universal-Yoneda}).
+\subsection{The Jaskelioff-O\textsf{'}Connor theorem for type constructors\label{subsec:The-Jaskelioff-OConnor-theorem}}
-\subsubsection{Statement \label{subsec:Statement-function-extension-rule}\ref{subsec:Statement-function-extension-rule}}
+The full formulation of the theorem involves functor typeclasses instead
+of typeclasses for simple types. The theorem applies to all $FM$-typeclasses
+for functors. Those typeclasses have method signatures of the form
+$\forall A.\,(P^{F})^{A}\rightarrow F^{A}$, where $P$ is a functor
+on functors (the kind of $P$ is $(*\rightarrow*)\rightarrow*\rightarrow*$)
+and functions of type $(P^{F})^{A}\rightarrow F^{A}$ are restricted
+to natural transformations between functors $P^{F}$ and $F$. Examples
+of well-known $FM$-typeclasses of that form are pointed functors,
+filterable functors, applicative functors, and monads.
-The following type isomorphism holds:
-\begin{align*}
- & E\rightarrow R=(\exists A.\,P^{A})\rightarrow R\cong\forall C.\,P^{C}\rightarrow R\quad,\\
-{\color{greenunder}\text{or equivalently}:}\quad & \big(\forall B.\,(\forall A.\,P^{A}\rightarrow B)\rightarrow B\big)\rightarrow R\cong\forall C.\,P^{C}\rightarrow R\quad,
-\end{align*}
-where $R$ is a fixed type. In this isomorphism, it is assumed that
-the type $E$ contains only functions $e^{:E}$ that obey the naturality
-law~(\ref{eq:naturality-law-of-e-derivation1}).
+\subsubsection{Statement \label{subsec:Statement-Jaskelioff-OConnor}\ref{subsec:Statement-Jaskelioff-OConnor}
+(Jaskelioff-O\textsf{'}Connor)}
-This isomorphism can be also formulated via code like this:
-\begin{equation}
-\text{for all }e^{:E}\text{ and }r^{:E\rightarrow R}:\quad r(e)=e^{R}(\forall C.\,\text{pack}^{C}\bef r)\quad,\label{eq:surjectivity-of-pack}
-\end{equation}
-where the standard function \lstinline!pack! was defined in the proof
-of Statement~\ref{subsec:Statement-identity-law-of-pack}. Any function
-$r$ that consumes values of type $e$ can be expressed via application
-of $r$ to values constructed via \lstinline!pack!.
+Given any fixed $FM$-typeclass for functors, denote by $E$ the constructor
+of free instances of that typeclass: if $T$ is any functor then the
+functor $E^{T}$ is an instance of the $FM$-typeclass satisfying
+the properties of free typeclass constructors. Suppose $A$, $B$,
+$C$ are some fixed types. Then the following type equivalence holds:
+\begin{align}
+ & \forall(F\in P\text{-typeclass}).\,(A\rightarrow F^{B})\rightarrow F^{C}\cong(E^{R})^{C}\quad,\label{eq:jaskelioff-o-connor-theorem}\\
+{\color{greenunder}\text{where }R\text{ is defined by}:}\quad & R^{T}\triangleq A\times(B\rightarrow T)\quad.\nonumber
+\end{align}
+Here, it is assumed that the type $(A\rightarrow F^{B})\rightarrow F^{C}$
+is restricted to functions satisfying the $FM$-typeclass naturality
+law with respect to $F$.
\subparagraph{Proof}
-The isomorphism is shown by defining two functions (\lstinline!inF!
-and \lstinline!outF!):
-\begin{align*}
- & \text{inF}:(\forall C.\,P^{C}\rightarrow R)\rightarrow E\rightarrow R\quad,\\
- & \text{inF}\triangleq k^{:\forall C.\,P^{C}\rightarrow R}\rightarrow e^{:E}\rightarrow e^{R}(k)\quad,\\
- & \text{outF}:(E\rightarrow R)\rightarrow\forall C.\,P^{C}\rightarrow R\quad,\\
- & \text{outF}\triangleq r^{:E\rightarrow R}\rightarrow\forall C.\,p^{:P^{C}}\rightarrow r(\text{pack}^{C}(p))=r^{:E\rightarrow R}\rightarrow\forall C.\,\text{pack}^{C}\bef r\quad,
-\end{align*}
-and by proving that those functions are inverses of each other.
+Denote by $K\overset{P}{\rightarrow}L$ the type of $FM$-typeclass
+morphisms between functors $K$ and $L$ that belong to the typeclass.
+(The full type signature of an $FM$-typeclass morphism is $\forall A.\,K^{A}\overset{P}{\rightarrow}L^{A}$.)
-Without the type annotations, the code of \lstinline!inF! and \lstinline!outF!
-is:
+We will prove the type equivalence~(\ref{eq:jaskelioff-o-connor-theorem})
+in three steps.
+
+\textbf{(1)} Use the Yoneda identity to obtain this type equivalence:
\[
-\text{inF}=k\rightarrow q\rightarrow q(k)\quad,\quad\quad\text{outF}=r\rightarrow p\rightarrow r(k\rightarrow k(p))\quad.
+A\rightarrow F^{B}\cong\forall X.\,R^{X}\rightarrow F^{X}\quad.
\]
-Now it is quick to prove one direction of isomorphism ($\text{inF}\bef\text{outF}\overset{?}{=}\text{id}$):
+To derive this formula, write:
\begin{align*}
-{\color{greenunder}\text{expect to equal }\text{id}:}\quad & \text{inF}\bef\text{outF}=k\rightarrow\text{outF}\,(q\rightarrow q(k))\\
- & =k\rightarrow p\rightarrow(q\rightarrow q(k))(k\rightarrow k(p))\\
- & =k\rightarrow\gunderline{p\rightarrow k(p)}=k\rightarrow k=\text{id}\quad.
+ & A\rightarrow F^{B}\\
+{\color{greenunder}\text{covariant Yoneda identity}:}\quad & \cong A\rightarrow\forall X.\,(B\rightarrow X)\rightarrow F^{X}\\
+{\color{greenunder}\text{move }\forall X\text{ to front}:}\quad & \cong\forall X.\,A\rightarrow(B\rightarrow X)\rightarrow F^{X}\\
+{\color{greenunder}\text{uncurry the function}:}\quad & \cong\forall X.\,A\times(B\rightarrow X)\rightarrow F^{X}=\forall X.\,R^{X}\rightarrow F^{X}\quad.
\end{align*}
+In the first line of this derivation, we have used the assumption
+that $F$ is a (covariant) functor.
-The other direction ($\text{outF}\bef\text{inF}\overset{?}{=}\text{id}$)
-requires more work. The argument of the function $\text{outF}\bef\text{inF}$
-has type $E\rightarrow R$, and we need to show that for any function
-$r^{:E\rightarrow R}$ the following equation holds:
+\textbf{(2)} By the universal property of the free $FM$-typeclass
+runner, for any functor $F$ that belongs to the $FM$-typeclass and
+for any functor $R$ (not necessarily a member of the $FM$-typeclass)
+there is a one-to-one correspondence between $FM$-typeclass morphisms
+$E^{R}\overset{P}{\rightarrow}F$ and natural transformations $R\leadsto F$.
+In other words, there is a type equivalence between the following
+types (where we wrote out the full type signatures):
\[
-\text{inF}\,(\text{outF}\,(r))\overset{?}{=}r\quad,\quad\text{or equivalently}:\quad r\triangleright\text{outF}\triangleright\text{inF}\overset{?}{=}r\quad.
+\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X}\cong\forall X.\,R^{X}\rightarrow F^{X}\quad.
\]
-The last equation is between functions of type $E\rightarrow R$;
-we may apply both sides to an arbitrary value $e^{:E}$ and require
-that the results (of type $R$) should be equal:
+Now we set $R^{T}\triangleq A\times(B\rightarrow T)$ and obtain:
\[
-\big(r\triangleright\text{outF}\triangleright\text{inF}\big)(e)\overset{?}{=}r(e)\quad.
+(A\rightarrow F^{B})\rightarrow F^{C}\cong(\forall X.\,R^{X}\rightarrow F^{X})\rightarrow F^{C}\cong(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\quad.
\]
-We begin by subtituting the definitions of \lstinline!inF! and \lstinline!outF!:
-\begin{align*}
-{\color{greenunder}\text{expect to equal }r(e):}\quad & e\triangleright\big(r\triangleright\text{outF}\triangleright\text{inF}\big)=e\triangleright\big((\forall A.\,p^{:P^{A}}\rightarrow r(\text{pack}^{A}(p)))\triangleright\text{inF}\big)\\
- & =e^{R}\big(\forall A.\,p^{:P^{A}}\rightarrow r(\text{pack}^{A}(p))\big)=e^{R}(\forall A.\,\text{pack}^{A}\bef r)\quad.
-\end{align*}
-Since $e$ is unknown and arbitrary, we can make progress in the proof
-only if we use the naturality law of $e$ as given by Eq.~(\ref{eq:naturality-law-of-e-derivation1}).
-We assign $B=E$, $C=R$, $f=r$, $k=\text{pack}$ in that law and
-obtain:
+So, the left-hand side of Eq.~(\ref{eq:jaskelioff-o-connor-theorem})
+is equivalent to:
\[
-r(e^{E}(\text{pack}))=e^{R}(\forall A.\,\text{pack}^{A}\bef r)\quad.
+\forall(F\in P\text{-typeclass}).\,(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\quad.
\]
-By the identity law of pack (Statement~\ref{subsec:Statement-identity-law-of-pack}),
-$e^{E}(\text{pack})=e$. So, we conclude the derivation:
-\begin{align*}
-{\color{greenunder}\text{expect to equal }r(e):}\quad & e\triangleright\big(r\triangleright\text{outF}\triangleright\text{inF}\big)=\gunderline{e^{R}(\forall A.\,\text{pack}^{A}\bef r)}\\
-{\color{greenunder}\text{naturality law of }e:}\quad & =r(\gunderline{e^{E}(\text{pack})})\\
-{\color{greenunder}\text{identity law of }\text{pack}:}\quad & =r(e)\quad.
-\end{align*}
-We have proved the isomorphism and also verified Eq.~(\ref{eq:surjectivity-of-pack}).
-$\square$
-\subsection{Greatest fixpoints and the Church-co-Yoneda identity\label{subsec:The-greatest-fixpoints-and-Church-co-Yoneda}}
-
-We have seen that the least fixpoints of functors are expressed via
-the Church encoding type that involves a universally quantified higher-order
-function. An analogous encoding (with an existentially quantified
-type) exists for greatest fixpoints. We will now prove some properties
-of that encoding.\footnote{This section follows the logic shown in P.~Wadler\textsf{'}s paper \textsf{``}Recursive
-types for free\textsf{''} except that the existential types are defined by
-Eq.~(\ref{eq:existential-via-universal-Yoneda}) via the universal
-quantifier.}
-
-We work with a fixed covariant functor $F$ and denote by $C$ the
-following Church-encoded type:
+\textbf{(3)} We use the covariant Yoneda identity in the category
+of functors that belong to the $FM$-typeclass. As we have found in
+Section~\ref{subsec:Imposing-laws-of-P-typeclasses-via-monad-algebras},
+all those functors are $E$-monad algebras, which form a category.
+The $FM$-typeclass morphisms are in one-to-one correspondence with
+the $E$-monad algebra morphisms. Therefore, we may write the covariant
+Yoneda identity for that category as:
\[
-C\triangleq\exists A.\,(A\rightarrow F^{A})\times A\quad.
+\forall(F\in P\text{-typeclass}).\,(\forall X.\,Q^{X}\overset{P}{\rightarrow}F^{X})\rightarrow S^{F}\cong S^{Q}\quad,
\]
-We will prove that $C$ is the greatest fixpoint of the type equation
-$X\cong F^{X}$; that is, $C=\nu X.\,F^{X}$.
-
-First, we define some auxiliary functions that work with the type
-$C$ and prove their properties.
-
-The function \lstinline!unfold! constructs values of type $C$:
-\begin{align*}
- & \text{unfold}:\forall T.\,(T\rightarrow F^{T})\times T\rightarrow C\quad,\\
- & \text{unfold}^{T}(u^{:T\rightarrow F^{T}}\times t^{:T})\triangleq\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R}\rightarrow p^{T}(u\times t)\quad.
-\end{align*}
-Note that \lstinline!unfold! is the same as the function \lstinline!pack!
-from Statement~\ref{subsec:Statement-identity-law-of-pack} if we
-set $E=C$ and $P^{A}\triangleq(A\rightarrow F^{A})\times A$ in the
-definition of \lstinline!pack!.
-
-By parametricity, the function \lstinline!unfold! satisfies a relational
-naturality law: for all types $A$, $B$ and all functions $f^{:A\rightarrow B}$,
-\begin{equation}
-\text{if}\quad u\bef f^{\uparrow F}=f\bef v\quad\text{then}\quad\text{unfold}^{A}(u^{:A\rightarrow F^{A}}\times a^{:A})=\text{unfold}^{B}(v^{:B\rightarrow F^{B}}\times f(a))\quad.\label{eq:relational-naturality-law-of-unfold}
-\end{equation}
-In category theory, the precondition $u\bef f^{\uparrow F}=f\bef v$
-is known as the \textsf{``}$F$-coalgebra morphism law\textsf{''} of $f$. Let us
-give some definitions for reference:
-
-\subsubsection{Definition \label{subsec:Definition-F-coalgebra}\ref{subsec:Definition-F-coalgebra}}
-
-Given a functor $F$, a type $A$ together with a function $u:A\rightarrow F^{A}$
-is called an $F$\textbf{-coalgebra}.\index{$F$-coalgebra} The type
-$A$ is called the \textbf{carrier} of the $F$-coalgebra, and the
-function $u$ is called the \textbf{structure map} of the $F$-coalgebra.
-(Keep in mind that $u$ is not universally quantified over $A$; it
-is a function that only works with a single, specified type $A$.
-For a given type $A$, there could be several different structure
-maps $u$, $u^{\prime}$, and so on; each of them will then define
-a different $F$-coalgebra.)
+where $Q$ is any fixed functor from the $FM$-typeclass, $S^{F}$
+is any type expression that is covariant in $F$, and the naturality
+law with respect to $F$ is assumed to hold. We will use this Yoneda
+identity with $Q=E^{R}$, and set $S^{F}$ to just $F^{C}$ (the application
+of $F$ to the fixed type $C$). Then we get:
+\[
+\forall(F\in P\text{-typeclass}).\,(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\cong(E^{R})^{C}\quad.
+\]
+The last type is the right-hand side of Eq.~(\ref{eq:jaskelioff-o-connor-theorem}).
+So, Eq.~(\ref{eq:jaskelioff-o-connor-theorem}) holds.
-If $A$ and $B$ are two $F$-coalgebras with structure maps $u:A\rightarrow F^{A}$
-and $v:B\rightarrow F^{B}$ then a function $f:A\rightarrow B$ is
-called an $F$-coalgebra morphism if this law holds:
+Let us now derive the code that implements the type equivalence~(\ref{eq:jaskelioff-o-connor-theorem})
+in the direction of right-to-left. Suppose we are given a value $q$
+of the type in the right-hand side of Eq.~(\ref{eq:jaskelioff-o-connor-theorem}):
\[
-\xymatrix{\xyScaleY{2.3pc}\xyScaleX{2.5pc}A\ar[d]\sb(0.4){u}\ar[r]\sp(0.5){f} & B\ar[d]\sp(0.4){v}\\
-F^{A}\ar[r]\sp(0.5){f^{\uparrow F}} & F^{B}
-}
+q:(E^{R})^{C}\quad.
\]
+We need to retrace step \textbf{(3)} above and convert this $q$ to
+a function $f$ of type:
\[
-u\bef f^{\uparrow F}=f\bef v\quad.
+f:\forall(F\in P\text{-typeclass}).\,(\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X})\rightarrow F^{C}\quad.
+\]
+The required function $f$ is defined by:
+\[
+f^{F}\big(k^{:\forall X.\,(E^{R})^{X}\overset{P}{\rightarrow}F^{X}}\big)\triangleq k^{C}(q)\quad.
\]
-This is the $F$-coalgebra morphism law of $f$. $\square$
-It is also helpful to define a function \lstinline!unfoldF! that
-constructs values of type $F^{C}$:
-\begin{align*}
- & \text{unfoldF}:\forall T.\,(T\rightarrow F^{T})\times T\rightarrow F^{C}\quad,\\
- & \text{unfoldF}^{T}(u^{:T\rightarrow F^{T}}\times t^{:T})\triangleq t\triangleright u\triangleright\big(a^{:T}\rightarrow\text{unfold}^{T}(u\times a)\big)^{\uparrow F}\quad.
-\end{align*}
+Continue by retracing step \textbf{(2)}, converting $f$ to a function
+$g$ of type:
+\[
+g:\forall(F\in P\text{-typeclass}).\,(\forall X.\,R^{X}\rightarrow F^{X})\rightarrow F^{C}\quad.
+\]
+The function $g$ is defined by:
+\[
+g^{F}\big(k^{:\forall X.\,R^{X}\rightarrow F^{X}}\big)\triangleq f^{F}\big(\forall Y.\,r^{:(E^{R})^{Y}}\rightarrow\text{run}_{E}^{R,Y}(k)(r)\big)\quad,
+\]
+where the universal runner ($\text{run}_{E}^{T,Y}$) has type:
+\[
+\text{run}_{E}^{T,Y}:(\forall X.\,T^{X}\rightarrow F^{X})\rightarrow(E^{T})^{Y}\rightarrow F^{Y}\quad.
+\]
-The isomorphism $C\cong F^{C}$ will be implemented via two functions:
+It remains to retrace step \textbf{(1)} and define a function $h$
+of type:
\[
-\text{fix}:F^{C}\rightarrow C\quad,\quad\quad\text{unfix}:C\rightarrow F^{C}\quad,
+h:\forall(F\in P\text{-typeclass}).\,(A\rightarrow F^{B})\rightarrow F^{C}\quad.
\]
-which we define via \lstinline!unfold! and \lstinline!unfoldF! like
-this:
-\begin{align*}
- & \text{unfix}:C\rightarrow F^{C}\quad,\quad\quad\text{unfix}\triangleq c^{:C}\rightarrow c^{F^{C}}(\forall A.\,\text{unfoldF}^{A})=c^{:C}\rightarrow c^{F^{C}}(\text{unfoldF})\quad,\\
- & \text{fix}:F^{C}\rightarrow C\quad,\quad\quad\text{fix}\triangleq p^{:F^{C}}\rightarrow\text{unfold}^{F^{C}}(\text{unfix}^{\uparrow F}\times p)\quad.
-\end{align*}
-Because of these functions, $C$ is at the same time an $F$-algebra
-and an $F$-coalgebra.
+We implement $h$ via this code:
+\[
+h^{F}(k^{:A\rightarrow F^{B}})\triangleq g^{F}\big(\forall X.\,a^{:A}\times t^{:B\rightarrow X}\rightarrow k(a)\triangleright t^{\uparrow F}\big)\quad.
+\]
+This completes the code that transforms $q$ into $h$. $\square$
+
+We will now apply the Jaskelioff-O\textsf{'}Connor theorem to prove some useful
+type equivalences.
+
+\subsubsection{Statement \label{subsec:Statement-identity-monad-morphism}\ref{subsec:Statement-identity-monad-morphism}}
+
+Denote by $F\xrightarrow{\text{Monad}}G$ (more verbosely, $\forall X.\,F^{X}\xrightarrow{\text{Monad}}G^{X}$)
+the type of monad morphisms between monads $F$ and $G$. Those are
+natural transformations of type $\forall X.\,F^{X}\rightarrow G^{X}$
+that additionally satisfy the laws of monad morphisms. Denote by $\text{Id}$
+the identity monad ($\text{Id}^{A}\triangleq A$).
-\subsubsection{Statement \label{subsec:Statement-coalgebra-morphism-unfold}\ref{subsec:Statement-coalgebra-morphism-unfold}}
+\textbf{(a)} The standard monad method $\text{pu}_{M}:\forall A.\,A\rightarrow M^{A}$
+is the only monad morphism of type $\text{Id}\xrightarrow{\text{Monad}}M$
+that works in the same way for all monads $M$.\footnote{See \texttt{\href{https://cstheory.stackexchange.com/questions/53389/}{https://cstheory.stackexchange.com/questions/53389/}}}
+We can express this as a type equivalence:
+\[
+\forall M^{:\text{Monad}}.\,\text{Id}\xrightarrow{\text{Monad}}M\cong\bbnum 1\quad.
+\]
-For any $F$-coalgebra $A$ with a structure map $u:A\rightarrow F^{A}$,
-denote by $\psi_{u}^{A}$ the following function of type $A\rightarrow C$:
+\textbf{(b)} The identity function of type $\forall X.\,M^{X}\rightarrow M^{X}$
+is the only monad morphism of type $M\xrightarrow{\text{Monad}}M$
+that works in the same way for all monads $M$.\footnote{See \texttt{\href{https://stackoverflow.com/questions/61444425/}{https://stackoverflow.com/questions/61444425/}}}
+We can express this as a type equivalence:
\[
-\psi_{u}^{A}:A\rightarrow C\quad,\quad\quad\psi_{u}^{A}\triangleq a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\quad.
+\forall M^{:\text{Monad}}.\,M\xrightarrow{\text{Monad}}M\cong\bbnum 1\quad.
\]
-Then $\psi_{u}^{A}$ is an $F$-coalgebra morphism of type $A\rightarrow C$.
+
\subparagraph{Proof}
-Write the $F$-coalgebra morphism law for that function:
-\[
-u\bef\big(a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\big)^{\uparrow F}\overset{?}{=}\big(a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\big)\bef v\quad.
-\]
-Apply both sides to an arbitrary value $t^{:A}$ and obtain:
+The \lstinline!Monad! typeclass has methods in the form of an $FM$-typeclass
+for functors $K$ if we define $P$ by $(P^{K})^{A}\triangleq A+K^{K^{A}}$.
+Then the methods of the \lstinline!Monad! typeclass are represented
+by a single value of type:
\[
-t\triangleright u\triangleright(a\rightarrow\text{unfold}^{A}(u\times a))^{\uparrow F}\overset{?}{=}\text{unfix}\,(\text{unfold}^{A}(u\times t))\quad.
+\forall A.\,(P^{K})^{A}\rightarrow K^{A}=\forall A.\,A+K^{K^{A}}\rightarrow K^{A}\cong(\forall A.\,A\rightarrow K^{A})\times(\forall A.\,K^{K^{A}}\rightarrow K^{A})\quad.
\]
-Begin with the right-hand side:
+This is a tuple type describing the type signatures of $K$\textsf{'}s \lstinline!pure!
+and \lstinline!flatten! methods when $K$ is a monad. So, the Jaskelioff-O\textsf{'}Connor
+theorem applies to the \lstinline!Monad! typeclass. The free monad
+constructor ($E$) is defined recursively as $(E^{F})^{A}\triangleq A+F^{(E^{F})^{A}}$,
+making $E^{F}$ a monad when $F$ is any functor. The free monad\textsf{'}s
+universal runner is defined by:
\begin{align*}
- & \text{unfix}\,(\text{unfold}^{A}(u\times t))\\
-{\color{greenunder}\text{definition of }\text{unfix}:}\quad & =(\text{unfold}^{A}(u\times t))^{F^{C}}(\text{unfoldF})\\
-{\color{greenunder}\text{definition of }\text{unfold}:}\quad & =\text{unfoldF}^{A}(u\times t)\\
-{\color{greenunder}\text{definition of }\text{unfoldF}:}\quad & =t\triangleright u\triangleright\big(a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\big)^{\uparrow F}\quad.
+ & \text{run}_{E}^{F,A}:(\forall X.\,F^{X}\rightarrow M^{X})\rightarrow(E^{F})^{A}\rightarrow M^{A}\quad,\\
+ & \text{run}_{E}^{F,A}\big(k^{:\forall X.\,F^{X}\rightarrow M^{X}}\big)\triangleq\,\begin{array}{|c||c|}
+ & M^{A}\\
+\hline A & \text{pu}_{M}\\
+F^{(E^{F})^{A}} & k^{(E^{F})^{A}}\bef\text{flm}_{M}\big(\overline{\text{run}}_{E}^{F,A}(k)\big)
+\end{array}\quad.
\end{align*}
-This is now equal to the left-hand side. $\square$
-
-\subsubsection{Statement \label{subsec:Statement-identity-law-of-unfold}\ref{subsec:Statement-identity-law-of-unfold}}
-The function \lstinline!unfold! satisfies an \textbf{identity law}:
+\textbf{(a)} Monad morphisms are natural transformations that satisfy
+additional laws. We first consider the given type without restricting
+the functions of type $A\rightarrow M^{A}$ to monad morphisms but
+still assuming that they are natural transformations:
\[
-\text{for all }c^{:C}:\quad\text{unfold}^{C}(\text{unfix}\times c)\overset{?}{=}c\quad.
+\forall M^{:\text{Monad}}.\,\forall A.\,A\rightarrow M^{A}\quad.
\]
-This law\index{identity laws!of unfold@of \lstinline!unfold!} is
-similar to the identity law of \lstinline!pack! (Statement~\ref{subsec:Statement-identity-law-of-pack}).
-
-\subparagraph{Proof}
-
-Apply Statement~\ref{subsec:Statement-identity-law-of-pack}, which
-gives $e^{E}(\text{pack})=e$, and substitute $E=C$, $e=c$, $P^{A}=(A\rightarrow F^{A})\times A$,
-and \lstinline!unfold! instead of \lstinline!pack!. We obtain:
-\begin{equation}
-c=c^{C}(\text{unfold})\quad.\label{eq:unfold-id-law-derivation1}
-\end{equation}
-Now use the law~(\ref{eq:surjectivity-of-pack}) where we substitute
-$E=R=C$ and $e=c$:
+By the Yoneda identity, we get the type equivalence:
\[
-\text{for all }r^{:C\rightarrow C}:\quad r(c)=c^{C}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times a^{:A}\rightarrow r(\text{unfold}^{A}(u\times a))\big)\quad.
+\forall A.\,A\rightarrow M^{A}\cong M^{\bbnum 1}\quad.
\]
-We will use this law with the function $r$ defined by:
+So, we have reduced the type to $\forall M^{:\text{Monad}}.\,M^{\bbnum 1}$.
+This type will be in the form suitable for the Jaskelioff-O\textsf{'}Connor
+theorem~(\ref{eq:jaskelioff-o-connor-theorem}) if we set $F=M$,
+$A=\bbnum 0$, $C=\bbnum 1$; the parameter $B$ remains unused since
+$A\rightarrow M^{B}=\bbnum 0\rightarrow M^{B}\cong\bbnum 1$. Then
+Eq.~(\ref{eq:jaskelioff-o-connor-theorem}) gives:
\[
-r:C\rightarrow C\quad,\quad\quad r(c)\triangleq\text{unfold}^{C}(\text{unfix}\times c)\quad.
+\forall M^{:\text{Monad}}.\,M^{\bbnum 1}\cong\forall M^{:\text{Monad}}.\,(\bbnum 0\rightarrow M^{B})\rightarrow M^{\bbnum 1}\cong(E^{R})^{\bbnum 1}\quad,
\]
-Then we get:
-\begin{align}
- & \text{unfold}^{C}(\text{unfix}\times c)=r(c)=c^{C}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times a^{:A}\rightarrow r(\text{unfold}^{A}(u\times a))\big)\nonumber \\
- & =c^{C}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times a^{:A}\rightarrow\text{unfold}^{C}(\text{unfix}\times\text{unfold}^{A}(u\times a)))\big)\quad.\label{eq:unfold-id-law-derivation3}
-\end{align}
-Now we apply the naturality law~(\ref{eq:relational-naturality-law-of-unfold})
-with $B=C$, $f=a\rightarrow\text{unfold}^{A}(u\times a)$, and $v=\text{unfix}$:
-\begin{equation}
-\text{unfold}^{A}(u\times a)=\text{unfold}^{C}(\text{unfix}\times\text{unfold}^{A}(u\times a)))\quad.\label{eq:unfold-id-law-derivation2}
-\end{equation}
-The precondition of this law ($u\bef f^{\uparrow F}\overset{?}{=}f\bef v$)
-is the $F$-coalgebra morphism law of \lstinline!unfold!, and it
-has been demonstrated in Statement~\ref{subsec:Statement-coalgebra-morphism-unfold}.
-So, Eq.~(\ref{eq:unfold-id-law-derivation2}) holds.
-
-Finally, we can finish the proof:
-\begin{align*}
-{\color{greenunder}\text{expect to equal }c:}\quad & \text{unfold}^{C}(\text{unfix}\times c)\\
-{\color{greenunder}\text{use Eq.~(\ref{eq:unfold-id-law-derivation3})}:}\quad & =c^{C}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times a^{:A}\rightarrow\gunderline{\text{unfold}^{C}(\text{unfix}\times\text{unfold}^{A}(u\times a)))}\big)\\
-{\color{greenunder}\text{use Eq.~(\ref{eq:unfold-id-law-derivation2})}:}\quad & =c^{C}\big(\gunderline{\forall A.\,u^{:A\rightarrow F^{A}}\times a^{:A}\rightarrow\text{unfold}^{A}(u\times a)}\big)=c^{C}(\text{unfold})\\
-{\color{greenunder}\text{use Eq.~(\ref{eq:unfold-id-law-derivation1})}:}\quad & =c\quad.
-\end{align*}
-
-
-\subsubsection{Statement \label{subsec:Statement-greatest-fixpoint-church-encoding}\ref{subsec:Statement-greatest-fixpoint-church-encoding}}
-
-The functions \lstinline!fix! and \lstinline!unfix! are inverses
-to each other.
-
-\subparagraph{Proof}
-
-Translate the existential quantifier via Eq.~(\ref{eq:existential-via-universal-Yoneda})
-and write $C$ as:
+where we must define $R^{X}=A\times(B\rightarrow X)$. However, setting
+$A=\bbnum 0$ gives also $R=\bbnum 0$. Then the free monad $E^{R}$
+is the identity functor:
\[
-C\triangleq\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R)\rightarrow R\quad.
+(E^{R})^{C}=C+R^{(E^{R})^{C}}=C+\bbnum 0\cong C\quad.
+\]
+Finally, we obtain $(E^{R})^{\bbnum 1}=\bbnum 1$, and so:
+\[
+\forall M^{:\text{Monad}}.\,\forall A.\,A\rightarrow M^{A}\cong\bbnum 1\quad.
\]
-We need to verify that:
-
-\textbf{(1)} For any $c:C$ we have $\text{fix}\,(\text{unfix}\,(c))=c$.
-\textbf{(2)} For any $q:F^{C}$ we have $\text{unfix}\,(\text{fix}\,(q))=q$.
+We conclude that \emph{without} restricting to monad morphisms there
+is only a single function of the given type. It remains to derive
+the code for that function and to verify that it is indeed a monad
+morphism.
-To prove item \textbf{(1)}:
+We begin with a unit value (that we denote by $1$) viewed as a value
+of type $(E^{R})^{C}$ in the right-hand side of Eq.~(\ref{eq:jaskelioff-o-connor-theorem}).
+We follow the proof of Statement~\ref{subsec:Statement-Jaskelioff-OConnor}.
+The first step is to convert the value of type $(E^{R})^{C}$ into
+a function $f$ of type:
+\[
+f:\forall M^{:\text{Monad}}.\,\big(\forall X.\,(E^{R})^{X}\xrightarrow{\text{Monad}}M^{X}\big)\rightarrow M^{C}\quad.
+\]
+In our case, this function is simplified to:
\begin{align*}
-{\color{greenunder}\text{expect to equal }c:}\quad & \gunderline{\text{fix}}\,(\text{unfix}\,(c))\\
-{\color{greenunder}\text{definition of }\text{fix}:}\quad & =\text{unfold}^{F^{C}}(\text{unfix}^{\uparrow F}\times\text{unfix}\,(c))\\
-{\color{greenunder}\text{naturality law of }\text{unfold}:}\quad & =\text{unfold}^{C}(\text{unfix}\times c)\\
-{\color{greenunder}\text{identity law of }\text{unfold}:}\quad & =c\quad.
+ & f:\forall M^{:\text{Monad}}.\,\big(\forall X.\,\text{Id}^{X}\xrightarrow{\text{Monad}}M^{X}\big)\rightarrow M^{\bbnum 1}\quad,\\
+ & f^{M}\big(k^{:\forall X.\,\text{Id}^{X}\xrightarrow{\text{Monad}}M^{X}}\big)\triangleq k^{\bbnum 1}(1)\quad.
\end{align*}
-Here we applied the naturality law~(\ref{eq:relational-naturality-law-of-unfold})
-with $A=C$, $B=F^{C}$, $a=c$, $f=\text{unfix}$, $u=\text{unfix}$,
-and $v=\text{unfix}^{\uparrow F}$. To verify the precondition of
-that law, write:
+The next step is to convert $f$ to a function $g$ of type:
\[
-u\bef f^{\uparrow F}\overset{?}{=}f\bef v\quad,\quad\text{or equivalently:}\quad\text{unfix}\bef\text{unfix}^{\uparrow F}\overset{?}{=}\text{unfix}\bef\text{unfix}^{\uparrow F}\quad.
+g:\forall M^{:\text{Monad}}.\,(\forall X.\,R^{X}\rightarrow M^{X})\rightarrow M^{C}\quad.
\]
-This holds trivially.
-
-To prove item \textbf{(2)}, write:
+In our case, $R^{X}=\bbnum 0$ and $R^{X}\rightarrow M^{X}\cong\bbnum 1$,
+so this function is simplified to:
\begin{align*}
-{\color{greenunder}\text{expect to equal }q:}\quad & \text{unfix}\,(\gunderline{\text{fix}\,(q)})\\
-{\color{greenunder}\text{definition of }\text{fix}:}\quad & =\gunderline{\text{unfix}}\,\big(\text{unfold}^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\big)\\
-{\color{greenunder}\text{definition of }\text{unfold}:}\quad & =\text{unfix}\,\big(\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R}\rightarrow p^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\big)\\
-{\color{greenunder}\text{definition of }\text{unfix}:}\quad & =\big(\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times A\rightarrow R}\rightarrow p^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\big)^{F^{C}}(\text{unfoldF})\\
-{\color{greenunder}\text{apply function}:}\quad & =\text{unfoldF}^{F^{C}}(\text{unfix}^{\uparrow F}\times q)\\
-{\color{greenunder}\text{definition of }\text{unfoldF}:}\quad & =q\triangleright\gunderline{\text{unfix}^{\uparrow F}\bef\big(a^{:F^{C}}\rightarrow\text{unfold}\,(\text{unfix}^{\uparrow F}\times a)\big)^{\uparrow F}}\\
-{\color{greenunder}\text{composition under }^{\uparrow F}:}\quad & =q\triangleright\big(x^{:C}\rightarrow\gunderline{\text{unfold}\,(\text{unfix}^{\uparrow F}\times\text{unfix}\,(x))}\big)^{\uparrow F}\\
-{\color{greenunder}\text{definition of }\text{fix}:}\quad & =q\triangleright\big(x^{:C}\rightarrow\gunderline{\text{fix}\,(\text{unfix}\,(x))}\big)^{\uparrow F}\\
-{\color{greenunder}\text{item \textbf{(1)}}:}\quad & =q\triangleright\gunderline{(x^{:C}\rightarrow x)^{\uparrow F}}=x\triangleright\text{id}=q\quad.
+ & g:\forall M^{:\text{Monad}}.\,\bbnum 1\rightarrow M^{\bbnum 1}\quad,\\
+ & g^{M}(k^{:\bbnum 1})\triangleq f^{M}\big(\forall Y.\,r^{:(E^{R})^{Y}}\rightarrow\text{run}_{E}^{R,Y}(k)(r)\big)\\
+ & \quad=f^{M}(\forall Y.\,r^{:Y}\rightarrow\text{pu}_{M}^{Y}(r))=\text{pu}_{M}^{\bbnum 1}(1)\quad.
\end{align*}
-$\square$
-
-It follows that $C$ is a fixpoint of the type equation $C\cong F^{C}$.
-To show that $C$ is indeed the \emph{greatest} fixpoint, we need
-to prove that for any other fixpoint $T$ there exists a unique fixpoint-preserving
-morphism $\psi^{T}:T\rightarrow C$. Similarly to what we saw in Statement~\ref{subsec:Statement-fixpoint-preserving-fix},
-it is sufficient to check that $\psi^{T}$ is an $F$-coalgebra morphism.
-
-\subsubsection{Statement \label{subsec:Statement-greatest-fixpoint-Church-encoding-morphism}\ref{subsec:Statement-greatest-fixpoint-Church-encoding-morphism}}
+Finally, we convert $g$ to a function $h$ of type:
+\begin{align*}
+ & h:\forall M^{:\text{Monad}}.\,(A\rightarrow M^{B})\rightarrow M^{C}\\
+ & =\forall M^{:\text{Monad}}.\,(\bbnum 0\rightarrow M^{B})\rightarrow M^{\bbnum 1}\quad.\\
+ & \cong\forall M^{:\text{Monad}}.\,\bbnum 1\rightarrow M^{\bbnum 1}\cong\forall M^{:\text{Monad}}.\,M^{\bbnum 1}\quad.
+\end{align*}
+ There exists only one value of type $\forall M^{:\text{Monad}}.\,M^{\bbnum 1}$,
+and that value is $\text{pu}_{M}(1)$. Converting that to the type
+signature $\forall A.\:A\rightarrow M^{A}$, we recover just the standard
+monad method $\text{pu}_{M}$. We know that $\text{pu}_{M}$ gives
+a monad morphism between the identity monad and $M$ (see Statement~\ref{subsec:Statement-pure-M-is-monad-morphism}).
+So, we have proved that there exists a unique monad morphism of type
+$\forall M^{:\text{Monad}}.\,\text{Id}\xrightarrow{\text{Monad}}M$.
-For any $F$-coalgebra $A$ with a structure map $u:A\rightarrow F^{A}$,
-there exists a unique $F$-algebra morphism $\psi_{u}^{A}$ of type
-$A\rightarrow C$. The function $\psi_{u}^{A}$ is known as the \textbf{anamorphism}\index{anamorphism}
-and was defined as in Statement~\ref{subsec:Statement-coalgebra-morphism-unfold}:
+\textbf{(b)} Again, we first consider the given type without restricting
+the functions of type $M^{X}\rightarrow M^{X}$ to monad morphisms
+(but still assuming that they are natural transformations):
\[
-\psi_{u}^{A}:A\rightarrow C\quad,\quad\quad\psi_{u}^{A}\triangleq a^{:A}\rightarrow\text{unfold}^{A}(u\times a)\quad.
+\forall M^{:\text{Monad}}.\,\forall X.\,M^{X}\rightarrow M^{X}\quad.
\]
-
-
-\subparagraph{Proof}
-
-We know from Statement~\ref{subsec:Statement-coalgebra-morphism-unfold}
-that $\psi_{u}^{A}$ satisfies the law of $F$-coalgebra morphisms.
-Let $f:A\rightarrow C$ be any other $F$-coalgebra morphism; we need
-to prove that $f=\psi_{u}^{A}$.
-
-We know that $f$ satisfies the $F$-coalgebra morphism law:
+This type will be in the form suitable for the Jaskelioff-O\textsf{'}Connor
+theorem~(\ref{eq:jaskelioff-o-connor-theorem}) if we set $F=M$,
+$A=\bbnum 1$, and $B=C=X$. The functor $R$ is then defined by:
\[
-u\bef f^{\uparrow F}=f\bef\text{unfix}\quad.
+R^{T}\triangleq A\times(B\rightarrow T)\cong X\rightarrow T\quad,
\]
-This is the precondition of the relational naturality law~(\ref{eq:relational-naturality-law-of-unfold})
-of \lstinline!unfold! if we set $B=C$ and $v=\text{unfix}$. So,
-the conclusion of that law holds. We use that equation as well as
-Statement~\ref{subsec:Statement-identity-law-of-unfold} and get:
-\begin{align*}
-{\color{greenunder}\text{for any }a^{:A}:}\quad & \psi_{u}^{A}(a)=\text{unfold}^{A}(u^{:A\rightarrow F^{A}}\times a^{:A})\\
-{\color{greenunder}\text{naturality law of }\text{unfold}:}\quad & =\text{unfold}^{C}(\text{unfix}\times f(a))\\
-{\color{greenunder}\text{identity law of }\text{unfold}:}\quad & =f(a)\quad.
-\end{align*}
-It follows that $\psi_{u}^{A}=f$. $\square$
-
-We conclude this Appendix with the proof of a type identity dual to
-the Church-Yoneda identity\index{Church-co-Yoneda identity} shown
-in Statement~\ref{subsec:Statement-Church-Yoneda-identity}. That
-identity has no accepted name, and this book calls it the \textsf{``}Church-co-Yoneda\textsf{''}
-identity.
-
-\subsubsection{Statement \label{subsec:Statement-Church-co-Yoneda}\ref{subsec:Statement-Church-co-Yoneda}}
-
-For any covariant functors $F$ and $G$:
+and the functor $E^{R}$ (the free monad on $R$) is defined recursively
+by:
\[
-G^{\nu X.\,F^{X}}\cong\exists A.\,(A\rightarrow F^{A})\times G^{A}\quad.
+(E^{R})^{T}\triangleq T+\big(X\rightarrow(E^{R})^{T}\big)\quad.
\]
-
-
-\subparagraph{Proof}
-
-Denote for brevity $C\triangleq\nu X.\,F^{X}$. The existential type
-is rewritten as:
+ With these definitions, Eq.~(\ref{eq:jaskelioff-o-connor-theorem})
+gives:
+\[
+\forall M^{:\text{Monad}}.\,\forall X.\,M^{X}\rightarrow M^{X}\cong\forall X.\,(E^{R})^{X}\quad.
+\]
+We are using the functor $(E^{R})^{T}$ with the type parameter $T=X$;
+however, $E^{R}$ also contains $X$ through the definition of $R$.
+To avoid confusion and to simplify notation, let us write $G^{X}$
+instead of $(E^{R})^{X}$, where the type constructor $G$ is defined
+recursively by:
\[
-\exists A.\,(A\rightarrow F^{A})\times G^{A}=\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R\quad.
+G^{X}\triangleq X+(X\rightarrow G^{X})\quad.
\]
-We will demonstrate the isomorphism if we define functions \lstinline!toG!
-and \lstinline!fromG! that are mutual inverses, with type signatures:
+(Note that $G$ is neither covariant nor contravariant.) With this
+definition, we obtain:
\[
-\text{toG}:(\exists A.\,(A\rightarrow F^{A})\times G^{A})\rightarrow G^{C}\quad,\quad\quad\text{fromG}:G^{C}\rightarrow\exists A.\,(A\rightarrow F^{A})\times G^{A}\quad.
+\forall M^{:\text{Monad}}.\,\forall X.\,M^{X}\rightarrow M^{X}\cong\forall X.\,G^{X}\quad.
\]
-The first type signature can be implemented as:
+
+To simpify the type $\forall X.\,G^{X}$, begin by expanding the recursive
+type $G^{X}$:
\begin{align*}
- & \text{toG}:\big(\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R\big)\rightarrow G^{C}\quad,\\
- & \text{toG}\triangleq k^{:\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R}\rightarrow k^{G^{C}}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)\quad,
+ & \forall X.\,G^{X}\cong\forall X.\,X+(X\rightarrow G^{X})\\
+{\color{greenunder}\text{non-disjunctivity}:}\quad & \cong(\forall X.\,X)+(\forall X.\,X\rightarrow G^{X})\\
+{\color{greenunder}\text{use }\forall X.\,X\cong\bbnum 0:}\quad & \cong\forall X.\,X\rightarrow G^{X}\quad.
\end{align*}
-where $\psi_{u}^{A}$ is the anamorphism of type $A\rightarrow C$
-defined in Statement~\ref{subsec:Statement-coalgebra-morphism-unfold}.
+Here we used the non-disjunctivity property from Example~\ref{subsec:Example-undisjunctive-type-constructors}(e).
-The function \lstinline!fromG! is implemented as:
+Continue expanding the recursive type:
\begin{align*}
- & \text{fromG}:G^{C}\rightarrow\forall R.\,(\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R)\rightarrow R\quad,\\
- & \text{fromG}\triangleq g^{:G^{C}}\rightarrow\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R}\rightarrow p^{C}(\text{unfix}\times g)\quad.
+ & \forall X.\,X\rightarrow G^{X}\cong\forall X.\,X\rightarrow(X+(X\rightarrow G^{X}))\\
+{\color{greenunder}\text{non-disjunctivity}:}\quad & \cong(\gunderline{\forall X.\,X\rightarrow X})+\big(\forall X.\,X\rightarrow X\rightarrow G^{X}\big)\\
+ & \cong\bbnum 1+\forall X.\,X\times X\rightarrow G^{X}\quad.
+\end{align*}
+The relevant non-disjunctivity property was shown in Example~\ref{subsec:Example-undisjunctive-type-constructors}(f).
+Expand further, using the same non-disjunctivity property:
+\begin{align*}
+ & \forall X.\,G^{X}\cong\bbnum 1+\forall X.\,X\times X\rightarrow G^{X}\\
+ & \cong\bbnum 1+\forall X.\,X\times X\rightarrow(X+(X\rightarrow G^{X}))\\
+{\color{greenunder}\text{non-disjunctivity}:}\quad & \cong\bbnum 1+(\gunderline{\forall X.\,X\times X\rightarrow X})+\big(\forall X.\,X\times X\rightarrow X\rightarrow G^{X}\big)\\
+ & \cong\bbnum 1+\bbnum 2+\forall X.\,X\times X\times X\rightarrow G^{X}\quad.
\end{align*}
+Proceeding similarly, we obtain:
+\[
+\forall X.\,\underbrace{X\times...\times X}_{n\text{ times}}\rightarrow G^{X}\cong\underbrace{\bbnum 1+...+\bbnum 1}_{n\text{ times}}+\forall X.\,\underbrace{X\times...\times X}_{n+1\text{ times}}\rightarrow G^{X}\quad.
+\]
+It follows by induction that $\forall X.\,G^{X}$ is equivalent to
+an \textsf{``}infinite\textsf{''} sum type:
+\[
+\forall X.\,G^{X}\cong\bbnum 1+\bbnum 2+\bbnum 3+...
+\]
+Values of that type may be described by pairs $\left(n,k\right)$
+of natural numbers such that $1\le k\le n$. The number $n$ chooses
+the part \textsf{``}$\bbnum n$\textsf{''} within the disjunctive type $\bbnum 1+\bbnum 2+\bbnum 3+...$,
+where we denoted by \textsf{``}$\bbnum n$\textsf{''} the type $\underbrace{\bbnum 1+...+\bbnum 1}_{n\text{ times}}$.
+The number $k$ chooses a specific unit value within $\underbrace{\bbnum 1+...+\bbnum 1}_{n\text{ times}}$.
-It remains to prove the two directions of the isomorphism roundtrip:
+The next step is to convert values $\left(n,k\right)$ of that type
+into functions of type $M^{X}\rightarrow M^{X}$ that work in the
+same way for all monads $M$ and all types $X$. We have to find out
+whether any of those functions obey the laws of monad morphisms. For
+that, we need to derive the specific code of those functions. We follow
+the steps outlined in the proof of Statement~\ref{subsec:Statement-Jaskelioff-OConnor}.
-\textbf{(1)} For any $g:G^{C}$ we have: $\text{toG}\,(\text{fromG}\,(g))=g$.
+First, we translate pairs $\left(n,k\right)$ into values of type
+$\forall X.\,G^{X}$ that we will denote by $q_{n,k}$. To achieve
+that, we need to retrace the way we expanded the recursive type $G^{X}$.
+As an example, consider the pair $\left(n=2,k=1\right)$. The value
+$n=2$ corresponds to the type $\bbnum 2$, which was obtained from
+$\forall X.\,X\rightarrow X\rightarrow X$ during expansion of $\forall X.\,G^{X}$.
+The type $\forall X.\,X\rightarrow X\rightarrow X$ has only two distinct
+values, which are functions that return the first or the second argument
+of type $X$. The index $k=1$ selects the first of those values,
+which is a function whose code is written as $x_{1}^{:X}\rightarrow x_{2}^{:X}\rightarrow x_{1}$.
-\textbf{(2)} For any $k:\exists A.\,(A\rightarrow F^{A})\times G^{A}$
-we have: $\text{fromG}\,(\text{toG}\,(k))=k$.
+To simplify notation, let us temporarily fix the type parameter $X$;
+we will restore the quantifier $\forall X$ at the end of the derivation.
-To prove item \textbf{(1)}:
-\begin{align*}
- & \text{toG}\,(\gunderline{\text{fromG}}\,(g))=\gunderline{\text{toG}}\,\big(\forall R.\,p^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R}\rightarrow p^{C}(\text{unfix}\times g)\big)\\
- & =\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)^{C}(\text{unfix}\times g)\\
- & =g\triangleright(\psi_{\text{unfix}}^{C})^{\uparrow F}\quad.
-\end{align*}
-We note that $\psi_{\text{unfix}}^{C}$ is the identity function ($\text{id}^{:C\rightarrow C}$)
-because it is the unique $F$-coalgebra morphism of type $C\rightarrow C$
-by Statement~\ref{subsec:Statement-greatest-fixpoint-Church-encoding-morphism}.
-It follows that:
+The type $X\rightarrow X\rightarrow X$ was found during expansion
+of the recursive type $G^{X}$ as:
\[
-\text{toG}\,(\text{fromG}\,(g))=g\triangleright(\psi_{\text{unfix}}^{C})^{\uparrow F}=g\triangleright\text{id}^{\uparrow F}=g\quad.
+G^{X}=X+(X\rightarrow(X+(X\rightarrow(X+...))))\quad.
\]
-
-To prove item \textbf{(2)}, apply both sides to a type $R$ and a
-value $p^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow R}$:
+So, the pair $\left(n=2,k=1\right)$ corresponds to the function $q_{2,1}^{X}:G^{X}$
+written as:
\begin{align*}
-{\color{greenunder}\text{expect to equal }k^{R}(p):}\quad & \big(\text{fromG}\,(\text{toG}\,(k))\big)^{R}(p)=p^{C}(\text{unfix}\times\text{toG}\,(k))\\
- & =p^{C}\big(\text{unfix}\times k^{G^{C}}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)\big)\quad.
+ & q_{2,1}^{X}:X+(X\rightarrow(X+(X\rightarrow(X+(X\rightarrow G^{X})))))\quad,\\
+ & q_{2,1}^{X}\triangleq\bbnum 0^{:X}+(x_{1}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{2}^{:X}\rightarrow(x_{1}+\bbnum 0^{:X\rightarrow G^{X}}))))\quad.
\end{align*}
-To proceed, we need to use the naturality law of $k$:
-\[
-\text{for all }Q,R,f^{:Q\rightarrow R},q^{:\forall A.\,(A\rightarrow F^{A})\times G^{A}\rightarrow Q}:\quad k^{R}(\forall A.\:q^{A}\bef f)=f(k^{Q}(q))\quad.
-\]
-Setting the following parameters in this law:
+In a similar way, we define the functions $q_{n,k}$ for any $1\le k\le n$:
\[
-Q=G^{C}\quad,\quad\quad f=t^{:G^{C}}\rightarrow p^{C}(\text{unfix}\times t)\quad,\quad q=\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\quad,
+q_{n,k}^{X}\triangleq\bbnum 0^{:X}+(x_{1}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{2}^{:X}\rightarrow...\rightarrow(\bbnum 0^{:X}+(x_{n}^{:X}\rightarrow(x_{k}+\bbnum 0^{:X\rightarrow G^{X}})))...)))\quad.
\]
-we obtain:
+To make this code description rigorous, let us define $u_{i,n,k}$
+and $v_{i,n}$ like this:
\begin{align*}
- & k^{R}(\forall A.\:u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F}))\\
- & =p^{C}\big(\text{unfix}\times k^{G^{C}}\big(\forall A.\,u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow g\triangleright(\psi_{u}^{A})^{\uparrow F}\big)\big)\quad.
+ & u_{i,n,k}\triangleq\bbnum 0^{:X}+(x_{i}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{i+1}^{:X}\rightarrow...\rightarrow(x_{n}^{:X}\rightarrow(x_{k}+\bbnum 0^{:X\rightarrow G^{X}}))...))),\\
+ & v_{i,n}(x_{0})\triangleq\bbnum 0^{:X}+(x_{i}^{:X}\rightarrow(\bbnum 0^{:X}+(x_{i+1}^{:X}\rightarrow...\rightarrow(x_{n}^{:X}\rightarrow(x_{0}+\bbnum 0^{:X\rightarrow G^{X}}))...))).
\end{align*}
-We expect the left-hand side to equal $k^{R}(p)$, so the remaining
-difference is:
+These formulas hold for $1\le i\le k\le n$. An inductive definition
+of $q_{n,k}^{X}$, $u_{i,n,k}$, and $v_{i,n}$ is:
\begin{align*}
- & p\overset{?}{=}\forall A.\:u^{:A\rightarrow F^{A}}\times g^{:G^{A}}\rightarrow p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F})\quad,\\
-{\color{greenunder}\text{or equivalently}:}\quad & p^{A}(u^{:A\rightarrow F^{A}}\times g^{:G^{A}})\overset{?}{=}p^{C}(\text{unfix}\times g\triangleright(\psi_{u}^{A})^{\uparrow F})\quad.
+ & q_{n,k}^{X}=u_{1,n,k}\quad,\quad\quad u_{i,n,k}:G^{X}\quad,\quad\quad v_{i,n}:X\rightarrow G^{X}\quad,\\
+{\color{greenunder}\text{for }1\le i m.flatMap { x_2 => pure(x_1) } }
+\end{lstlisting}
+This code can be rewritten as a functor block, making its logic more
+visually clear:
+\begin{lstlisting}
+def h_2_1(m: M[X]): M[X] = for {
+ x_1 <- m
+ x_2 <- m
+} yield x_1
+\end{lstlisting}
+The code runs two effects of \lstinline!m! but returns the first
+value (\lstinline!x_1!), ignoring \lstinline!x_2!.
-\subsubsection{Statement \label{subsec:Statement-nested-greatest-fixpoints}\ref{subsec:Statement-nested-greatest-fixpoints}}
+Now we can generalize the code pattern from $h_{2,1}$ to $h_{n,k}$
+and write symbolically:
+\begin{lstlisting}
+def h_n_k(m: M[X]): M[X] = for {
+ x_1 <- m
+ x_2 <- m
+ ...
+ x_n <- m
+} yield x_k
+\end{lstlisting}
-For any bifunctor $F$, the following equivalence holds:
+To prove that this is indeed the correct code for $h_{n,k}^{M}(m)$,
+we need to use induction in $n$. We rewrite $q_{n,k}^{X}=u_{1,n,k}$
+and compute $\text{run}_{E}^{R,X}(p)(q_{n,k})=\text{run}_{E}^{R,X}(p)(u_{1,n,k})$.
+Using the code of $\text{run}_{E}$, we obtain the following inductive
+code definitions:
+\begin{align*}
+{\color{greenunder}\text{for }1\le i (A, Int)
+val q: M[M[Unit]] = { s => ( { t => ((), s + 1) }, s) }
+\end{lstlisting}
+\[
+M^{A}\triangleq\text{Int}\rightarrow A\times\text{Int}\quad,\quad\quad q:M^{M^{\bbnum 1}}\quad,\quad q\triangleq s^{:\text{Int}}\rightarrow(\_^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}})\times s\quad.
+\]
+For more intuition, let us express \lstinline!q! via the \lstinline!State!
+monad operations \lstinline!get! and \lstinline!set!:
+\begin{lstlisting}
+val get: M[Int] = s => (s, s)
+val set: Int => M[Unit] = x => s => ((), x)
+// Assuming that map and flatMap are defined for M:
+val q: M[M[Unit]] = for {
+ s <- get
+} yield set(s + 1)
+\end{lstlisting}
+Now we compute the two sides of the composition law, step by step.
+First, we will use Scala\textsf{'}s functor block syntax. The \lstinline!flatten!
+method can be written as:
+\begin{lstlisting}
+def flatten[A](mm: M[M[A]]): M[A] = for {
+ m <- mm
+ x <- m
+} yield x
+\end{lstlisting}
+Substituting the value \lstinline!q! defined above, we get:
+\begin{lstlisting}
+val flatten_q: M[Unit] = for { // This is flatten(q).
+ m <- for {
+ s <- get
+ } yield set(s + 1)
+ x <- m
+} yield x
+\end{lstlisting}
+Eliminate the nested \lstinline!for! and obtain:
+\begin{lstlisting}
+val flatten_q: M[Unit] = for {
+ s <- get
+ m = set(s + 1)
+ x <- m
+} yield x
+\end{lstlisting}
+Or equivalently (as the returned value is always a unit value):
+\begin{lstlisting}
+val flatten_q: M[Unit] = for {
+ s <- get
+ _ <- set(s + 1)
+} yield ()
+\end{lstlisting}
+Applying \lstinline!h_n_k! to this value means writing code of the
+form:
+\begin{lstlisting}
+val h_flatten_q: M[Unit] = for {
+ x_1 <- flatten_q
+ ...
+ x_n <- flatten_q
+} yield x_k
+\end{lstlisting}
+The returned value in \lstinline!x_k! is in any case the unit value,
+so let us focus on the state updates. Each \lstinline!flatten_q!
+has the effect of reading a state value \lstinline!s! and storing
+the incremented value \lstinline!s + 1!. The function \lstinline!h_n_k!
+repeats $n$ times the effect of \lstinline!flatten_q!. This increments
+the state $n$ times. So, the left-hand side of the law becomes:
+\begin{lstlisting}
+val lhs: M[Unit] = for { // This is h_flatten_q === h_n_k(flatten(q)).
+ s <- get
+ _ <- set(s + n)
+} yield ()
+\end{lstlisting}
+
+Turning now to the right-hand side of the law, we write the first
+sub-expression ($q\triangleright h_{n,k}^{\uparrow M}$, or in Scala,
+\lstinline!q.map(h_n_k)!) as the following Scala code:
+\begin{lstlisting}
+val q_map_h: M[M[Unit]] = for {
+ m <- q
+} yield h_n_k(m)
+\end{lstlisting}
+Substituting the code of \lstinline!q! (but not yet expanding \lstinline!h_n_k!),
+we find:
+\begin{lstlisting}
+val q_map_h: M[M[Unit]] = for {
+ s <- get
+} yield h_n_k(set(s + 1))
+\end{lstlisting}
+The function call \lstinline!h_n_k(set(s + 1))! repeats $n$ times
+the effect of \lstinline!set(s + 1)!, but \lstinline!s! is a fixed
+value in that scope, so the result is equal to just a single effect:
+\begin{lstlisting}
+val q_map_h: M[M[Unit]] = for {
+ s <- get
+} yield set(s + 1)
+\end{lstlisting}
+This is the same value as \lstinline!q! itself.
+The next sub-expression is \lstinline!h_n_k(q_map_h)!, which equals
+\lstinline!h_n_k(q)!:
+\begin{lstlisting}
+val h_q_map_h: M[M[Unit]] = for {
+ x_1 <- q
+ ...
+ x_n <- q
+} yield x_k
+\end{lstlisting}
+Substituting the code for \lstinline!q!, we get:
+\begin{lstlisting}
+val h_q_map_h: M[M[Unit]] = for {
+ x_1 <- for {
+ s <- get
+ } yield set(s + 1)
+ ...
+ x_n <- for {
+ s <- get
+ } yield set(s + 1)
+} yield x_k
+\end{lstlisting}
+Eliminate the nested \lstinline!for! and obtain:
+\begin{lstlisting}
+val h_q_map_h: M[M[Unit]] = for {
+ s <- get
+ x_1 = set(s + 1)
+ ...
+ s <- get
+ x_n = set(s + 1)
+} yield x_k
+\end{lstlisting}
+The code runs $n$ times the effect of \lstinline!get! but actually
+never runs the effect of \lstinline!set!: the \emph{unevaluated}
+effectful value \lstinline!set(s + 1)! is merely assigned to each
+\lstinline!x_i! and then returned under a monad wrapper. So, the
+code shown above for \lstinline!h_q_map_h! can be simplified to just
+a single \lstinline!get!:
+\begin{lstlisting}
+val h_q_map_h: M[M[Unit]] = for {
+ s <- get
+} yield set(s + 1)
+\end{lstlisting}
+This is again just equal to \lstinline!q!.
-\subsubsection{Statement \label{subsec:Statement-mutually-recursive-greatest-fixpoints}\ref{subsec:Statement-mutually-recursive-greatest-fixpoints}}
+It remains to apply \lstinline!flatten! to \lstinline!h_q_map_h!,
+which is the same as \lstinline!flatten(q)! and was already computed
+as \lstinline!flatten_q! above:
+\begin{lstlisting}
+val rhs: M[Unit] = for { // This is flatten(h_q_map_h) === flatten(q).
+ s <- get
+ _ <- set(s + 1)
+} yield ()
+\end{lstlisting}
-Given any bifunctors $F$, $G$, define $T$ and $U$ as the simultaneous
-greatest fixpoints of two type equations:
-\[
-T=F^{T,U}\quad,\quad\quad U=G^{T,U}\quad.
-\]
-Then the types $T$ and $U$ can be expressed as:
+The left-hand side and the right-hand side of the law differ only
+in the \lstinline!set! operation (\lstinline!set(s + n)! vs.~\lstinline!set(s + 1)!).
+So, they are equal only when $n=1$ (that is, for \lstinline!h_1_1!).
+It follows that, for all $n\ge2$ and for all $1\le k\le n$, the
+function $h_{n,k}$ of type $M^{X}\rightarrow M^{X}$ violates the
+composition law of monad morphisms when applied to the chosen value
+$q:M^{M^{X}}$.
+
+Let us now summarize this derivation in code notation. The left-hand
+side of the composition law is:
\begin{align*}
- & T\cong\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times A\quad,\\
- & U\cong\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times B\quad.
+ & \text{ftn}_{M}(q)=s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}}\quad,\\
+ & h_{n,k}(\text{ftn}_{M}(q))=s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+n)^{:\text{Int}}\quad.
\end{align*}
+Here we used the fact that $h_{n,k}(m)$ repeats $n$ times the effect
+of $m$ (and that effect increments the value $s$).
-
-\subparagraph{Proof}
-
-If $T$ and $U$ are fixed (and equal to the correct greatest fixpoints)
-then we can write:
-\[
-T=\nu A.\,F^{A,U}\quad,\quad\quad U=\nu B.\,G^{T,B}\quad.
-\]
-Now we can substitute $U$ into the equation for $T$:
-\[
-T=\nu A.\,F^{A,\,\nu B.\,G^{T,B}}\quad.
-\]
-The last line is a fixpoint equation involving only $T$, so we may
-express $T$ as the greatest fixpoint of that equation. Then we get:
+Turn to the right-hand side of the law and calculate:
\begin{align*}
- & T=\nu C.\,\nu A.\,F^{A,\,\nu B.\,G^{C,B}}\\
-{\color{greenunder}\text{use Statement~\ref{subsec:Statement-nested-greatest-fixpoints} and set }A=C:}\quad & \cong\gunderline{\nu A.}\,F^{A,\,\nu B.\,G^{A,B}}\\
-{\color{greenunder}\text{use Church encoding}:}\quad & \cong\exists A.\:(A\rightarrow F^{A,\,\nu B.\,G^{A,B}})\times A\\
-{\color{greenunder}\text{define }N^{A,C}\triangleq(A\rightarrow F^{A,C})\times A:}\quad & =\exists A.\:N^{A,\,\nu B.\,G^{A,B}}\\
-{\color{greenunder}\text{Church-co-Yoneda identity (Statement~\ref{subsec:Statement-Church-co-Yoneda})}:}\quad & \cong\gunderline{\exists A.\,\exists B.}\,(B\rightarrow G^{A,B})\times N^{A,B}\quad.
+ & q\triangleright h_{n,k}^{\uparrow M}=s^{:\text{Int}}\rightarrow(\_^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}})\times s=q\quad,\\
+ & h_{n,k}(q\triangleright h_{n,k}^{\uparrow M})=s^{:\text{Int}}\rightarrow(\_^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}})\times s=q\quad,\\
+ & \text{ftn}_{M}(q)=s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}}\quad.
\end{align*}
-Writing out the definition of $N^{A,B}$, we obtain the claimed Church
-encoding for $T$:
+The condition for the two sides of the law to be equal is:
\[
-T\cong\exists A.\,\exists B.\,(A\rightarrow F^{A,B})\times(B\rightarrow G^{A,B})\times A\quad.
+s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+n)^{:\text{Int}}\overset{?}{=}s^{:\text{Int}}\rightarrow1^{:\bbnum 1}\times(s+1)^{:\text{Int}}\quad.
\]
- The formula for $U$ is derived similarly. $\square$
+This holds only if $n=1$.
+
+It follows that $h_{1,1}$ (which is an identity function of type
+$M^{X}\rightarrow M^{X}$) is the only monad morphism that fits the
+required type. $\square$
-\chapter{Solutions of some exercises}
+\chapter{Solutions for selected exercises}
\addsec{Chapter \ref{chap:1-Values,-types,-expressions,}}
@@ -10382,7 +10604,9 @@ \subsubsection*{Exercise \ref{par:Exercise-mt-3-1}}
\hline A & \text{pu}_{M}\\
M^{A} & \text{id}\\
M^{N^{A}} & \gamma_{M}^{\uparrow M}\bef\text{ftn}_{M}
-\end{array}\quad,\\
+\end{array}\quad,
+\end{align*}
+\begin{align*}
{\color{greenunder}\text{right-hand side}:}\quad & \text{ftn}_{N}\bef\gamma_{M}=\,\begin{array}{|c||cc|}
& A & M^{A}\\
\hline A & \text{id} & \bbnum 0\\
@@ -10831,7 +11055,8 @@ \subsubsection*{Exercise \ref{subsec:Exercise-effectful-list-not-monad}}
\textbf{(b)} The code for the non-standard \lstinline!flatten! function
is:
\begin{lstlisting}[mathescape=true]
-def flatten[A](p: List[List[A]]): List[A] = p.takeWhile(_.nonEmpty).flatten // $\color{dkgreen}\textrm{ftn}_L$
+def flatten[A](p: List[List[A]]): List[A] =
+ p.takeWhile(_.nonEmpty).flatten // $\color{dkgreen}\textrm{ftn}_L$
\end{lstlisting}
The new \lstinline!flatten! function gives the same results as \lstinline!List!\textsf{'}s
standard \lstinline!flatten! method, except if one of the nested
@@ -10874,7 +11099,7 @@ \subsubsection*{Exercise \ref{subsec:Exercise-effectful-list-not-monad}}
\subsubsection*{Exercise \ref{subsec:Exercise-combined-codensity-monad}}
-\textbf{(a)} Denote for brevity $\text{Cod}_{F}^{M,A}\triangleq C^{A}$.
+\textbf{(a)} Denote for brevity $C^{A}\triangleq\text{Cod}_{F}^{M,A}$.
The naturality law for functions $c^{:C^{A}}$ says that for any $k^{:A\rightarrow F^{X}}$
and $q^{:X\rightarrow Y}$, we have:
\[
@@ -10916,17 +11141,18 @@ \subsubsection*{Exercise \ref{subsec:Exercise-combined-codensity-monad}}
\[
\text{ftn}_{M}^{\uparrow F}\bef\text{ftn}_{M}^{\uparrow F}\overset{?}{=}\text{ftn}_{M}^{\uparrow M\uparrow F}\bef\text{ftn}_{M}^{\uparrow F}\quad,
\]
-which follows from the associativity law of $\text{ftn}_{M}$.
+which disappears due to the associativity law of $\text{ftn}_{M}$.
-\textbf{(b)} The \lstinline!flatMap! method must have the type signature:
+\textbf{(b)} The \lstinline!flatMap! method of $P$ must have the
+type signature:
\[
-\text{flm}_{L}:\big((A\rightarrow X)\rightarrow M^{X}\big)\rightarrow(A\rightarrow(B\rightarrow X)\rightarrow M^{X})\rightarrow(B\rightarrow X)\rightarrow M^{X}\quad.
+\text{flm}_{P}:\big((A\rightarrow X)\rightarrow M^{X}\big)\rightarrow(A\rightarrow(B\rightarrow X)\rightarrow M^{X})\rightarrow(B\rightarrow X)\rightarrow M^{X}\quad.
\]
Choose $M^{A}\triangleq\bbnum 1+A$; now we need to implement the
type signature:
\begin{align*}
- & \text{flm}_{L}:\big((A\rightarrow X)\rightarrow\bbnum 1+X\big)\rightarrow\left(A\rightarrow(B\rightarrow X)\rightarrow\bbnum 1+X\right)\rightarrow(B\rightarrow X)\rightarrow\bbnum 1+X\quad,\\
- & \text{flm}_{L}\triangleq p^{:(A\rightarrow X)\rightarrow\bbnum 1+X}\rightarrow q^{:\left(A\rightarrow(B\rightarrow X)\rightarrow\bbnum 1+X\right)}\rightarrow r^{:B\rightarrow X}\rightarrow\text{???}^{:\bbnum 1+X}\quad.
+ & \text{flm}_{P}:\big((A\rightarrow X)\rightarrow\bbnum 1+X\big)\rightarrow\left(A\rightarrow(B\rightarrow X)\rightarrow\bbnum 1+X\right)\rightarrow(B\rightarrow X)\rightarrow\bbnum 1+X\quad,\\
+ & \text{flm}_{P}\triangleq p^{:(A\rightarrow X)\rightarrow\bbnum 1+X}\rightarrow q^{:\left(A\rightarrow(B\rightarrow X)\rightarrow\bbnum 1+X\right)}\rightarrow r^{:B\rightarrow X}\rightarrow\text{???}^{:\bbnum 1+X}\quad.
\end{align*}
Can this function ever return a value of type $\bbnum 0+X$? When
we try filling out the typed hole $\text{???}^{:\bbnum 1+X}$, we
@@ -10936,10 +11162,37 @@ \subsubsection*{Exercise \ref{subsec:Exercise-combined-codensity-monad}}
we have no available values of type $A$. We also cannot apply the
function $p$ since its argument is of type $A\rightarrow X$, but
we only have $A\rightarrow\bbnum 1+X$, which is not guaranteed to
-return nonempty values. So, the only way of implementing \lstinline!flatMap!
+return nonempty values. So, the only way of implementing $\text{flm}_{P}$
via fully parametric code is to return the constant value $1+\bbnum 0^{:X}$.
This would lose information and violate an identity law of monads.
+\textbf{(c)} In general, the type $\forall A.\,M^{A}\rightarrow\forall X.\,(A\rightarrow F^{X})\rightarrow F^{M^{X}}$
+is equivalent (via the contravariant Yoneda identity) to $\forall X.\,M^{F^{X}}\rightarrow F^{M^{X}}$.
+This cannot be implemented as a natural transformation for arbitrary
+monads $M$ and functors $F$.
+
+A simple counterexample is found with $M^{A}\triangleq R\rightarrow A$
+and $F^{A}\triangleq\bbnum 1+A$. Consider a function $f$ with the
+type signature of a monad morphism $\forall A.\,M^{A}\rightarrow\text{Cod}_{F}^{M,A}$
+with these $F$ and $M$:
+\[
+f:\forall A.\,(R\rightarrow A)\rightarrow\forall X.\,(A\rightarrow\bbnum 1+X)\rightarrow\bbnum 1+(R\rightarrow X)\quad.
+\]
+Can $f$ be a monad morphism? We can simplify the type of $f$ by
+using the covariant Yoneda identity:
+\begin{align*}
+ & \forall A.\,(R\rightarrow A)\rightarrow\forall X.\,(A\rightarrow\bbnum 1+X)\rightarrow\bbnum 1+(R\rightarrow X)\\
+ & \cong\forall X.\,(R\rightarrow\bbnum 1+X)\rightarrow\bbnum 1+(R\rightarrow X)\quad.
+\end{align*}
+A function of type $\forall X.\,(R\rightarrow\bbnum 1+X)\rightarrow\bbnum 1+(R\rightarrow X)$
+cannot make decisions based on its argument (of type $R\rightarrow\bbnum 1+X$)
+as $R$ and $X$ are unknown types. The function cannot always return
+$\bbnum 0+(R\rightarrow X)$ as the function of type $R\rightarrow\bbnum 1+X$
+could fail to return a value of type $X$ for some argument values
+$r^{:R}$. So, the function must always return $\bbnum 1+\bbnum 0^{:R\rightarrow X}$.
+But that code would lose information and fail the identity law of
+monad morphisms.
+
\addsec{Chapter \ref{chap:Summary-of-the}}
\subsubsection*{Exercise \ref{par:Exercise-additional-1-9}}
diff --git a/sofp-src/tex/sofp-applicative.tex b/sofp-src/tex/sofp-applicative.tex
index b150dc8e4..ab99b411a 100644
--- a/sofp-src/tex/sofp-applicative.tex
+++ b/sofp-src/tex/sofp-applicative.tex
@@ -795,10 +795,10 @@ \subsection{Single-traversal \texttt{fold} operations. I. Applicative \textquote
& \text{zip}_{\text{Fold}}:R\times\left(R\times Z\rightarrow R\right)\times S\times\left(S\times Z\rightarrow S\right)\rightarrow\left(R\times S\right)\times(R\times S\times Z\rightarrow R\times S)\quad.
\end{align*}
A fully parametric, information-preserving implementation of \lstinline!zipFold!
-(shown above) follows unambiguously from its type signature. So, let
-us use the \index{curryhoward library@\texttt{curryhoward} library}\lstinline!curryhoward!
+can be derived unambiguously from its type signature. So, let us use
+the \index{curryhoward library@\texttt{curryhoward} library}\lstinline!curryhoward!
library\footnote{See \texttt{\href{https://github.com/Chymyst/curryhoward}{https://github.com/Chymyst/curryhoward}}}
-to generate the code automatically:
+to generate the code automatically (equivalent code is shown above):
\begin{lstlisting}
import io.chymyst.ch._ // Import from the `curryhoward` library.
def zipFold[Z, R, S](op1: Fold[Z, R], op2: Fold[Z, S]): Fold[Z, (R, S)] = implement
@@ -1070,7 +1070,7 @@ \subsection{Parsing with applicative and monadic combinators\label{subsec:Parsin
a large parser out of smaller ones by using different functions (\textsf{``}combinators\textsf{''}).
We will now look at both applicative and monadic parser combinators.
-We will apply these parsing techniques to some toy \textsf{``}languages\textsf{''}.
+We will now apply these parsing techniques to some toy \textsf{``}languages\textsf{''}.
The first language encodes square roots of positive integers in an
XML-like format, as, for example, in the strings \lstinline!121!,
\lstinline!10000!, and \lstinline!123!.
@@ -1286,7 +1286,7 @@ \subsection{Parsing with applicative and monadic combinators\label{subsec:Parsin
filterable, monoidal, and other functionality for building up large
parsers from parts.
-\subsection{Functor block syntax for applicative functors}
+\subsection{Functor block syntax for applicative functors\label{subsec:Functor-block-syntax-for-applicative}}
It is often desirable to combine applicative and monadic computations
in a single functor block. This can be done by using \lstinline!zip!,
@@ -2204,7 +2204,39 @@ \subsection{Constructions of applicative functors\label{subsec:Constructions-of-
there will be two inequivalent implementations of \lstinline!zip!.
So, each monad construction gives at least one applicative construction.
We will focus on constructions that produce applicative functors and
-have no analogous monad constructions.
+do \emph{not} come from monad constructions. The results are summarized
+in Table~\ref{tab:Constructions-of-applicative-functors}.
+
+\begin{table}
+\begin{centering}
+\begin{tabular}{|c|c|c|}
+\hline
+\textbf{\small{}Construction} & \textbf{\small{}Type notation} & \textbf{\small{}Assumptions}\tabularnewline
+\hline
+\hline
+{\footnotesize{}fixed type} & {\footnotesize{}$F^{A}\triangleq Z$} & {\footnotesize{}$Z$ is a monoid}\tabularnewline
+\hline
+{\footnotesize{}identity} & {\footnotesize{}$F^{A}\triangleq A$} & {\footnotesize{}$F$ is commutative}\tabularnewline
+\hline
+{\footnotesize{}composition} & {\footnotesize{}$F^{A}\triangleq G^{H^{A}}$} & {\footnotesize{}$G$ and $H$ are applicative functors}\tabularnewline
+\hline
+{\footnotesize{}product} & {\footnotesize{}$F^{A}\triangleq P^{A}\times Q^{A}$} & {\footnotesize{}$P$ and $Q$ are applicative}\tabularnewline
+\hline
+{\footnotesize{}co-product} & {\footnotesize{}$F^{A}\triangleq Z+P^{A}$} & {\footnotesize{}$Z$ is a monoid and $P$ is applicative}\tabularnewline
+\hline
+{\footnotesize{}co-product} & {\footnotesize{}$F^{A}\triangleq P^{A}+Q^{A}$} & {\footnotesize{}conditions in Statement~\ref{subsec:Statement-co-product-with-co-pointed-applicative}}\tabularnewline
+\hline
+{\footnotesize{}co-product} & {\footnotesize{}$F^{A}\triangleq P^{A}+Q^{A}\times R^{A}$} & {\footnotesize{}$P$, $Q$ are polynomial and $R$ is applicative}\tabularnewline
+\hline
+{\footnotesize{}recursive type} & {\footnotesize{}$F^{A}\triangleq S^{A,F^{P^{A}}}$} & {\footnotesize{}$S$ and $P$ are polynomial}\tabularnewline
+\hline
+{\footnotesize{}recursive type} & {\footnotesize{}$F^{A}\triangleq P^{A}+Q^{A}\times R^{F^{A}}$} & {\footnotesize{}conditions in Statement~\ref{subsec:Statement-applicative-recursive-type-1}}\tabularnewline
+\hline
+\end{tabular}
+\par\end{centering}
+\caption{Constructions of applicative functors.\label{tab:Constructions-of-applicative-functors}}
+\end{table}
+
\paragraph{Type parameters}
@@ -3306,7 +3338,10 @@ \subsubsection{Statement \label{subsec:Statement-applicative-recursive-type-1}\r
functor if the standard definition of \lstinline!zip! is used. Nevertheless,
the associativity and the commutativity laws hold for \lstinline!zip!.
The absence of a well-defined value \lstinline!wu! does not lead
-to practical disadvantages when working with finite lists.
+to practical disadvantages when working with lists. (To make \lstinline!List!
+a lawful applicative functor, one can use a \textsf{``}padding\textsf{''} version
+of \lstinline!zip!\index{padding zip@padding \texttt{zip}} as shown
+in Exercise~\ref{subsec:Exercise-applicative-I-1-1-1}.)
For certain choices of $F$, $G$, and $H$, the functor $L$ will
be a monad. It is important that the implementation of applicative
@@ -3321,8 +3356,8 @@ \subsubsection{Statement \label{subsec:Statement-applicative-recursive-type-1}\r
method (returning an infinite list of values, as we just saw).
There exist other recursive constructions that produce lawful applicative
-functors. For instance, one could assume an \textsf{``}biapplicative bifunctor\textsf{''}
-$P$ having a \lstinline!bizip! method with this type signature:
+functors. For instance, assume a \textsf{``}biapplicative bifunctor\textsf{''} $P$
+having a \lstinline!bizip! method with this type signature:
\[
\text{bizip}_{P}^{A,B,F}:P^{A,F^{A}}\times P^{B,F^{B}}\rightarrow P^{A\times B,F^{A}\times F^{B}}\quad(\text{for all functors }F)\quad.
\]
@@ -3472,7 +3507,36 @@ \subsubsection{Definition \label{subsec:Definition-applicative-contrafunctor}\re
\end{align*}
The rest of this section proves some constructions that produce lawful
-applicative contrafunctors.
+applicative contrafunctors. The results are summarized in Table~\ref{tab:Constructions-of-applicative-contrafunctors}.
+
+\begin{table}
+\begin{centering}
+\begin{tabular}{|c|c|c|}
+\hline
+\textbf{\small{}Construction} & \textbf{\small{}Type notation} & \textbf{\small{}Assumptions}\tabularnewline
+\hline
+\hline
+{\footnotesize{}fixed type} & {\footnotesize{}$F^{A}\triangleq Z$} & {\footnotesize{}$Z$ is a monoid}\tabularnewline
+\hline
+{\footnotesize{}identity} & {\footnotesize{}$F^{A}\triangleq A$} & {\footnotesize{}$F$ is commutative}\tabularnewline
+\hline
+{\footnotesize{}composition} & {\footnotesize{}$F^{A}\triangleq G^{H^{A}}$} & {\footnotesize{}$G$ is an appl.~functor, $H$ is an appl.~contrafunctor}\tabularnewline
+\hline
+{\footnotesize{}product} & {\footnotesize{}$F^{A}\triangleq P^{A}\times Q^{A}$} & {\footnotesize{}$P$ and $Q$ are applicative contrafunctors}\tabularnewline
+\hline
+{\footnotesize{}co-product} & {\footnotesize{}$F^{A}\triangleq P^{A}+Q^{A}$} & {\footnotesize{}$P$ and $Q$ are applicative contrafunctors}\tabularnewline
+\hline
+{\footnotesize{}function type} & {\footnotesize{}$F^{A}\triangleq P^{A}\rightarrow Q^{A}$} & {\footnotesize{}$P$ is any functor, $Q$ is an applicative contrafunctor}\tabularnewline
+\hline
+{\footnotesize{}recursive type} & {\footnotesize{}$F^{A}\triangleq S^{A,F^{P^{A}}}$} & {\footnotesize{}$S$ and $P$ are polynomial}\tabularnewline
+\hline
+{\footnotesize{}recursive type} & {\footnotesize{}$F^{A}\triangleq P^{A}+Q^{A}\times R^{F^{A}}$} & {\footnotesize{}conditions in Statement~\ref{subsec:Statement-applicative-recursive-type-1}}\tabularnewline
+\hline
+\end{tabular}
+\par\end{centering}
+\caption{Constructions of applicative contrafunctors.\label{tab:Constructions-of-applicative-contrafunctors}}
+\end{table}
+
\paragraph{Type parameters}
@@ -4013,7 +4077,33 @@ \subsubsection{Example \label{subsec:Example-profunctor-pure-not-equivalent}\ref
\]
The rest of this section proves some constructions that produce lawful
-applicative profunctors.
+applicative profunctors and are not equivalent to previously shown
+constructions of applicative functors or contrafunctors. The results
+are summarized in Table~\ref{tab:Constructions-of-applicative-profunctors}.
+
+\begin{table}
+\begin{centering}
+\begin{tabular}{|c|c|c|}
+\hline
+\textbf{\small{}Construction} & \textbf{\small{}Type notation} & \textbf{\small{}Assumptions}\tabularnewline
+\hline
+\hline
+{\footnotesize{}composition} & {\footnotesize{}$F^{A}\triangleq G^{H^{A}}$} & {\footnotesize{}$G$ is an applicative functor, $H$ is an applicative
+profunctor}\tabularnewline
+\hline
+{\footnotesize{}product} & {\footnotesize{}$F^{A}\triangleq P^{A}\times Q^{A}$} & {\footnotesize{}$P$ and $Q$ are applicative profunctors}\tabularnewline
+\hline
+{\footnotesize{}co-product} & {\footnotesize{}$F^{A}\triangleq Z+Q^{A}$} & {\footnotesize{}$Z$ is a monoid type}\tabularnewline
+\hline
+{\footnotesize{}co-product} & {\footnotesize{}$F^{A}\triangleq P^{A}+Q^{A}$} & {\footnotesize{}conditions of Statement~\ref{subsec:Statement-applicative-profunctor-co-product-2}}\tabularnewline
+\hline
+{\footnotesize{}function type} & {\footnotesize{}$F^{A}\triangleq P^{A}\rightarrow Q^{A}$} & {\footnotesize{}$P$ is any functor, $Q$ is an applicative profunctor}\tabularnewline
+\hline
+\end{tabular}
+\par\end{centering}
+\caption{Constructions of applicative profunctors.\label{tab:Constructions-of-applicative-profunctors}}
+\end{table}
+
\subsubsection{Statement \label{subsec:Statement-applicative-profunctor-composition}\ref{subsec:Statement-applicative-profunctor-composition}}
@@ -4556,12 +4646,13 @@ \subsubsection{Statement \label{subsec:Statement-applicative-profunctor-exponent
Note that the functor $H$ must be \emph{covariant} in the last construction
($P^{A}\triangleq H^{A}\rightarrow G^{A}$). Otherwise, the profunctor
-$P$ will not be applicative even in simple cases such as $P^{A}\triangleq H^{A}\rightarrow A$.
-(We omit the proof of that statement.)
+$P$ is not guaranteed to be applicative even in simple cases such
+as $P^{A}\triangleq H^{A}\rightarrow A$. (We omit the proof of that
+statement.)
\section{Discussion and further developments}
-\subsection{Equivalence of typeclass methods with laws}
+\subsection{Equivalence of lawful typeclass methods}
In this and the previous chapters, we have seen that certain typeclass
methods are equivalent. The equivalence of \lstinline!map2!, \lstinline!zip!,
@@ -4581,10 +4672,10 @@ \subsection{Equivalence of typeclass methods with laws}
A function $\text{pu}_{F}:A\rightarrow F^{A}$ satisfying a naturality
law is equivalent to a value $\text{wu}_{F}:F^{\bbnum 1}$.
-After seeing those detailed proofs, we can now clarify the meaning
-of equivalence of typeclass methods when we require some laws to hold.
-The goal of this subsection is to find a rigorous formulation of that
-equivalence.
+After seeing those detailed proofs, we can now clarify what it means
+for two typeclass methods to be \textsf{``}equivalent\textsf{''} when we require some
+laws to hold. The goal of this subsection is to find a rigorous formulation
+of that equivalence.
In each case seen so far, we have two functions with two different
type signatures (usually with type parameters), and we assume that
@@ -4597,7 +4688,7 @@ \subsection{Equivalence of typeclass methods with laws}
example, the type signature \lstinline!pure[A]: A => F[A]! (in the
type notation, $\text{pu}_{F}:\forall A.\,A\rightarrow F^{A}$) gives
rise to the naturality law $f\bef\text{pu}_{F}=\text{pu}_{F}\bef f^{\uparrow F}$.
-In Scala code, this law is written as \lstinline!pure(f(x)) == pure(x).map(f)!.
+In Scala code, this law is written as the \textsf{``}code equation\textsf{''} \lstinline!pure(f(x)) == pure(x).map(f)!.
What we have proved in Section~\ref{subsec:Pointed-functors-motivation-equivalence}
is a one-to-one correspondence between two \emph{sets}: the set of
@@ -5204,8 +5295,7 @@ \subsection{The pattern of \textquotedblleft functorial\textquotedblright{} type
\hline
\end{tabular}
\par\end{centering}
-\caption{Some typeclasses that follow the functorial pattern.}
-\label{tab:functorial-typeclasses}
+\caption{Some typeclasses that follow the functorial pattern.\label{tab:functorial-typeclasses}}
\end{table}
We\index{typeclass!functorial pattern} call \textbf{functorial} all
@@ -5213,30 +5303,24 @@ \subsection{The pattern of \textquotedblleft functorial\textquotedblright{} type
remind us that there exists a certain (categorical) functor at the
core of the typeclass. Having defined that functor, we can derive
the methods and the laws of the typeclass via the following steps:
-\begin{enumerate}
-\item Define each category\textsf{'}s composition operation and identity morphism.
-\item Verify that the category laws hold.
-\item Write the type signature of the \textsf{``}lifting\textsf{''} method corresponding
+
+1) Define each category\textsf{'}s composition operation and identity morphism.
+
+2) Verify that the category laws hold.
+
+3) Write the type signature of the \textsf{``}lifting\textsf{''} method corresponding
to the functor.
-\item Impose the naturality laws and the functor laws on the \textsf{``}lifting\textsf{''}
+
+4) Impose the naturality laws and the functor laws on the \textsf{``}lifting\textsf{''}
method.
-\item Derive other typeclass methods (and their laws) from the \textsf{``}lifting\textsf{''}
+
+5) Derive other typeclass methods (and their laws) from the \textsf{``}lifting\textsf{''}
method and its laws.
-\end{enumerate}
-Let us go through this pattern for the applicative functor typeclass
-studied in this chapter. Following the functorial pattern, we say
-that a covariant type constructor $F$ is applicative if there exists
-a (categorical) functor between the $F$-ap and $F$-lifted categories.
-The morphisms of the $F$-ap category are values of type $F^{A\rightarrow B}$;
-the morphisms of the $F$-lifted category are values of type $F^{A}\rightarrow F^{B}$.
-This is all we need to start with. All other properties of applicative
-functors are then derived in a systematic way. With this approach,
-we do not need to memorize the complicated type signatures and laws
-of the methods \lstinline!map2! and \lstinline!ap!.
-
-The first step is to define the $F$-ap category\textsf{'}s morphisms. We
-define identity morphisms (\lstinline!wid[A]! of type $F^{A\rightarrow A}$)
-and the composition operation ($\odot$) that composes $F^{A\rightarrow B}$
+
+Let us go through this pattern for the applicative functor typeclass.
+The first step is to define the $F$-ap category. We define identity
+morphisms (\lstinline!wid[A]! of type $F^{A\rightarrow A}$) and
+the composition operation ($\odot$) that composes $F^{A\rightarrow B}$
with $F^{B\rightarrow C}$ to obtain $F^{A\rightarrow C}$. The second
step is to verify that the category laws hold with those definitions;
this is done in Statement~\ref{subsec:Statement-ap-category-laws}.
@@ -5255,8 +5339,11 @@ \subsection{The pattern of \textquotedblleft functorial\textquotedblright{} type
suitable laws are equivalent to \lstinline!ap! (see Section~\ref{subsec:Equivalence-of-map2-zip-ap}
and Statement~\ref{subsec:Statement-ap-functor-laws}).
-In this way, we derive the applicative typeclass by following the
-functorial typeclass pattern.
+In this way, we rediscover the applicative typeclass by following
+the functorial typeclass pattern. All other properties of applicative
+functors are derived in a systematic way. With this approach, we do
+not need to memorize the complicated type signatures and laws of the
+methods \lstinline!map2! and \lstinline!ap!.
Many typeclasses can be derived from this pattern, but some cannot.
For example, applicative contrafunctors (Section~\ref{sec:Applicative-contrafunctors-and-profunctors})
@@ -5278,10 +5365,10 @@ \subsubsection{Exercise \label{subsec:Exercise-applicative-II-4-2}\ref{subsec:Ex
\subsubsection{Exercise \label{subsec:Exercise-applicative-I-1-1-1}\ref{subsec:Exercise-applicative-I-1-1-1}}
-Implement a \textsf{``}padding\textsf{''} \lstinline!zip! method for lists such that
-the shorter list is padded with the \emph{last} value until its length
-is equal to that of the longer list. Zipping with an empty list returns
-again an empty list. A sample test:
+Implement a \textsf{``}padding\textsf{''} \lstinline!zip! method\index{padding zip@padding \texttt{zip}}
+for lists such that the shorter list is padded with its \emph{last}
+value until its length is equal to that of the longer list. Zipping
+with an empty list returns again an empty list. A sample test:
\begin{lstlisting}
def paddingZip[A, B](left: List[A], right: List[B]): List[(A, B)] = ???
@@ -5294,6 +5381,25 @@ \subsubsection{Exercise \label{subsec:Exercise-applicative-I-1-1-1}\ref{subsec:E
Prove that the laws of \lstinline!zip! hold for \lstinline!paddingZip!
with a suitable \lstinline!wu!.
+\subsubsection{Exercise \label{subsec:Exercise-applicative-I-concatenating-zip}\ref{subsec:Exercise-applicative-I-concatenating-zip}}
+
+Implement a \textsf{``}concatenating\textsf{''} \lstinline!zip! method\index{concatenating zip@concatenating \texttt{zip}}
+for lists. The first value in the first list is repeated until the
+second list is finished; then the last value in the second list is
+repeated until the first list is finished. Zipping with an empty list
+returns again an empty list. A sample test:
+\begin{lstlisting}
+def concatenatingZip[A, B](left: List[A], right: List[B]): List[(A, B)] = ???
+
+scala> concatenatingZip(List(1, 2, 3), List("a", "b", "c", "d"))
+res0: List[(Int, String)] = List((1, "a"), (1, "b"), (1, "c"), (1, "d"), (2, "d"), (3, "d"))
+
+scala> concatenatingZip(List(), List(1, 2, 3))
+res1: List[(Unit, Int)] = List()
+\end{lstlisting}
+Prove that the laws of \lstinline!zip! hold for \lstinline!concatenatingZip!
+with a suitable \lstinline!wu!.
+
\subsubsection{Exercise \label{subsec:Exercise-applicative-II-4}\ref{subsec:Exercise-applicative-II-4}}
Show that $F^{A}\triangleq G^{A}+H^{G^{A}}$ is a lawful applicative
@@ -5411,7 +5517,7 @@ \subsubsection{Exercise \label{subsec:Exercise-profunctor-pure-not-equivalent-1}
\textbf{(a)} Show that $P$ is pointed: there exist a value \lstinline!wu!
of type $P^{\bbnum 1}$ and a method \lstinline!pure! of type $A\rightarrow P^{A}$.
-\textbf{(b)} Show that the type of fully parametric functions $\text{pu}_{P}:A\rightarrow P^{A}$
+\textbf{(b)} Show that the type of fully parametric functions $\text{pu}_{P}:\forall A.\,A\rightarrow P^{A}$
is \emph{not} equivalent to the type $P^{\bbnum 1}$.
\begin{comment}
diff --git a/sofp-src/tex/sofp-back-cover-no-bg.tex b/sofp-src/tex/sofp-back-cover-no-bg.tex
index d82b24deb..11a826bc5 100644
--- a/sofp-src/tex/sofp-back-cover-no-bg.tex
+++ b/sofp-src/tex/sofp-back-cover-no-bg.tex
@@ -25,10 +25,10 @@
practical applications of parametricity.
Long and difficult, yet boring explanations are logically
-developed in excruciating detail through 1982
+developed in excruciating detail through 1995
Scala code snippets, 233 statements with step-by-step
-derivations, 105 diagrams, 237 examples
-with tested Scala code, and 315 exercises. Discussions
+derivations, 105 diagrams, 239 examples
+with tested Scala code, and 317 exercises. Discussions
build upon each chapter\textsf{'}s material further.
Beginners in FP will find tutorials about the \texttt{map}/\texttt{reduce}
diff --git a/sofp-src/tex/sofp-disjunctions.tex b/sofp-src/tex/sofp-disjunctions.tex
index e86719a14..3651bcc41 100644
--- a/sofp-src/tex/sofp-disjunctions.tex
+++ b/sofp-src/tex/sofp-disjunctions.tex
@@ -188,9 +188,9 @@ \subsection{Case classes with type parameters}
s: MySockX[Int] = MySockX(10.5,white,123)
\end{lstlisting}
Because the value \lstinline!123! has type \lstinline!Int!, the
-type parameter \lstinline!A! in \lstinline!MySockX[A]! was automatically
-set to the type \lstinline!Int!. The result has type \lstinline!MySockX[Int]!.
-The programmer does not need to specify that type explicitly.
+compiler has automatically set the type parameter \lstinline!A! in
+\lstinline!MySockX[A]! to the type \lstinline!Int!. The result has
+type \lstinline!MySockX[Int]!.
Each time we create a value of type \lstinline!MySockX!, a specific
type will have to be used instead of the type parameter \lstinline!A!.
@@ -210,8 +210,12 @@ \subsection{Case classes with type parameters}
\end{lstlisting}
This function is defined for all types \lstinline!A! at once, because
its code works in the same way regardless of what \lstinline!A! is.
-Scala will set the type parameter \lstinline!A! automatically when
-we apply \lstinline!fits! to an argument:
+(In this simple example, \lstinline!fits! does not actually use the
+value of type \lstinline!A! stored inside \lstinline!MySockX!; but
+another function might.)
+
+The type parameter \lstinline!A! is set automatically when we apply
+\lstinline!fits! to an argument:
\begin{lstlisting}
scala> fits(MySockX(10.5, "blue", List(1, 2, 3))) // Using MySockX[List[Int]].
res0: Boolean = true
@@ -331,8 +335,8 @@ \subsection{Tuples with one part and with zero parts}
Other than that, \lstinline!case class C()! and \lstinline!case object C!
have the same meaning: a named tuple with zero parts, which we may
also view as a \textsf{``}named \lstinline!Unit!\index{unit type!named}\textsf{''}
-type. This book will not use \lstinline!case object!s because \lstinline!case class!es
-are sufficient.
+type. For this book\textsf{'}s purposes, case classes are sufficient and case
+objects are not needed.
\subsection{Pattern matching for case classes}
diff --git a/sofp-src/tex/sofp-essay3.tex b/sofp-src/tex/sofp-essay3.tex
index 072a3ae3a..288a05bd5 100644
--- a/sofp-src/tex/sofp-essay3.tex
+++ b/sofp-src/tex/sofp-essay3.tex
@@ -109,10 +109,11 @@
There exist books intended as presentations of category theory for
computer scientists\footnote{See, e.g., \texttt{\href{https://www.amazon.com/dp/0262660717}{https://www.amazon.com/dp/0262660717}}
-or \texttt{\href{https://www.math.mcgill.ca/triples/Barr-Wells-ctcs.pdf}{https://www.math.mcgill.ca/triples/Barr-Wells-ctcs.pdf}}} or for programmers.\footnote{\texttt{\href{https://github.com/hmemcpy/milewski-ctfp-pdf}{https://github.com/hmemcpy/milewski-ctfp-pdf}}}
+or the manuscript \textsf{``}Basic category theory for computing science\textsf{''}:
+\texttt{\href{https://www.math.mcgill.ca/triples/Barr-Wells-ctcs.pdf}{https://www.math.mcgill.ca/triples/Barr-Wells-ctcs.pdf}}} or for programmers.\footnote{\texttt{\href{https://github.com/hmemcpy/milewski-ctfp-pdf}{https://github.com/hmemcpy/milewski-ctfp-pdf}}}
However, those books do not cover certain concepts relevant to programming,
-such as applicative\footnote{Applicative functors are known in mathematics as \textsf{``}monoidal\textsf{''}: \texttt{\href{https://en.wikipedia.org/wiki/Monoidal_functor}{https://en.wikipedia.org/wiki/Monoidal\_functor}}}
-or traversable functors. Instead, those books dwell on concepts (e.g.,
+such as applicative\footnote{Applicative functors are known in mathematics as \textsf{``}monoidal\textsf{''}: for
+example, see \texttt{\href{https://en.wikipedia.org/wiki/Monoidal_functor}{https://en.wikipedia.org/wiki/Monoidal\_functor}}} or traversable functors. Instead, those books dwell on concepts (e.g.,
limits, enriched categories, topoi) that have no applications in practical
functional programming today.
@@ -364,8 +365,8 @@
correct types, and also that all return values have the expected types.
To each programming language of that kind, there corresponds\footnote{Academically minded computer scientists say that this definition of
-a \textsf{``}types/functions\textsf{''} category is insufficiently rigorous. See the
-discussion in \texttt{\href{https://math.andrej.com/2016/08/06/hask-is-not-a-category/}{https://math.andrej.com/2016/08/06/hask-is-not-a-category/}}} a \textsf{``}types/functions\textsf{''} category:
+a \textsf{``}types and functions\textsf{''} category is insufficiently rigorous. See
+the discussion in \texttt{\href{https://math.andrej.com/2016/08/06/hask-is-not-a-category/}{https://math.andrej.com/2016/08/06/hask-is-not-a-category/}}} a category of \textsf{``}types and functions\textsf{''}:
\begin{itemize}
\item The objects of the category are all the data types supported by the
language (including user-defined data types). As an example, for Scala
@@ -667,7 +668,7 @@ \subsection*{Monadic endofunctors}
array of $25$ values.
The Scala library contains such a function, named \lstinline!flatMap!.
-An example of usage is:
+An example of usage:
\begin{lstlisting}
scala> (1 to 10).toArray.flatMap(x => 1 to x / 2)
res0: Array[Int] = Array(1, 1, 1, 2, 1, 2, 1, 2, 3, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 5)
diff --git a/sofp-src/tex/sofp-filterable.tex b/sofp-src/tex/sofp-filterable.tex
index cbb6ecdbd..a177f4e12 100644
--- a/sofp-src/tex/sofp-filterable.tex
+++ b/sofp-src/tex/sofp-filterable.tex
@@ -3686,7 +3686,7 @@ \subsection{Constructions of filterable contrafunctors\label{subsec:Construction
\caption{Constructions of filterable contrafunctors.\label{tab:Constructions-of-filterable-contrafunctors}}
\end{table}
-The \lstinline!Filterable! typeclass is a $P$-typeclass (see Section~\ref{subsec:P-typeclasses})
+The \lstinline!Filterable! typeclass is an $FM$-typeclass (see Section~\ref{subsec:P-typeclasses})
if formulated via \lstinline!filter! or via \lstinline!liftOpt!,
because those methods return the type $C^{A}$ itself. So, we expect
that the product, the exponential, and the recursive constructions
diff --git a/sofp-src/tex/sofp-free-type.tex b/sofp-src/tex/sofp-free-type.tex
index 92ae842f6..163576e44 100644
--- a/sofp-src/tex/sofp-free-type.tex
+++ b/sofp-src/tex/sofp-free-type.tex
@@ -154,13 +154,13 @@ \subsection{Stage 1: unevaluated expression trees}
\subsection{Stage 2: implementing type safety in the DSLs}
-The two DSLs defined in the previous section are not fully type-checked\index{type checking}
-at compile time. This becomes clear by looking at the DSL program
-\lstinline!prgFile! shown in the previous section. The code of \lstinline!runFile!
-assumes that the \lstinline!Read! operation is always applied to
-a \lstinline!Path!. However, this assumption is not enforced by the
-DSL. When composing a larger DSL program from separately defined parts,
-one could by mistake create an invalid DSL program such as \lstinline!Read(Read(Val("file")))!
+The two DSLs defined in the previous section are not type-safe.\index{type safety}
+This becomes clear by looking at the DSL program \lstinline!prgFile!
+shown in the previous section. The code of \lstinline!runFile! assumes
+that the \lstinline!Read! operation is always applied to a \lstinline!Path!.
+However, this assumption is not enforced by the DSL. When composing
+a larger DSL program from separately defined parts, one could by mistake
+create an invalid DSL program such as \lstinline!Read(Read(Val("file")))!
where the \lstinline!Read! operation is used incorrectly. Running
this program causes a run-time error:
\begin{lstlisting}
@@ -169,12 +169,11 @@ \subsection{Stage 2: implementing type safety in the DSLs}
\end{lstlisting}
The Scala compiler cannot verify that we are using the DSL correctly.
It would be better if the invalid DSL program \lstinline!Read(Read(Val("file")))!
-failed to compile. To achieve that, it would help to have different
-Scala types for DSL programs returning a \lstinline!String! and a
-\lstinline!Path!. So, let us replace the type \lstinline!PrgFile!
-by a type constructor \lstinline!PrgFile[A]!, representing a DSL
-program that will return a value of type \lstinline!A! when we run
-it:
+failed to compile. To achieve that, we need to have different Scala
+types for DSL programs returning a \lstinline!String! or a \lstinline!Path!.
+So, we replace the type \lstinline!PrgFile! by a type constructor
+\lstinline!PrgFile[A]!, which means a DSL program that will return
+a value of type \lstinline!A! when we run it:
\begin{lstlisting}
import java.nio.file.{Path => JPath}
import java.nio.file.{Files, Paths}
@@ -212,11 +211,11 @@ \subsection{Stage 2: implementing type safety in the DSLs}
that assumption. Both arguments of the \lstinline!Rotate! operation
are values of type \lstinline!PrgComplex!, and so the Scala compiler
is unable to verify that the DSL is being used correctly. If the programmer
-uses a plain complex number (\lstinline!Val!) instead of a \lstinline!Phase!
-value, the program will return an incorrect result \emph{without}
-any indication of error:
+uses \lstinline!Rotate! with a \lstinline!Val! instead of a \lstinline!Phase!,
+the program will return an incorrect result \emph{without} any indication
+of error:
\begin{lstlisting}
-val prgComplex3: PrgComplex = Rotate(prgComplex1, Val(Complex(0, 1))) // Forgot Phase()!
+val prgComplex3: PrgComplex = Rotate(prgComplex1, Val(Complex(0, 1)))
scala> runComplex(prgComplex3) // The result is incorrect, but there is no error message!
res5: Complex = Complex(11.0, -2.0)
@@ -230,11 +229,11 @@ \subsection{Stage 2: implementing type safety in the DSLs}
of the case classes are:
\begin{lstlisting}
sealed trait PrgComplex[A]
-final case class Val(c: Complex) extends PrgComplex[Complex]
+final case class Val(c: Complex) extends PrgComplex[Complex]
final case class Add(p1: PrgComplex[Complex], p2: PrgComplex[Complex]) extends PrgComplex[Complex]
final case class Mul(p1: PrgComplex[Complex], p2: PrgComplex[Complex]) extends PrgComplex[Complex]
-final case class Conj(p: PrgComplex[Complex]) extends PrgComplex[Complex]
-final case class Phase(p: PrgComplex[Complex]) extends PrgComplex[Double]
+final case class Conj(p: PrgComplex[Complex]) extends PrgComplex[Complex]
+final case class Phase(p: PrgComplex[Complex]) extends PrgComplex[Double]
final case class Rotate(p: PrgComplex[Complex], a: Phase) extends PrgComplex[Complex]
\end{lstlisting}
The revised code of \lstinline!runComplex! is clearer because phases
@@ -249,8 +248,8 @@ \subsection{Stage 2: implementing type safety in the DSLs}
case Rotate(p, alpha) => runComplex(p).rotate(runComplex(alpha))
}
\end{lstlisting}
-The example programs, \lstinline!prgComplex1! and \lstinline!prgComplex2!,
-do not change except for their type:
+The example programs (\lstinline!prgComplex1! and \lstinline!prgComplex2!)
+remain unchanged except for their types:
\begin{lstlisting}
val prgComplex1: PrgComplex[Complex] = Conj(Mul(Val(Complex(1, 2)), Val(Complex(3, -4))))
@@ -262,13 +261,13 @@ \subsection{Stage 2: implementing type safety in the DSLs}
scala> runComplex(prgComplex2)
res7: Complex = Complex(x = 2.000000000000001, y = 11.0)
\end{lstlisting}
-Since \lstinline!Rotate! now requires a \lstinline!PrgComplex[Double]!,
-forgetting to use \lstinline!Phase! will cause a type error:
+Since \lstinline!Rotate! now requires a \lstinline!Phase!, forgetting
+to use \lstinline!Phase! will be a type error:
\begin{lstlisting}
scala> val prgComplex3 = Rotate(prgComplex1, Val(Complex(0, 1)))
:1: type mismatch;
found : Val
- required: PrgComplex[Double]
+ required: Phase
case Phase(p) => runComplex(p)
^
Compilation Failed
@@ -295,17 +294,17 @@ \subsection{Stage 3: implementing bound variables}
val result = if (Files.exists(p)) new String(Files.readAllBytes(p)) else "No file."
\end{lstlisting}
Trying to translate the above code to the \lstinline!PrgFile! DSL,
-we find that we need to set the Scala variable \lstinline!p! to the
-path computed by a previous operation. Here is a first attempt:
+we find that we need to set the variable \lstinline!p! to the path
+computed by a previous operation. A first attempt is:
\begin{lstlisting}
val p: JPath = runFile(Path(Val("config_location.txt")))
val prg: PrgFile[String] = if (Files.exists(p)) Read(p) else Val("No file.")
\end{lstlisting}
-There are two problems with this code. The first problem is that \lstinline!Read(p)!
-does not compile because the argument of \lstinline!Read! should
-be a \lstinline!PrgFile[JPath]! rather than just a \lstinline!JPath!.
-To solve this problem, we generalize the \lstinline!Val! class to
-hold values of arbitrary type:
+There are two problems with this code. First, \lstinline!Read(p)!
+does not compile: the argument of \lstinline!Read! should be a \lstinline!PrgFile[JPath]!
+rather than just a \lstinline!JPath!. To fix this, we add a type
+parameter to the \lstinline!Val! case class, now supporting values
+of any type:
\begin{lstlisting}
final case class Val[A](a: A) extends PrgFile[A]
\end{lstlisting}
@@ -321,8 +320,8 @@ \subsection{Stage 3: implementing bound variables}
To solve this problem, we introduce a new DSL operation that binds
Scala variables to values returned by other DSL operations. A standard
way of creating \index{bound variable}bound variables is by using
-those variables as arguments of nameless functions. So, let us consider
-the nameless function:
+arguments of nameless functions. So, let us consider the following
+nameless function:
\begin{lstlisting}
{ p => if (Files.exists(p)) Read(Val(p)) else Val("No file.") }
\end{lstlisting}
@@ -353,8 +352,8 @@ \subsection{Stage 3: implementing bound variables}
final case class Bind[A, B](pa: PrgFile[B])(f: B => PrgFile[A]) extends PrgFile[A]
\end{lstlisting}
-After adding the \lstinline!Bind!-handling code to the runner, the
-implementation of the DSL is:
+After adding the \lstinline!Bind!-handling code to the runner, we
+get:
\begin{lstlisting}
sealed trait PrgFile[A]
final case class Val[A](a: A) extends PrgFile[A]
@@ -382,7 +381,7 @@ \subsection{Stage 3: implementing bound variables}
\end{lstlisting}
Because the type parameter \lstinline!B! is already fixed, the argument
\lstinline!p! may be written without a type annotation (in this case,
-it would have been \lstinline!p:JPath!). This makes the DSL easier
+it would have been \lstinline!p: JPath!). This makes the DSL easier
to use. However, the underlying implementation becomes more complicated.
Scala\textsf{'}s pattern matching syntax is limited to the first curried argument.
So, the second curried argument of \lstinline!Bind! needs a \lstinline!val!
@@ -397,7 +396,7 @@ \subsection{Stage 3: implementing bound variables}
to use values computed by other parts. Since a \lstinline!Bind! value
contains a \emph{Scala function} (of type \lstinline!B => PrgFile[A]!),
that function may run arbitrary Scala code, not limited to DSL operations,
-in order to compute a result of type \lstinline!PrgFile[A]!. All
+as it computes its result value of type \lstinline!PrgFile[A]!. All
non-DSL code is enclosed inside a \lstinline!Bind! and will be evaluated
only when the DSL program is run:
\begin{lstlisting}
@@ -405,7 +404,7 @@ \subsection{Stage 3: implementing bound variables}
res8: String = "version = 1"
\end{lstlisting}
As before, a value of type \lstinline!PrgFile[A]! describes a computation
-but does not execute it.
+but does not run it.
\subsection{Stage 4: refactoring to a monadic DSL}
@@ -418,10 +417,10 @@ \subsection{Stage 4: refactoring to a monadic DSL}
def flatMap[B](f: A => PrgFile[B]): PrgFile[B] = Bind(this)(f)
def map[B](f: A => B): PrgFile[B] = flatMap(f andThen PrgFile.pure)
}
-final case class Val[A](a: A) extends PrgFile[A]
+final case class Val[A](a: A) extends PrgFile[A]
final case class Bind[A, B](pa: PrgFile[B])(val f: B => PrgFile[A]) extends PrgFile[A]
-final case class Path(p: PrgFile[String]) extends PrgFile[JPath]
-final case class Read(p: PrgFile[JPath]) extends PrgFile[String]
+final case class Path(p: PrgFile[String]) extends PrgFile[JPath]
+final case class Read(p: PrgFile[JPath]) extends PrgFile[String]
object PrgFile {
def pure[A](a: A): PrgFile[A] = Val(a)
@@ -488,13 +487,12 @@ \subsection{Stage 4: refactoring to a monadic DSL}
but that argument is a function that in any case cannot be meaningfully
printed.
-Typically, a monadic DSL program is a nested case class containing
-some function that, when called, will return further nested case classes
-and functions, etc. All those functions are waiting to be called;
-no side effects have been run yet. The actual business logic and side
-effects will be executed only when the \lstinline!run! method is
-applied. At that time, the entire DSL program will be converted into
-a result value.
+Typically, a monadic DSL program is a case class containing some functions
+that, when called, will return further nested case classes or functions.
+All those functions are waiting to be called; no side effects have
+been run yet. The actual business logic and side effects will be executed
+only when the \lstinline!run! method is applied. After that, we will
+get the result value of the entire DSL program.
\subsection{Stage 5: refactoring to reuse common code\label{subsec:Stage-5:-refactoring-monadDSL}}
@@ -509,13 +507,13 @@ \subsection{Stage 5: refactoring to reuse common code\label{subsec:Stage-5:-refa
def pure[A](a: A): PrgComplex[A] = Val(a)
}
-final case class Val[A](a: A) extends PrgComplex[A]
+final case class Val[A](a: A) extends PrgComplex[A]
final case class Bind[A, B](pa: PrgComplex[B])(val f: B => PrgComplex[A]) extends PrgComplex[A]
-final case class Add(x: Complex, y: Complex) extends PrgComplex[Complex]
-final case class Mul(x: Complex, y: Complex) extends PrgComplex[Complex]
-final case class Conj(x: Complex) extends PrgComplex[Complex]
-final case class Phase(p: Complex) extends PrgComplex[Double]
-final case class Rotate(p: Complex, p: Phase) extends PrgComplex[Complex]
+final case class Add(x: Complex, y: Complex) extends PrgComplex[Complex]
+final case class Mul(x: Complex, y: Complex) extends PrgComplex[Complex]
+final case class Conj(x: Complex) extends PrgComplex[Complex]
+final case class Phase(p: Complex) extends PrgComplex[Double]
+final case class Rotate(p: Complex, p: Phase) extends PrgComplex[Complex]
def runComplex[A]: PrgComplex[A] => A = {
case Val(a) => a
@@ -562,12 +560,12 @@ \subsection{Stage 5: refactoring to reuse common code\label{subsec:Stage-5:-refa
// The case classes are changed to:
final case class Val[A](a: A) extends PrgFile[A]
final case class Bind[A, B](pa: PrgFile[B])(val f: B => PrgFile[A]) extends PrgFile[A]
-final case class Op[A](op: PrgFileC[A]) extends PrgFile[A] // Wrap custom operations.
+final case class Op[A](op: PrgFileC[A]) extends PrgFile[A] // Custom operation.
def runFile[A]: PrgFile[A] => A = {
case Val(a) => a
case bind@Bind(pa) => runFile(bind.f(runFile(pa)))
- case Op(op) => runFileC(op) // Run the custom operation and get the result.
+ case Op(op) => runFileC(op) // Run a custom operation.
}
\end{lstlisting}
@@ -577,18 +575,18 @@ \subsection{Stage 5: refactoring to reuse common code\label{subsec:Stage-5:-refa
// The case classes are changed to:
final case class Val[A](a: A) extends PrgComplex[A]
final case class Bind[A, B](pa: PrgComplex[B])(val f: B => PrgComplex[A]) extends PrgComplex[A]
-final case class Op[A](op: PrgComplexC[A]) extends PrgComplex[A] // Wrap custom operations.
+final case class Op[A](op: PrgComplexC[A]) extends PrgComplex[A] // Custom operation.
def runComplex[A]: PrgComplex[A] => A = {
case Val(a) => a
case bind@Bind(pa) => runComplex(bind.f(runComplex(pa)))
- case Op(op) => runComplexC(op) // Run the custom operation and get the result.
+ case Op(op) => runComplexC(op) // Run a custom operation.
}
sealed trait PrgComplexC[A]
-final case class Add(x: Complex, y: Complex) extends PrgComplexC[Complex]
-final case class Mul(x: Complex, y: Complex) extends PrgComplexC[Complex]
-final case class Conj(x: Complex) extends PrgComplexC[Complex]
-final case class Phase(p: Complex) extends PrgComplexC[Double]
+final case class Add(x: Complex, y: Complex) extends PrgComplexC[Complex]
+final case class Mul(x: Complex, y: Complex) extends PrgComplexC[Complex]
+final case class Conj(x: Complex) extends PrgComplexC[Complex]
+final case class Phase(p: Complex) extends PrgComplexC[Double]
final case class Rotate(p: Complex, alpha: Phase) extends PrgComplexC[Complex]
def runComplexC[A]: PrgComplexC[A] => A = {
@@ -607,11 +605,11 @@ \subsection{Stage 5: refactoring to reuse common code\label{subsec:Stage-5:-refa
The effect constructor and its runner encapsulate the entire domain-specific
logic. The code in the classes \lstinline!PrgComplex! and \lstinline!PrgFile!
is only concerned with providing the monadic functionality to the
-DSL. We can replace those two classes by a single class (called, say,
-\lstinline!MonadDSL!) that takes the effect constructor as a \emph{type
-parameter} \lstinline!F!. Since the type parameter \lstinline!F!
-is itself a type constructor, we must declare it via the Scala syntax
-\lstinline!F[_]!. The code is:
+DSL. We can replace those two classes by a single class (called \lstinline!MonadDSL!)
+that takes the effect constructor as a \emph{type parameter} \lstinline!F!.
+Since the type parameter \lstinline!F! is itself a type constructor,
+we must declare it via the Scala syntax \lstinline!F[_]!. The code
+is:
\begin{lstlisting}
sealed trait MonadDSL[F[_], A] {
def flatMap[B](f: A => MonadDSL[F, B]): MonadDSL[F, B] = Bind(this)(f)
@@ -717,10 +715,9 @@ \subsection{Stage 5: refactoring to reuse common code\label{subsec:Stage-5:-refa
\subsection{A first recipe for monadic DSLs\label{subsec:A-first-recipe-monadic-dsl}}
-The previous section gave motivation for defining the type constructor
-\lstinline!MonadDSL[F[_], A]!. That type constructor is called the
-\textsf{``}free monad on \lstinline!F!\textsf{''}, for reasons explained later in
-this chapter. The full code is:
+The previous section motivated defining the type constructor \lstinline!MonadDSL[F[_], A]!.
+That type constructor is known as the \textsf{``}free monad on \lstinline!F!\textsf{''},
+for reasons explained later in this chapter. The full code is:
\begin{lstlisting}
sealed trait MonadDSL[F[_], A] {
def flatMap[B](f: A => MonadDSL[F, B]): MonadDSL[F, B] = Bind(this)(f)
@@ -795,8 +792,8 @@ \subsection{A first recipe for monadic DSLs\label{subsec:A-first-recipe-monadic-
cannot be a functor because it is impossible to create values of type
\lstinline!PrgFileC[A]! with an arbitrary type \lstinline!A! (the
type \lstinline!A! must be either \lstinline!JPath! or \lstinline!String!).
-However, in some cases the effect constructor \lstinline!F! could
-be itself a lawful functor.
+However, in other cases the effect constructor \lstinline!F! could
+be a lawful functor.
Next, we implement an \textsf{``}effect runner\textsf{''} \index{effect runner}for
\lstinline!F!. An \textbf{effect runner} for an effect constructor
@@ -911,8 +908,8 @@ \subsection{A first recipe for monadic DSLs\label{subsec:A-first-recipe-monadic-
\end{lstlisting}
The resulting code creates fewer nested case classes in memory.
-Unlike other laws, the right identity law already holds for any value
-\lstinline!p! of type \lstinline!MonadDSL[F, A]!:
+The right identity law already holds for any value \lstinline!p!
+of type \lstinline!MonadDSL[F, A]!:
\begin{lstlisting}
p.flatMap(f andThen MonadDSL.pure) == p.map(f)
\end{lstlisting}
@@ -1000,18 +997,18 @@ \subsection{Running a DSL program into another monad}
DSL with a different set of operations and its own effect runner that
works more efficiently or supports a different run-time environment.
-\section{Different encodings of the free monad}
+\section{Different encodings of the free monad\label{sec:Different-encodings-of-free-monad}}
\subsection{Motivation\label{subsec:Motivation-free-monad-different-encodings}}
The type \lstinline!MonadDSL[F, A]! is called a \textbf{free monad}
-on\index{free monad} the type constructor \lstinline!F!. The word
-\textsf{``}free\textsf{''} indicates that \lstinline!MonadDSL! is free of any domain-specific
-code. We may view \lstinline!MonadDSL[F, A]! as a wrapper that adds
-the monad\textsf{'}s functionality to any type constructor \lstinline!F! and
-creates a new monadic DSL based on \lstinline!F!\textsf{'}s operations. The
-construction uses \lstinline!F! as a type parameter, and so it works
-equally well with every \lstinline!F!.
+on\index{free monad} the type constructor \lstinline!F!. For intuition,
+one may say that \lstinline!MonadDSL! is \textsf{``}free of\textsf{''} any domain-specific
+code. The wrapper type \lstinline!MonadDSL[F, A]! adds the functionality
+of a monad to any type constructor \lstinline!F! and creates a new
+monadic DSL based on \lstinline!F!\textsf{'}s operations. The construction
+uses \lstinline!F! as a \emph{type parameter}, and so it works equally
+well with every \lstinline!F!.
A monad must support the methods \lstinline!pure!, \lstinline!flatMap!,
and \lstinline!map!. The effect constructor \lstinline!F! will not
@@ -1043,7 +1040,7 @@ \subsection{Motivation\label{subsec:Motivation-free-monad-different-encodings}}
abstract class Free1[F[_]: Functor, T] {
def flatMap[A](f: T => Free1[F, A]): Free1[F, A] = this match {
case Pure(t) => f(t)
- case Flatten(p) => Flatten(p.map(g => g.flatMap(f))) // Use F\textsf{'}s Functor instance.
+ case Flatten(p) => Flatten(p.map(g => g.flatMap(f))) // Use the Functor instance for F.
}
}
final case class Pure[F[_]: Functor, T](t: T) extends Free1[F, T]
@@ -1065,7 +1062,7 @@ \subsection{Motivation\label{subsec:Motivation-free-monad-different-encodings}}
\end{lstlisting}
In 2016, K.~Robinson\index{Kelley Robinson} gave a talk\footnote{See \texttt{\href{https://www.slideshare.net/KelleyRobinson1/why-the-free-monad-isnt-free-61836547}{https://www.slideshare.net/KelleyRobinson1/why-the-free-monad-isnt-free-61836547}}}
-where the code for the free monad looked like this:
+showing the following code for the free monad:
\begin{lstlisting}
sealed trait Free3[F[_], T] {
def flatMap[A](f: T => Free3[F, A]): Free3[F, A] = FlatMap(this, f)
@@ -1084,14 +1081,15 @@ \subsection{Motivation\label{subsec:Motivation-free-monad-different-encodings}}
However, \lstinline!Free1! and \lstinline!Free2! have different
data in their case classes and are not obviously equivalent to each
other (or to \lstinline!Free3!). We call these implementations \textbf{encodings}\index{free monad!encodings}
-of the free monad. The different codes implement the same idea (turning
-a type constructor \lstinline!F! into a monad) in different ways.
+of the free monad. The different codes implement the same idea: turn
+a type constructor \lstinline!F! formally into a monad by adding
+some case classes.
To figure out how to use those codes in practice, a programmer might
ask:
\begin{itemize}
-\item Are these encodings equivalent (given that \lstinline!Free2! has
-2 case classes and \lstinline!Free3! has 3)?
+\item Are these encodings equivalent (even though \lstinline!Free2! has
+2 case classes while \lstinline!Free3! has 3)? What are the differences?
\item Are there any other encodings of the free monad?
\item What laws should an encoding satisfy in order to be considered \textsf{``}correct\textsf{''}?
\item These encodings convert an arbitrary type constructor \lstinline!F!
@@ -1105,20 +1103,20 @@ \subsection{Motivation\label{subsec:Motivation-free-monad-different-encodings}}
\subsection{The raw tree encoding\label{subsec:The-raw-tree-encoding-of-the-free-monad}}
-To understand the relationships between the encodings of the free
-monad, let us first examine how the code of \lstinline!MonadDSL!
-(or equivalently \lstinline!Free3!) implements the \lstinline!map!
-method. In \lstinline!MonadDSL!, we implemented \lstinline!map!
-through \lstinline!flatMap!. As a result, our code for the \lstinline!map!
-method is not similar to the code of the two other monadic methods
-(\lstinline!pure! and \lstinline!flatMap!) that merely create new
-values of the case classes \lstinline!Val! and \lstinline!Bind!
-without performing any computations.
+To understand the relationship between the encodings of the free monad,
+let us first examine how the code of \lstinline!MonadDSL! (or equivalently
+\lstinline!Free3!) implements the \lstinline!map! method. In \lstinline!MonadDSL!,
+we implemented \lstinline!map! through \lstinline!flatMap!. As a
+result, our code for the \lstinline!map! method is\emph{ }not exactly
+similar to the code of the two other monadic methods (\lstinline!pure!
+and \lstinline!flatMap!) that merely wrap their arguments in new
+case classes (\lstinline!Val! and \lstinline!Bind!) without performing
+any computations.
We could implement \lstinline!map! in a similar way if we added a
new case class, say \lstinline!FMap!, to \lstinline!MonadDSL!. The
-result is a new encoding that we will call \lstinline!Free4! (since
-it uses $4$ case classes):
+result is a new encoding called \lstinline!Free4! (as it uses $4$
+case classes):
\begin{lstlisting}
sealed trait Free4[F[_], A] {
def flatMap[B](f: A => Free4[F, B]): Free4[F, B] = Bind4(this, f)
@@ -1127,10 +1125,10 @@ \subsection{The raw tree encoding\label{subsec:The-raw-tree-encoding-of-the-free
object Free4 {
def pure[F[_], A](a: A): Free4[F, A] = Val(a)
}
-final case class Val[F[_], A](a: A) extends Free4[F, A]
-final case class Bind4[F[_], A, B](pa: Free4[F, B], f: B => Free4[F, A]) extends Free4[F, A]
-final case class FMap[F[_], A, B](pa: Free4[F, B], f: B => A) extends Free4[F, A]
-final case class Op[F[_], A](op: F[A]) extends Free4[F, A] // Wrap domain-specific operations.
+final case class Val[F[_], A](a: A) extends Free4[F, A]
+final case class Bind4[F[_], A, B](pa: Free4[F, B], f: B => Free4[F, A]) extends Free4[F, A]
+final case class FMap[F[_], A, B](pa: Free4[F, B], f: B => A) extends Free4[F, A]
+final case class Op[F[_], A](op: F[A]) extends Free4[F, A]
\end{lstlisting}
The code of the runners needs to be revised accordingly:
\begin{lstlisting}
@@ -1149,12 +1147,12 @@ \subsection{The raw tree encoding\label{subsec:The-raw-tree-encoding-of-the-free
\end{lstlisting}
The code of \lstinline!Free4!\textsf{'}s methods \lstinline!map!, \lstinline!flatMap!,
-and \lstinline!pure! merely wraps the arguments of each method into
+and \lstinline!pure! simply wraps the arguments of each method into
a case class without performing any computations with those arguments.
We call \lstinline!Free4! the \textbf{raw tree encoding}\index{free monad!raw tree encoding}
of the free monad. The name \textsf{``}raw tree\textsf{''} means that a DSL program
-is a completely unevaluated expression tree that uses a new nested
-case class for each step of a computation.
+is a completely unevaluated expression tree where each DSL operation
+is represented by a new nested case class.
\subsection{Comparing the reduced encodings of the free monad}
@@ -1284,11 +1282,11 @@ \subsection{Comparing the reduced encodings of the free monad}
case classes (\lstinline!Pure3!, \lstinline!Suspend!, and \lstinline!FlatMap!).
The \lstinline!Return! case class corresponds to \lstinline!Pure3!.
Trying to replace \lstinline!Bind! by \lstinline!FlatMap!, we find
-that the type of their data are not the same: the first part of \lstinline!Bind!
+that the types of their data are not the same: the first part of \lstinline!Bind!
has type \lstinline!F[A]! while the first part of \lstinline!FlatMap!
has type \lstinline!Free3[F, A]!. We note that \lstinline!Suspend!
-converts \lstinline!F[A]! into \lstinline!Free3[F, A]!. So, we write
-the code of \lstinline!free2toFree3! like this:
+converts \lstinline!F[A]! into \lstinline!Free3[F, A]!. So, the
+code of \lstinline!free2toFree3! becomes:
\begin{lstlisting}
def free2toFree3[F[_], A]: Free2[F, A] => Free3[F, A] = {
case Return(a) => Pure3(a)
@@ -1297,8 +1295,8 @@ \subsection{Comparing the reduced encodings of the free monad}
\end{lstlisting}
The inverse conversion function (\lstinline!free3toFree2!) is more
-complicated because \lstinline!Suspend! and \lstinline!FlatMap!
-are not straightforwardly mapped into \lstinline!Free2!\textsf{'}s case classes.
+complicated because the case classes \lstinline!Suspend! and \lstinline!FlatMap!
+are not directly mapped into \lstinline!Free2!\textsf{'}s case classes.
\begin{lstlisting}
def free3toFree2[F[_], A]: Free3[F, A] => Free2[F, A] = {
case Pure3(a) => Return(a)
@@ -1363,7 +1361,7 @@ \subsection{Comparing the reduced encodings of the free monad}
There are injective maps from smaller encodings to larger ones, and
surjective maps from larger to smaller encodings.
-\subsection{Types with existential quantifiers}
+\subsection{Types with existential quantifiers\label{subsec:Types-with-existential-quantifiers}}
The previous section showed all derivations in the Scala code syntax
rather than in the code notation. The reason is that the constructions
@@ -1625,9 +1623,9 @@ \subsection{Types with existential quantifiers}
properties of free monads and other constructions. With the new notation
for existential types, the free monad constructions are written as:
\begin{align*}
-{\color{greenunder}\text{free monad on }F\text{ in a reduced encoding}:}\quad & \text{Free}_{2}^{F,T}\triangleq T+\exists A.\,F^{A}\times(A\rightarrow\text{Free}_{2}^{F,T})\quad,\\
-{\color{greenunder}\text{free monad on }F\text{ in a reduced encoding}:}\quad & \text{Free}_{3}^{F,T}\triangleq T+F^{T}+\exists A.\,\text{Free}_{3}^{F,A}\times(A\rightarrow\text{Free}_{3}^{F,T})\quad,\\
-{\color{greenunder}\text{free monad on }F\text{ in a raw tree encoding}:}\quad & \text{Free}_{4}^{F,A}\triangleq A+F^{A}+\exists B.\,\text{Free}_{4}^{F,B}\times(B\rightarrow A)\\
+{\color{greenunder}\text{reduced encoding, 2 case classes}:}\quad & \text{Free}_{2}^{F,T}\triangleq T+\exists A.\,F^{A}\times(A\rightarrow\text{Free}_{2}^{F,T})\quad,\\
+{\color{greenunder}\text{reduced encoding, 3 case classes}:}\quad & \text{Free}_{3}^{F,T}\triangleq T+F^{T}+\exists A.\,\text{Free}_{3}^{F,A}\times(A\rightarrow\text{Free}_{3}^{F,T})\quad,\\
+{\color{greenunder}\text{raw tree encoding}:}\quad & \text{Free}_{4}^{F,A}\triangleq A+F^{A}+\exists B.\,\text{Free}_{4}^{F,B}\times(B\rightarrow A)\\
& \quad\quad+\exists B.\,\text{Free}_{4}^{F,B}\times(B\rightarrow\text{Free}_{4}^{F,A})\quad.
\end{align*}
@@ -1650,9 +1648,10 @@ \subsection{Expressing existential quantifiers via universal quantifiers}
\textsf{``}external code\textsf{''} is the function \lstinline!toInt! shown in the
previous section. The type signature and the code of \lstinline!toInt!
is written in the type notation as:
-\[
-\text{toInt}:\left(\exists C.\,\text{Int}\times C\times(C\rightarrow\text{Int})\right)\rightarrow\text{Int}\quad,\quad\quad\text{toInt}\triangleq(\exists C.\,a^{:\text{Int}}\times c^{:C}\times p^{:C\rightarrow\text{Int}})\rightarrow a+p(c)\quad.
-\]
+\begin{align*}
+ & \text{toInt}:\left(\exists C.\,\text{Int}\times C\times(C\rightarrow\text{Int})\right)\rightarrow\text{Int}\quad,\\
+ & \text{toInt}\triangleq(\exists C.\,a^{:\text{Int}}\times c^{:C}\times p^{:C\rightarrow\text{Int}})\rightarrow a+p(c)\quad.
+\end{align*}
Generalizing from this example, we say that \textsf{``}code external to the
existential quantifier\textsf{''} means any function having an argument of
an existentially quantified type. For instance, this could be a function
@@ -1824,7 +1823,8 @@ \subsection{Free monad on a functor (\lstinline!Free1!)}
& \text{Free}_{1}^{F,T}\triangleq T+F^{\text{Free}_{1}^{F,T}}\quad,\\
& \text{Free}_{2}^{F,T}\triangleq T+\exists A.\,F^{A}\times(A\rightarrow\text{Free}_{2}^{F,T})\quad.
\end{align*}
-To proceed, we use the \textsf{``}covariant co-Yoneda identity\textsf{''} (Statement~\ref{subsec:Statement-co-Yoneda-two-identities}a
+To proceed, we use the \textsf{``}covariant co-Yoneda identity\textsf{''} (which we
+will prove as Statement~\ref{subsec:Statement-co-Yoneda-two-identities}a
in Appendix~\ref{app:Proofs-of-naturality-parametricity}):
\[
\exists A.\,(A\rightarrow R)\times F^{A}\cong F^{R}\quad.
@@ -1837,11 +1837,11 @@ \subsection{Free monad on a functor (\lstinline!Free1!)}
This type expression is the same as the definition of $\text{Free}_{1}^{F,T}$.
We have just shown that \lstinline!Free1! (which assumes that $F$
-is a functor) is equivalent to \lstinline!Free2! as type constructors.
-(Recall that the equivalence of \lstinline!Free2!, \lstinline!Free3!,
+is a functor) is equivalent at the level of types to \lstinline!Free2!.
+Recall that the equivalence of \lstinline!Free2!, \lstinline!Free3!,
and \lstinline!Free4! holds only after applying a runner to a free
monad value; the free monad encodings \lstinline!Free2!, \lstinline!Free3!,
-\lstinline!Free4! are \emph{not} equivalent as type constructors.)
+\lstinline!Free4! are \emph{not} equivalent as type constructors.
\section{Free constructions for other typeclasses}
@@ -1993,7 +1993,7 @@ \subsection{Expected properties of a free typeclass construction\label{sec:Expec
Substituting in that equation $P\triangleq M$ and $(S^{F})^{A}\triangleq\text{Free}_{4}^{F,A}\rightarrow M^{A}$,
we get the type equivalence:
\begin{align*}
- & \forall F^{\bullet}.\,\forall A.\,(\forall T.\,F^{T}\rightarrow M^{T})\rightarrow\text{Free}_{4}^{F,A}\rightarrow M^{A}\\
+ & \forall F.\,\forall A.\,(\forall T.\,F^{T}\rightarrow M^{T})\rightarrow\text{Free}_{4}^{F,A}\rightarrow M^{A}\\
& \quad\quad\cong\forall A.\,\text{Free}_{4}^{M,A}\rightarrow M^{A}\quad.
\end{align*}
The last line ($\text{Free}_{4}^{M,A}\rightarrow M^{A}$) is the type
@@ -2031,8 +2031,8 @@ \subsection{Expected properties of a free typeclass construction\label{sec:Expec
the \lstinline!Monad! typeclass. (Strictly speaking, the functions
of the form \lstinline!emap4(runner)! are \emph{not} monad morphisms:
Those functions do satisfy the monad morphism laws, but they are not
-maps between lawful monads, as $\text{Free}_{4}^{F,A}$ fails to obey
-the monad laws.)
+maps between lawful monads, as $\text{Free}_{4}^{F,A}$ violates the
+monad laws.)
We have derived the code of \lstinline!emap4! by applying \lstinline!run4M!
to a specific runner of type $\forall T.\,F^{T}\rightarrow\text{Free}_{4}^{G,T}$.
@@ -2056,10 +2056,10 @@ \subsection{Expected properties of a free typeclass construction\label{sec:Expec
value of type $M^{A}$ by translating \lstinline!Free4!\textsf{'}s operations
into the corresponding operations of the monad $M$.
-It turns out that the monad morphism laws of the runner and the free
-evaluator have far-reaching consequences for the theory of typeclasses
-with laws. For now, let us list the properties that are relevant for
-practical programming with free monads:
+It turns out that the laws of the runner and the free evaluator have
+far-reaching consequences for the theory of typeclasses with laws.
+For now, let us list the properties that are relevant for practical
+programming with free monads:
\begin{enumerate}
\item For a given monad $M$ and a fixed function \lstinline!runnerM!,
the function \lstinline!run4M(runnerM)! preserves the monad operations
@@ -2184,22 +2184,30 @@ \subsection{Expected properties of a free typeclass construction\label{sec:Expec
below.
We can now generalize the properties 1\textendash 4 to an arbitrary
-typeclass. Let $T$ be a type that does not belong to the typeclass,
-and denote the free typeclass instance constructed on $T$ by $\text{Free}^{T}$.
-We will formulate the expected properties in terms of the free evaluator
-(\lstinline!eval!) as its type signature is simpler than that of
-the universal runner:
+typeclass. Let $T$ be any type and denote a free typeclass instance
+constructed on $T$ by $\text{Free}^{T}$ (in any encoding). We formulate
+the expected properties in terms of the free evaluator (\lstinline!eval!)
+as its type signature is simpler than that of the universal runner:
\begin{enumerate}
+\item The type $\text{Free}^{T}$ is covariant with respect to $T$. For
+any $T$, the type $\text{Free}^{T}$ supports the typeclass operations
+(but may violate some typeclass laws). There exists a natural transformation
+$T\rightarrow\text{Free}^{T}$. For any $T$, $U$ and any $f:T\rightarrow U$,
+the function $f^{\uparrow\text{Free}}$ of type $\text{Free}^{T}\rightarrow\text{Free}^{U}$
+preserves the typeclass operations.
\item For a given type $M$ that belongs to a typeclass, the free evaluator
function (\lstinline!eval!) of type $\text{Free}^{M}\rightarrow M$
preserves the typeclass operations.
\item The free evaluator \lstinline!eval! is the \emph{only} possible function
of type $\text{Free}^{M}\rightarrow M$ that preserves the typeclass
operations.
-\item The constructor $\text{Free}^{T}$ is covariant with respect to $T$:
-For any two types constructors $T$ and $U$ and a map $f:T\rightarrow U$
-between them, there is a unique function of type $\text{Free}^{T}\rightarrow\text{Free}^{U}$
-that preserves the typeclass operations.
+\item The universal runner is defined through \lstinline!eval! as:
+\begin{align*}
+ & \text{run}:(T\rightarrow M)\rightarrow\text{Free}^{T}\rightarrow M\quad,\\
+ & \text{run}\,(f^{:T\rightarrow M})\triangleq f^{\uparrow\text{Free}}\bef\text{eval}\quad.
+\end{align*}
+For any $f$, the function $\text{run}\left(f\right)$ preserves the
+typeclass operations.
\item Any violations of the typeclass laws in a $\text{Free}^{T}$ program
will disappear once a runner is applied and a final value of type
$M$ is computed (as long as $M$ is a lawful typeclass instance).
@@ -2207,10 +2215,10 @@ \subsection{Expected properties of a free typeclass construction\label{sec:Expec
The following sections will show various free typeclass constructions.
We will not prove that those properties hold for those constructions.
Instead, Section~\ref{sec:Laws-of-free-constructions} will show
-general proofs that apply to all $P$-typeclasses and to all possible
-laws.
+general proofs that apply to all FM-typeclasses and to all possible
+choices of typeclass laws.
-\subsection{Free pointed type}
+\subsection{Free pointed type\label{subsec:Free-pointed-type}}
One of the simplest typeclasses is the \textbf{pointed}\index{pointed type}
type (a type that has a designated default value). This is the \lstinline!HasDefault!
@@ -2238,7 +2246,7 @@ \subsection{Free pointed type}
\text{FreeDefault}^{T}\triangleq\bbnum 1+T\quad.
\]
We find that \lstinline!FreeDefault[T]! is equivalent to \lstinline!Option[T]!,
-so we will define it that way:
+so we may write a simpler definition like this:
\begin{lstlisting}
type FreeDefault[T] = Option[T]
\end{lstlisting}
@@ -2247,7 +2255,7 @@ \subsection{Free pointed type}
\subsubsection{Definition \label{subsec:Definition-free-pointed-type}\ref{subsec:Definition-free-pointed-type}}
The \textbf{free pointed type} on\index{free pointed type} a given
-type $T$ is the type $\bbnum 1+T$.
+type $T$ is the type $\bbnum 1+T$. $\square$
The \lstinline!HasDefault! typeclass has no laws, so the raw tree
encoding ($\bbnum 1+T$) cannot be reduced by imposing any typeclass
@@ -2519,8 +2527,8 @@ \subsection{Free semigroup\label{subsec:Free-semigroup}}
surjective).
It is important to note that \lstinline!toNEL! preserves the semigroup
-operations (but \lstinline!fromNEL! does not!). It is a general property
-of free typeclass constructions that there is only one typeclass-preserving
+operations (but \lstinline!fromNEL! does \emph{not}). It is a general
+property of free typeclass constructions that there is only one typeclass-preserving
function of type \lstinline!SFR[T] => NEL[T]! (this is a property
of the universal evaluator). However, there are several possible implementations
of \lstinline!fromNEL!: we could have created a left-associated tree,
@@ -2528,7 +2536,14 @@ \subsection{Free semigroup\label{subsec:Free-semigroup}}
still holds. But none of those alternative implementations could preserve
the typeclass operations.
-\subsection{Free monoid and its partially lawful encodings\label{subsec:Free-monoids}}
+{*}{*}{*} There are also alternative implementations of the universal
+runner that correspond to those functions. When the universal runner
+is applied with a lawful semigroup, the results are the same. But
+when we use SFR instead of a lawful semigroup, the results are \emph{not}
+the same. We see that it is important to take into account which laws
+hold when using the universal runner.{*}{*}{*}
+
+\subsection{Free monoid and its reduced encodings\label{subsec:Free-monoids}}
A monoid (see Example~\ref{subsec:tc-Example-Monoids}) is a typeclass
with a two methods: \lstinline!combine! and \lstinline!empty!. The
@@ -2558,7 +2573,7 @@ \subsection{Free monoid and its partially lawful encodings\label{subsec:Free-mon
an unevaluated expression tree (an \textsf{``}\lstinline!FMR!-program\textsf{''})
built from the monoid operations and from values of type $T$:
-\begin{wrapfigure}{l}{0.6\columnwidth}%
+\begin{wrapfigure}{l}{0.7\columnwidth}%
\vspace{-0.4\baselineskip}
\begin{lstlisting}
val exampleFMR: FMR[Int] = Combine(Empty(), Combine( Combine(Wrap(456), Empty()), Wrap(123)))
@@ -2574,7 +2589,7 @@ \subsection{Free monoid and its partially lawful encodings\label{subsec:Free-mon
implicit def monoidFMR[T]: Monoid[FMR[T]] = Monoid((l, r) => Combine(l, r), Empty())
\end{lstlisting}
We define a syntax extension for the infix binary operation \lstinline!|+|!
-as in the previous section.
+as before.
As usual with raw tree encodings, this free monoid\textsf{'}s operations do
not perform any computations but only create nested case classes in
@@ -2690,7 +2705,6 @@ \subsection{Free monoid and its partially lawful encodings\label{subsec:Free-mon
satisfies only the identity laws. The code is:
\begin{lstlisting}
type F3[T] = Option[Tree2[T]]
-def wrapF3[T](t: T): F3[T] = Some(Leaf(t))
def concatF3[T]: (F3[T], F3[T]) => F3[T] = {
case (None, x) => x
case (x, None) => x
@@ -2702,7 +2716,7 @@ \subsection{Free monoid and its partially lawful encodings\label{subsec:Free-mon
case Leaf(a) => runT(a)
case Branch(left, right) => runnerTree2(runT)(left) |+| runnerTree2(runT)(right)
}
-def runnerF3[M: Monoid, T](runT: T => M)(fmr: F3[T]): M = fmr match {
+def runnerF3[M: Monoid, T](runT: T => M): F3[T] => M = {
case Some(t) => runnerTree2(runT)(t)
case None => Monoid[M].empty
}
@@ -2791,17 +2805,255 @@ \subsection{Free monoid and its partially lawful encodings\label{subsec:Free-mon
which develops a rigorous theory of free typeclass encodings that
satisfy only a subset of the laws of a given typeclass.
+Are there any other encodings of the free monoid? Heuristically, we
+expect to find a reduced encoding satisfying any given subset of the
+monoid laws. The four encodings shown above correspond to four specific
+subsets of the laws; as there are three laws, one has 8 different
+encodings corresponding to all different subsets of the 3 laws that
+could be chosen. The following examples show how to implement the
+remaining encodings.
+
+\subsubsection{Example \label{subsec:Example-reduced-monoid-encoding-one-law}\ref{subsec:Example-reduced-monoid-encoding-one-law}\index{examples}}
+
+Find a reduced encoding of the free monoid that satisfies the left
+identity law and the associativity law, but \emph{not} the right identity
+law.
+
+\subparagraph{Solution}
+
+We start with the encoding \lstinline!F2!, which satisfies the associativity
+law. This encoding represents expressions built up from values of
+type $T$ and the special empty value $e$ via the operation $\oplus$.
+An example expression is:
+\[
+t_{1}\oplus t_{2}\oplus e\oplus t_{3}\oplus e\oplus e\quad.
+\]
+Here, we do not need parentheses since the operation $\oplus$ is
+associative and our encoding obeys the associativity law. This expression
+is represented by the non-empty list $\left[t_{1},t_{2},e,t_{3},e,e\right]$.
+
+To make the left identity law hold, we replace any expression of the
+form $e\oplus x$ by just $x$. This will eliminate \textsf{``}empty\textsf{''} list
+elements ($e$) to the left of any other elements (empty or not).
+For the example just shown, the result will be:
+\[
+t_{1}\oplus t_{2}\oplus t_{3}\oplus e\quad.
+\]
+This corresponds to a non-empty list of the form $\left[t_{1},t_{2},t_{3},e\right]$
+where all non-empty values appear before the empty one. The last empty
+element cannot be removed, since we do not impose the right identity
+law.
+
+What type can represent this data? A simple attempt would be a pair
+\lstinline!(List[T], Boolean)!, where the boolean value is \lstinline!true!
+when an empty value is present at the end. However, this type cannot
+guarantee that either the list of type \lstinline!List[T]! is non-empty
+or the boolean value is \lstinline!true!.
+
+To derive a correct data type, we begin by first defining the required
+structure by induction:
+\begin{itemize}
+\item Base cases:
+\begin{enumerate}
+\item We may have a single value of type $T$.
+\item We may have a single empty value ($e$).
+\end{enumerate}
+\item Inductive steps:
+\begin{itemize}
+\item If a sequence begins with a $t:T$ then it may continue to any other
+sequence of the same type (beginning either with another $t':T$ or
+with the empty value).
+\end{itemize}
+\end{itemize}
+If a sequence begins with an $e$, it must end at that point. So,
+there is no induction step following the second base case.
+
+To describe this logic, we need two case classes for the base cases
+and two more case classes to describe the two different types of induction
+steps. The empty value will be represented by a named \lstinline!Unit!
+type (\lstinline!OneE!):
+\begin{lstlisting}
+sealed trait F5[T]
+final case class OneT[T](single: T) extends F5[T] // Base case 1.
+final case class OneE[T]() extends F5[T] // Base case 2.
+final case class NELT[T](head: T, tail: F5[T]) extends F5[T]
+\end{lstlisting}
+In the type notation, we may write the recursive definition of $F_{5}$
+as:
+\[
+F_{5}^{T}\triangleq\bbnum 1+T+T\times F_{5}^{T}\quad.
+\]
+The \textsf{``}unrolling trick\textsf{''} \index{unrolling trick for recursive types}(Statement~\ref{Statement-unrolling-trick})
+simplifies this recursive definition to:
+\[
+F_{5}^{T}\cong\text{List}^{T}\times(\bbnum 1+T)\quad.
+\]
+\begin{lstlisting}
+final case class F5[T](start: List[T], end: Option[T])
+\end{lstlisting}
+The \lstinline!Monoid! typeclass instance and the runner code for
+\lstinline!F5! are written as:
+\begin{lstlisting}
+def wrapF5[T](t: T): F5[T] = F5(Nil, Some(t))
+def concatF5[T]: (F5[T], F5[T]) => F5[T] = {
+ case (F5(start1, Some(t)), F5(start2, end)) => F5(start1 ++ List(t) ++ start2, end)
+ case (F5(start1, None), F5(start2, end)) => F5(start1 ++ start2, end)
+}
+def emptyF5[T]: F5[T] = F5(Nil, None)
+implicit def monoidF5[T]: Monoid[F5[T]] = Monoid(concatF5[T], emptyF5[T])
+def runnerF5[M: Monoid, T](runT: T => M)(fm: F5[T]): M = {
+ val last: M = fm.end match {
+ case Some(t) => runT(t)
+ case None => Monoid[M].empty
+ }
+ fm.start.map(runT).reduce(Monoid[M].combine) |+| last
+}
+\end{lstlisting}
+
+To test this code, let us set $T=\text{Int}$ and create a free monoid
+value of type $F_{5}^{\text{Int}}$ corresponding to the expression
+$e\oplus1\oplus e\oplus2\oplus e$:
+\begin{lstlisting}
+scala> val testF5 = emptyF5[Int] |+| wrapF5(1) |+| emptyF5 |+| wrapF5(2) |+| emptyF5
+val testF5: F5[Int] = F5(List(1, 2),None)
+\end{lstlisting}
+We see that the free monoid $F_{5}$ simplifies this expression to
+$1\oplus2\oplus e$, although the expression should be equivalent
+to just $1\oplus2$ if we were able to use all the monoid laws.
+
+To evaluate the \textsf{``}free monoid program\textsf{''} \lstinline!testF5!, choose
+the target monoid $M=\text{String}$ (with the monoidal operation
+being the concatenation of strings). For the purposes of this example,
+define the function \lstinline!runT! that prints integers with up
+to 5 leading zeros. Then run the program and expect the concatenation
+of \lstinline!"00001"! and \lstinline!"00002"!:
+\begin{lstlisting}
+implicit val monoidString: Monoid[String] = Monoid(_ + _, "")
+
+val runT: Int => String = (x: Int) => f"${x}%05d"
+
+scala> runT(123)
+val res0: String = 00123
+
+scala> runnerF5(runT)(testF5)
+val res1: String = 0000100002
+\end{lstlisting}
+The result of the evaluation is the same as if the monoid program
+were just $1\oplus2$. The monoid laws appear to hold after applying
+the runner.
+
+\subsubsection{Example \label{subsec:Example-reduced-monoid-encoding-one-law-1}\ref{subsec:Example-reduced-monoid-encoding-one-law-1}}
+
+Find a reduced encoding of the free monoid that satisfies the left
+identity law but \emph{no} other laws of monoids.
+
+\subparagraph{Solution}
+
+Our goal is to define a recursive type \lstinline!F6! with the required
+properties.
+
+Start with the raw tree encoding, which is a binary tree with leaves
+of type $\bbnum 1+T$. The type \lstinline!F6[T]! must be similarly
+a binary tree with leaves of that type. However, the left identity
+law ($e\oplus x=x$) means that in any branching of the tree, the
+left branch cannot be an \textsf{``}empty\textsf{''} leaf (a leaf carrying the value
+$e$). The right branch remains unrestricted. To implement the restriction
+on the left branches, we introduce a special type (\lstinline!TreeNonEmpty!)
+for a tree that cannot be an empty leaf value. The left branches of
+\lstinline!TreeNonEmpty! must also have type \lstinline!TreeNonEmpty!
+(cannot be empty leaves), while the right branches are unrestricted
+(have type \lstinline!F6!). Finally, we define the type \lstinline!F6!
+as a tree that can itself be an empty leaf, but whose left branches
+have type \lstinline!TreeNonEmpty! (cannot be empty leaves). The
+right branches of \lstinline!F6! have again type \lstinline!F6!.
+\begin{lstlisting}
+sealed trait TreeNE[T] // Cannot be an empty leaf.
+final case class LeafNE[T](t: T) extends TreeNE[T]
+final case class BranchNE[T](left: TreeNE[T], right: F6[T]) extends TreeNE[T]
+
+sealed trait F6[T] // This tree can be an empty leaf, but its left branch.
+final case class LeafT[T](t: T) extends F6[T]
+final case class LeafE[T]() extends F6[T]
+final case class BranchF6[T](left: TreeNE[T], right: F6[T]) extends F6[T]
+\end{lstlisting}
+In the type notation, the encoding \lstinline!F6! is expressed via
+two \textbf{mutually recursive types}\index{mutually recursive types}:
+\begin{align*}
+{\color{greenunder}\text{\texttt{F6[T]} in the code}:}\quad & F_{6}^{T}\triangleq\bbnum 1+T+G^{T}\times F_{6}^{T}\quad,\\
+{\color{greenunder}\text{\texttt{TreeNE[T]} in the code}:}\quad & G^{T}\triangleq T+G^{T}\times F_{6}^{T}\quad.
+\end{align*}
+\textsf{''}Mutually recursive\textsf{''} means that each the definitions of $F_{6}^{T}$
+and $G$ uses both these types.
+
+Let us implement the \lstinline!Monoid! instance and a universal
+runner for \lstinline!F6!, which we write via two mutually recursive
+functions (\lstinline!runnerF6NE! and \lstinline!runnerF6!):
+\begin{lstlisting}
+def wrapF6[T](t: T): F6[T] = LeafT(t)
+
+def toTreeNE[T]: F6[T] => TreeNE[T] = {
+ case LeafE() => ??? // This case will never be used.
+ case LeafT(t) => LeafNE(t)
+ case BranchF6(left, right) => BranchNE(left, right)
+}
+def concatF6[T]: (F6[T], F6[T]) => F6[T] = {
+ case (LeafE(), x) => x // Left identity law holds automatically.
+ case (first, second) => BranchF6(toTreeNE(first), second) // `first` is guaranteed to be non-empty.
+ }
+def emptyF6[T]: F6[T] = LeafE()
+
+implicit def monoidF6[T]: Monoid[F6[T]] = Monoid(concatF6[T], emptyF6[T])
+
+def runnerF6NE[M: Monoid, T](runT: T => M)(tree: TreeNE[T]): M = tree match {
+ case LeafNE(t) => runT(t)
+ case BranchNE(left, LeafE()) => runnerF6NE(runT)(left)
+ case BranchNE(left, right) => runnerF6NE(runT)(left) |+| runnerF6(runT)(right)
+}
+def runnerF6[M: Monoid, T](runT: T => M)(tree: F6[T]): M = tree match {
+ case LeafE() => Monoid[M].empty
+ case LeafT(t) => runT(t)
+ case BranchF6(left, right) => runnerF6NE(runT)(left) |+| runnerF6(runT)(right)
+}
+\end{lstlisting}
+
+We test this code with the same data as in the previous example.
+\begin{lstlisting}
+scala> val testF6 = emptyF6[Int] |+| wrapF6(1) |+| emptyF6 |+| wrapF6(2) |+| emptyF6
+val testF6: F6[Int] = BranchF6(BranchNE(BranchNE(LeafNE(1),LeafE()),LeafT(2)),LeafE())
+\end{lstlisting}
+We see that the monoid program $(((e\oplus1)\oplus e)\oplus2)\oplus e$
+is simplified to the expression tree $((1\oplus e)\oplus2)\oplus e$
+because the free monoid $F_{6}$ only respects the left identity law
+but not the associativity law.
+
+Apply \lstinline!runnerF6! to \lstinline!testF6! using the same
+function \lstinline!runT! as before:
+\begin{lstlisting}
+scala> runnerF6(runT)(testF6)
+val res1: String = 0000100002
+\end{lstlisting}
+This is the same result as in the previous example.
+
+{*}{*}{*}Exercises: free monoids that satisfy the right identity law
+and the associativity law; or just the right identity law. Find a
+map between free monoids that satisfy the right identity law and that
+satisfy the left; show that operations are not preserved and that
+maps are not injective. Use a sorted list to implement commutativity
+law for semigroups and for monoids. Find a free semigroup that is
+commutative but not associative.
+
\subsection{Free functors}
Consider the \lstinline!Functor! typeclass whose only method is \lstinline!fmap!:
\[
\text{fmap}:\left(A\rightarrow B\right)\rightarrow F^{A}\rightarrow F^{B}\quad.
\]
-The \lstinline!fmap! method is not available for some type constructors
-$F$, such as contrafunctors or GADTs. (See Section~\ref{subsec:Examples-of-non-functors}
-for more examples.) Let us now apply the raw tree encoding recipe
-to the \lstinline!Functor! typeclass. The result will be a new type
-constructor that we call a \textbf{free functor on} $F$.\index{free functor}
+The \lstinline!fmap! method is supported by all covariant type constructors,
+but is not available when $F$ is a contrafunctor or a GADT. (See
+Section~\ref{subsec:Examples-of-non-functors} for more examples.)
+Let us now apply the raw tree encoding recipe to the \lstinline!Functor!
+typeclass. The result will be a new type constructor that we call
+a \textbf{free functor on} $F$.\index{free functor}
The recipe tells us to define a case class for the \lstinline!fmap!
method and another case class to wrap the given type constructor $F$.
@@ -2816,14 +3068,14 @@ \subsection{Free functors}
This code corresponds to the following notation for the lifting $f^{\uparrow\text{FFR}}$:
\begin{align}
- & \text{FFR}^{F^{\bullet},A}\triangleq F^{A}+\exists X.\,(X\rightarrow A)\times\text{FFR}^{F^{\bullet},X}\quad,\label{eq:definition-FFR-existential-type}\\
- & p^{:\text{FFR}^{F^{\bullet},A}}\triangleright(f^{:A\rightarrow B})^{\uparrow\text{FFR}^{F^{\bullet},\bullet}}\triangleq\bbnum 0^{:F^{B}}+\exists^{A}.\,f^{:A\rightarrow B}\times p^{:\text{FFR}^{F^{\bullet},A}}\quad.\nonumber
+ & \text{FFR}^{F,A}\triangleq F^{A}+\exists X.\,(X\rightarrow A)\times\text{FFR}^{F,X}\quad,\label{eq:definition-FFR-existential-type}\\
+ & p^{:\text{FFR}^{F,A}}\triangleright(f^{:A\rightarrow B})^{\uparrow\text{FFR}^{F,\bullet}}\triangleq\bbnum 0^{:F^{B}}+\exists^{A}.\,f^{:A\rightarrow B}\times p^{:\text{FFR}^{F,A}}\quad.\nonumber
\end{align}
The notation $\exists^{A}$ means that we bind the type $A$ to the
existentially quantified type $X$ in the definition~(\ref{eq:definition-FFR-existential-type})
-of $\text{FFR}^{F^{\bullet},B}$. This notation expresses the requirement
-that the existentially quantified type must be assigned to a specific
-type every time we create a specific value.
+of $\text{FFR}^{F,B}$. This notation expresses the requirement that
+the existentially quantified type must be assigned to a specific type
+every time we create a specific value.
A \textsf{``}free functor program\textsf{''} is a value of type \lstinline!FFR[F, A]!.
To construct such values, we must begin with a wrapped \lstinline!F!-operation
@@ -2837,38 +3089,42 @@ \subsection{Free functors}
$\forall C.\,F^{C}\rightarrow C$ (an \index{effect runner}effect
runner for $F$). To implement such functions, we use the trait \lstinline!Runner!
defined in Section~\ref{subsec:A-first-recipe-monadic-dsl}. Now
-we can write the code of the runner for $\text{FFR}^{F,A}$:
+we can write the code of the universal runner for $\text{FFR}^{F,A}$:
\begin{lstlisting}
def runFFR[F[_], A](runner: Runner[F]): FFR[F, A] => A = {
case FMap(f, p) => f(runFFR(runner)(p))
case Op(op) => runner.apply(op)
-}*** check if this works
+}
\end{lstlisting}
The code notation for this function is:
\begin{align*}
- & \text{runFFR}^{F^{\bullet},A}:(\forall C.\,F^{C}\rightarrow C)\rightarrow\text{FFR}^{F^{\bullet},A}\rightarrow A\quad,\\
+ & \text{runFFR}^{F,A}:(\forall C.\,F^{C}\rightarrow C)\rightarrow\text{FFR}^{F,A}\rightarrow A\quad,\\
& \text{runFFR}(\text{run}:\forall C.\,F^{C}\rightarrow C)\triangleq\forall B.\,\,\begin{array}{|c||c|}
& A\\
\hline F^{A} & \text{run}\\
-(B\rightarrow A)\times\text{FFR}^{F^{\bullet},B} & f^{:B\rightarrow A}\times p^{:FFR^{F^{\bullet},B}}\rightarrow p\triangleright\big(\overline{\text{runFFR}}(\text{run})\big)\triangleright f
+(B\rightarrow A)\times\text{FFR}^{F,B} & f^{:B\rightarrow A}\times p^{:FFR^{F,B}}\rightarrow p\triangleright\big(\overline{\text{runFFR}}(\text{run})\big)\triangleright f
\end{array}\quad.
\end{align*}
-The outside universal quantifier $\forall B$ replaces $\exists B$
-in the function argument, according to Eq.~(\ref{eq:existential-via-universal}).
+The outside quantifier $\forall B$ replaces $\exists B$ in the function
+argument, according to Eq.~(\ref{eq:existential-via-universal}).
-More generally, we may want to run the effects of $F$ into the effects
+More generally, we may need to run the effects of $F$ into the effects
of a given functor $G$. (The functor $G$ could, for example, describe
-errors or asynchronous execution.) The corresponding runner will have
-type $\forall C.\,F^{C}\rightarrow G^{C}$, and the code is:
+errors or asynchronous execution.) The corresponding effect runner
+will have type $\forall C.\,F^{C}\rightarrow G^{C}$ instead of $\forall C.\,F^{C}\rightarrow C$.
+The code for the universal runner is:
\begin{align*}
- & \text{runFFR}^{F^{\bullet},G^{\bullet},A}:(\forall C.\,F^{C}\rightarrow G^{C})\rightarrow\text{FFR}^{F^{\bullet},A}\rightarrow G^{A}\quad,\\
+ & \text{runFFR}^{F,G,A}:(\forall C.\,F^{C}\rightarrow G^{C})\rightarrow\text{FFR}^{F,A}\rightarrow G^{A}\quad,\\
& \text{runFFR}\,(\text{run})\triangleq\forall B.\,\,\begin{array}{|c||c|}
& G^{A}\\
\hline F^{A} & \text{run}\\
-(B\rightarrow A)\times\text{FFR}^{F^{\bullet},B} & f^{:B\rightarrow A}\times p^{:FFR^{F^{\bullet},B}}\rightarrow p\triangleright\big(\overline{\text{runFFR}}\,(\text{run})\big)\triangleright f^{\uparrow G}
+(B\rightarrow A)\times\text{FFR}^{F,B} & f^{:B\rightarrow A}\times p^{:FFR^{F,B}}\rightarrow p\triangleright\big(\overline{\text{runFFR}}\,(\text{run})\big)\triangleright f^{\uparrow G}
\end{array}\quad.
\end{align*}
+{*}{*}{*} example code: what if $\forall C.\,F^{C}\rightarrow C$
+cannot be implemented? What weaker property is sufficient?
+
The type constructor \lstinline!FFR! is a \index{free functor!raw tree encoding}raw
tree encoding of the free functor and does not satisfy the functor
laws. This is not a problem in practice, because the functor laws
@@ -2877,10 +3133,9 @@ \subsection{Free functors}
\subsubsection{Statement \label{subsec:Statement-free-functor-raw-tree-encoding-satisfies-laws}\ref{subsec:Statement-free-functor-raw-tree-encoding-satisfies-laws}}
-Take any free functor ($\text{FFR}^{F^{\bullet},A}$) and any runner
-($\text{run}:\forall C.\,F^{C}\rightarrow G^{C}$), where $G$ is
-a lawful functor. Denote for brevity $f^{\uparrow\text{FFR}}\triangleq f^{\uparrow\text{FFR}^{F^{\bullet},\bullet}}$.
-The functor laws will hold if we apply the runner function, denoted
+Take any free functor ($\text{FFR}^{F,A}$) and any runner ($\text{run}:\forall C.\,F^{C}\rightarrow G^{C}$),
+where $G$ is a lawful functor. Denote for brevity $f^{\uparrow\text{FFR}}\triangleq f^{\uparrow\text{FFR}^{F,\bullet}}$.
+The functor laws will hold after applying the runner function, denoted
for brevity by $\rho\triangleq\text{runFFR}\,(\text{run})$,{*}{*}{*}replace
$\rho$ with some other letter{*}{*}{*} to both sides of the laws:
\begin{align*}
@@ -2928,7 +3183,7 @@ \subsubsection{Statement \label{subsec:Statement-free-functor-raw-tree-encoding-
To transform the raw tree encoding of the free functor into a reduced
encoding, we require that all functor laws should hold even before
applying a runner. We begin by finding out in detail why the functor
-laws fail to hold for \lstinline!FFR[F, A]!.
+laws fail for \lstinline!FFR[F, A]!.
The type \lstinline!FFR[F, A]! is a disjunction of two case classes,
\lstinline!FMap! and \lstinline!Op!. The functor\textsf{'}s composition law
@@ -2958,40 +3213,42 @@ \subsubsection{Statement \label{subsec:Statement-free-functor-raw-tree-encoding-
not return \lstinline!Op(op)! but instead gives \lstinline!FMap(identity, Op(op))!.
Values of the form \lstinline!Op(op)! represent \lstinline!F!-effects.
The functor identity law would hold if we instead represented $F$-effects
-by the \lstinline!FMap! case class as \lstinline!FMap(identity, Op(op))!.
+by the expression \lstinline!FMap(identity, Op(op))!.
Any \lstinline!FFR!-program must have the form \lstinline!Op(x).map(y).map(z)...!,
having zero or more \lstinline!map! methods. If we represent \lstinline!F!-effects
by \lstinline!FMap(identity, Op(op))! and implement the \lstinline!map!
methods for \lstinline!FMap! as shown above, it will follow that
\emph{all} \lstinline!FFR!-programs always have the form \lstinline!FMap(f, Op(op))!
-for some function \lstinline!f!. So, we may remove the \lstinline!Op!
-case class altogether.
-
-The result is a simplified definition of the free functor. The complete
+for some function \lstinline!f!. It means we may remove the \lstinline!Op!
+case class altogether. Only one case class (\lstinline!FMap!) remains.
+However, we still need to implement the free functor as a trait \lstinline!FF[F, A]!
+containing a single case class \lstinline!FMap[F, C, A]!. This is
+because \lstinline!FMap[F, C, A]! has an extra type parameter (\lstinline!C!)
+that does not appear in \lstinline!FF[F, A]!. (In other words, the
+type parameter \lstinline!X! is existentially quantified.) The complete
code is:
\begin{lstlisting}
sealed trait FF[F[_], A] {
def map[B](f: A => B): FF[F, B]
}
-final case class FMap[F[_], X, Y](f: X => Y, p: F[X]) extends FF[F, Y] {
- def map[Z](g: Y => Z): FF[F, Z] = FMap[F, X, Z](f andThen g, p)
+final case class FMap[F[_], C, A](f: C => A, p: F[C]) extends FF[F, A] {
+ def map[B](g: A => B): FF[F, B] = FMap[F, C, B](f andThen g, p)
}
def runFF[F[_], A](runner: Runner[F]): FF[F, A] => A = {
case FMap(f, p) => f(runner.apply(p))
-}*** check if this works
+}
\end{lstlisting}
-The code notation for this code and a general runner is:
+The code notation for this code is:
\begin{align*}
- & \text{FF}^{F^{\bullet},A}\triangleq\exists C.\,\left(C\rightarrow A\right)\times F^{C}\quad,\quad\quad(\exists C.\,f^{:C\rightarrow A}\times p^{:F^{C}})\triangleright(g^{:A\rightarrow B})^{\uparrow\text{FR}}\triangleq\exists^{C}.\,(f\bef g)\times p\quad,\\
- & \text{runFF}:(\forall C.\,F^{C}\rightarrow G^{C})\rightarrow\text{FF}^{F^{\bullet},A}\rightarrow G^{A}\quad,\\
+ & \text{FF}^{F,A}\triangleq\exists C.\,\left(C\rightarrow A\right)\times F^{C}\quad,\quad\quad(\exists C.\,f^{:C\rightarrow A}\times p^{:F^{C}})\triangleright(g^{:A\rightarrow B})^{\uparrow\text{FR}}\triangleq\exists^{C}.\,(f\bef g)\times p\quad,\\
+ & \text{runFF}:(\forall C.\,F^{C}\rightarrow G^{C})\rightarrow\text{FF}^{F,A}\rightarrow G^{A}\quad,\\
& \text{runFF}\,(\text{run})\triangleq(\exists C.\,f^{:C\rightarrow A}\times p^{:F^{C}})\rightarrow p\triangleright\text{run}\triangleright f^{\uparrow G}\quad.
\end{align*}
This is the \textbf{reduced encoding}\index{free functor!reduced encoding}
of the free functor on $F$. This encoding was derived by imposing
-the functor laws, so those laws will hold for values of type \lstinline!FF[F, A]!
-even before applying a runner.
+the functor laws, so those laws will hold for values of type \lstinline!FF[F, A]!.
The free functor construction \lstinline!FF[F, A]! converts \emph{any}
type constructor \lstinline!F[_]! into a lawful functor. What if
@@ -3003,7 +3260,7 @@ \subsubsection{Statement \label{subsec:Statement-free-functor-raw-tree-encoding-
\begin{align*}
{\color{greenunder}\text{covariant co-Yoneda identity}:}\quad & \exists C.\,\left(C\rightarrow A\right)\times F^{C}\cong F^{A}\quad\text{for any functor }F\quad.
\end{align*}
-We will prove this type equivalence in Statement~\ref{subsec:Statement-co-Yoneda-two-identities}
+We will prove this type identity in Statement~\ref{subsec:Statement-co-Yoneda-two-identities}
(Appendix~\ref{app:Proofs-of-naturality-parametricity}).
We conclude that the reduced encoding of the free functor (\lstinline!FF[F, A]!)
@@ -3016,57 +3273,98 @@ \subsubsection{Statement \label{subsec:Statement-free-functor-raw-tree-encoding-
A disadvantage of the reduced encoding is that the function composition
is done in the code \lstinline!FMap(f andThen g, p)!. The Scala compiler
cannot directly handle the composition of a large number of functions
-without causing a stack overflow. This problem can be resolved if
-we postpone the function composition and instead create a list of
-functions that need to be composed. The runner can evaluate the list
-of functions without running into a stack overflow.
-
-This gives us an idea for another encoding of the stack-safe free
-functor, which we will call \lstinline!FFS!. First, we implement
-a data structure called \lstinline!FuncSeq! for storing a list of
-functions with matching types. A value of type \lstinline!FuncSeq[A, B]!
-holds a list of functions with types $A\rightarrow C_{1}$, $C_{1}\rightarrow C_{2}$,
-..., $C_{n-1}\rightarrow C_{n}$, $C_{n}\rightarrow B$, where $C_{i}$
-are some chosen types. A list of with those types can be composed
-to yield a function of type $A\rightarrow B$. To simplify code, we
-will cast all intermediate types to \lstinline!Any! and back. Our
-code will take care to construct \lstinline!FuncSeq! values with
-correct types.\lstinline!final case class FuncSeq[X, Y](first: X => Any, funcs: Vector[Any => Any]) { def append[Z](g: Y => Z): FuncSeq[X, Z] = FuncSeq(first, funcs :+ g.asInstanceOf[Any => Any])}!
+without causing a stack overflow:
+\begin{lstlisting}
+def composed(n: Int): Long => Long = (1 to n).foldLeft[Long => Long](x => x){ (prev, i) => prev andThen (x => x + i) }
-To ensure stack safety when working with \lstinline!FuncSeq!, we
-implement a tail-recursive function \lstinline!runSeq! that composes
-all functions stored in the sequence and applies them to a given value.
+scala> composed(100)(0) // OK to compose 100 functions.
+res0: Long = 5050
+
+scala> composed(100000)(0) // Cannot compose 100000 functions.
+java.lang.StackOverflowError
+\end{lstlisting}
+This code causes a stack overflow because each function composition
+creates a new stack frame when functions are applied.
+
+Stack overflows can be avoided if we postpone the function compositions.
+Instead, we just store all the functions that need to be composed
+as a sequence of functions with types $A\rightarrow C_{1}$, $C_{1}\rightarrow C_{2}$,
+..., $C_{n-1}\rightarrow C_{n}$, $C_{n}\rightarrow B$, where $C_{i}$
+are some fixed types. Then we write a \textsf{``}runner\textsf{''} that applies the
+functions one by one to a given initial value of type $A$. The result
+is as if we have evaluated a single function of type $A\rightarrow B$.
+
+Here is an example implementation of this idea. Define a helper class
+\lstinline!SafeFunction! as a subclass of \lstinline!A => B! that
+overrides the composition methods (\lstinline!compose!, \lstinline!andThen!).
+Instead of composing the functions immediately, the new function bodies
+are added to a sequence of already stored functions. The \lstinline!apply!
+method is the \textsf{``}runner\textsf{''} for computing the final result in constant
+stack space.
+
+To simplify code, we will store functions in a sequence of type \lstinline!Vector[Any => Any]!;;
+type safety will be guaranteed when constructing values of type \lstinline!SafeFunction!.
+The choice of the \lstinline!Vector! container type allows us efficient
+appending and prepending to the sequence.
+\begin{lstlisting}
+final case class SafeFunction[A, B](funcs: Vector[Any => Any]) extends (A => B) {
+ def apply(a: A): B = funcs.foldLeft[Any](a){ (prev, func) => func(prev) }.asInstanceOf[B]
+ override def andThen[C](g: B => C): A => C =
+ SafeFunction(funcs :+ g.asInstanceOf[Any => Any])
+ override def compose[C](g: C => A): C => B =
+ SafeFunction(g.asInstanceOf[Any => Any] +: funcs)
+}
+\end{lstlisting}
+Converting an ordinary function to a \lstinline!SafeFunction! is
+straightforward:
\begin{lstlisting}
-@tailrec def runSeq[X, Y](x: X, p: FuncSeq[X, Y]): Y = p.funcs.headOption match {
- case None => p.first(x).asInstanceOf[Y]
- case Some(second) => runSeq(p.first(x), FuncSeq(second, p.funcs.tail))
+def toSafeFunction[A, B](f: A => B): SafeFunction[A, B] = f match {
+ case SafeFunction(_) => f.asInstanceOf[SafeFunction[A, B]]
+ case _ => SafeFunction(Vector(f.asInstanceOf[Any => Any]))
}
\end{lstlisting}
-Now we can write the code of the free functor \lstinline!FFS!:
+For convenience, we also define the corresponding extension methods
+(\lstinline!safeAndThen!, \lstinline!safeCompose!) on ordinary functions:
+\begin{lstlisting}
+implicit class SafeCompose[A, B](f: A => B) {
+ def safeAndThen[C](g: B => C): A => C = toSafeFunction(f).andThen(g)
+ def safeCompose[C](g: C => A): C => B = toSafeFunction(f).compose(g)
+}
+\end{lstlisting}
+
+Millions of functions can be now composed with no stack overflow:
+\begin{lstlisting}
+def safeComposed(n: Int): Long => Long = (1 to n).foldLeft[Long => Long](x => x){ (prev, i) => prev.safeAndThen(x => x + i) }
+
+scala> safeComposed(10000000)(0) // Compose 10 million functions.
+res1: Long = 50000005000000
+\end{lstlisting}
+
+We use \lstinline!safeAndThen! to obtain a stack-safe encoding of
+the free functor (\lstinline!FFS!) with no changes in the runner:
\begin{lstlisting}
sealed trait FFS[F[_], A] {
def map[B](f: A => B): FFS[F, B]
}
-final case class FMap[F[_], X, Y](f: FuncSeq[X, Y], p: F[X]) extends FFS[F, Y] {
- def map[Z](g: Y => Z): FFS[F, Z] = FMap[F, X, Z](f append g, p)
+final case class FMap[F[_], X, Y](f: X => Y, p: F[X]) extends FFS[F, Y] {
+ def map[Z](g: Y => Z): FFS[F, Z] = FMap[F, X, Z](f.safeAndThen(g), p)
}
def runFF[F[_], A](runner: Runner[F]): FFS[F, A] => A = {
- case FMap(f, p) => runSeq(runner.apply(p), f)
-}*** check if this works
+ case FMap(f, p) => f(runner.apply(p))
+}
\end{lstlisting}
-
+Test this code: {*}{*}{*}
\subsection{Free contrafunctors}
Method $\text{contramap}:C^{A}\times\left(B\rightarrow A\right)\rightarrow C^{B}$
-Tree encoding: $\text{FreeCF}^{F^{\bullet},B}\triangleq F^{B}+\exists A.\text{FreeCF}^{F^{\bullet},A}\times\left(B\rightarrow A\right)$
+Tree encoding: $\text{FreeCF}^{F,B}\triangleq F^{B}+\exists A.\text{FreeCF}^{F,A}\times\left(B\rightarrow A\right)$
-Reduced encoding: $\text{FreeCF}^{F^{\bullet},B}\triangleq\exists A.F^{A}\times\left(B\rightarrow A\right)$
+Reduced encoding: $\text{FreeCF}^{F,B}\triangleq\exists A.F^{A}\times\left(B\rightarrow A\right)$
-A value of type $\text{FreeCF}^{F^{\bullet},B}$ must be of the form
-{\footnotesize{}
+A value of type $\text{FreeCF}^{F,B}$ must be of the form {\footnotesize{}
\[
\exists Z_{1}.\exists Z_{2}...\exists Z_{n}.F^{Z_{1}}\times\left(B\rightarrow Z_{n}\right)\times\left(Z_{n}\rightarrow Z_{n-1}\right)\times...\times\left(Z_{2}\rightarrow Z_{1}\right)
\]
@@ -3085,7 +3383,7 @@ \subsection{Free contrafunctors}
\texttt{\textcolor{blue}{\footnotesize{}def prefixLog{[}A{]}(p: A): A
$\rightarrow$ String = a $\rightarrow$ p.toString + a.toString}}{\footnotesize\par}
-If $F^{\bullet}$ is already a contrafunctor then $\text{FreeCF}^{F^{\bullet},A}\cong F^{A}$
+If $F$ is already a contrafunctor then $\text{FreeCF}^{F,A}\cong F^{A}$
\subsection{Free constructions that assume other typeclasses}
@@ -3189,8 +3487,8 @@ \subsection{Church encodings of free typeclasses}
theorem.{*}{*}{*}
As a first example of using Eq.~(\ref{eq:free-typeclass-via-church-encoding}),
-consider a $P$-typeclass called \lstinline!TC! whose methods do
-not have to obey any laws. The Scala code for the typeclass \lstinline!TC!
+consider an FM-typeclass called \lstinline!TC! whose methods do not
+have to obey any laws. The Scala code for the typeclass \lstinline!TC!
contains two methods:
\begin{lstlisting}
trait TC[A] {
@@ -3229,7 +3527,7 @@ \subsection{Church encodings of free typeclasses}
The code of \lstinline!FreeTC[T]! and of \lstinline!instanceFreeTC!
uses the trait \lstinline!TC! parametrically. We expect that similar
-code will work for any other $P$-typeclass to define a free instance.
+code will work for any other FM-typeclass to define a free instance.
To see that more clearly, rewrite the type signature of the function
\lstinline!run! showing the implicit parameter at the end:
\begin{lstlisting}
@@ -3241,20 +3539,20 @@ \subsection{Church encodings of free typeclasses}
\[
\forall A.\,(T\rightarrow A)\rightarrow\text{TC}^{A}\rightarrow A\quad.
\]
-Let us generalize from \lstinline!TC! to an arbitrary $P$-typeclass,
+Let us generalize from \lstinline!TC! to an arbitrary FM-typeclass,
replacing the type $\text{TC}^{A}$ by the type $P^{A}\rightarrow A$
-that describes all the methods of the $P$-typeclass. Then the free
-$P$-typeclass instance constructor is given by:
+that describes all the methods of the FM-typeclass. Then the free
+FM-typeclass instance constructor is given by:
\[
\forall A.\,(T\rightarrow A)\rightarrow(P^{A}\rightarrow A)\rightarrow A\quad.
\]
This type can be rewritten as $\forall A.\,(T+P^{A}\rightarrow A)\rightarrow A$,
which is the Church encoding of the recursive type $F\cong T+P^{F}$.
We recognize that $F$ is the free monad on the functor $P$, applied
-to the type $T$. Indeed, we know from the theory of $P$-typeclasses
+to the type $T$. Indeed, we know from the theory of FM-typeclasses
that the free monad on $P$ gives the raw tree encoding of the free
-$P$-typeclass. If the $P$-typeclass has no laws then this is the
-only available encoding.
+FM-typeclass. If the FM-typeclass has no laws then this is the only
+available encoding.
Most typeclasses do require some laws to hold. This technique will
still give acceptable results even though Scala code cannot enforce
@@ -3318,7 +3616,7 @@ \subsection{Church encodings of free typeclasses}
monoid laws will also hold for \lstinline!FreeMonoid[T]!.
What happens if we apply the same technique to a typeclass that is
-\emph{not} of the form of a $P$-typeclass? As it turns out, the construction
+\emph{not} of the form of an FM-typeclass? As it turns out, the construction
no longer works as expected. An example is the \lstinline!Eq! typeclass
(Section~\ref{subsec:The-Eq-typeclass}) whose evidence values have
type $T\times T\rightarrow\bbnum 2$, giving a comparison operation
@@ -3364,48 +3662,47 @@ \section{Laws of free constructions\label{sec:Laws-of-free-constructions}}
its various encodings. Can we formulate any properties or laws that
validate the correctness of those constructions? Are all the different
encodings equally safe to use? We will now develop the necessary theory
-for answering these questions in the case of $P$-typeclasses for
-ordinary types. (The notion of a \textsf{``}$P$-typeclass\textsf{''} was introduced
-in Section~\ref{subsec:P-typeclasses}.) We expect that $P$-typeclasses
-for type constructors (such as \lstinline!Functor! and \lstinline!Monad!)
-will have similar properties, although the technical details of the
-proofs will be more difficult to work out.
+for answering these questions in the case of FM-typeclasses for ordinary
+types. (The notion of a \textsf{``}FM-typeclass\textsf{''} was introduced in Section~\ref{subsec:P-typeclasses}.)
+We expect that FM-typeclasses for type constructors (such as \lstinline!Functor!
+and \lstinline!Monad!) will have similar properties, although the
+technical details of the proofs will be more difficult to work out.
-\subsection{Free constructions for $P$-typeclasses\label{subsec:Free-constructions-for-inductive-typeclasses}}
+\subsection{Free constructions for FM-typeclasses\label{subsec:Free-constructions-for-inductive-typeclasses}}
Some features are common to all the free typeclass constructions we
have seen. To find a mathematical description of those common features,
we need to generalize what we have learned about specific typeclasses
(free monads, free monoids, etc.) to an arbitrary typeclass. We will
use the encodings of the free monoid as the starting point and generalize
-to encodings of an arbitrary free $P$-typeclass.
+to encodings of an arbitrary free FM-typeclass.
-The free monoid is a type constructor (denoted by \textsf{``}$\text{FM}$\textsf{''})
-that transforms an arbitrary type $T$ into a new type ($\text{FM}^{T}$)
+The free monoid is a type constructor (which turns out to be \lstinline!List!)
+that transforms an arbitrary type $T$ into a new type ($\text{List}^{T}$)
having a \lstinline!Monoid! typeclass instance. Values of type $T$
-can be wrapped into values of type $\text{FM}^{T}$. For any given
+can be wrapped into values of type $\text{List}^{T}$. For any given
monoid $M$ and a given function of type $T\rightarrow M$, a \textsf{``}free
-monoid program\textsf{''} (i.e., a value of type $\text{FM}^{T}$) can be
-\textsf{``}run into $M$\textsf{''}. The resulting runner (of type $\text{FM}^{T}\rightarrow M$)
-will preserve the monoid operations between $\text{FM}^{T}$ and $M$.
-So, the monoid laws will hold after running a \textsf{``}free monoid program\textsf{''},
-even when the chosen encoding $\text{FM}^{T}$ violates some of the
-monoid laws.
+monoid program\textsf{''} (i.e., a value of type $\text{List}^{T}$) can be
+\textsf{``}run into $M$\textsf{''}. The resulting runner (of type $\text{List}^{T}\rightarrow M$)
+will preserve the monoid operations between $\text{List}^{T}$ and
+$M$. So, the monoid laws will hold after running a \textsf{``}free monoid
+program\textsf{''}, even when the chosen encoding $\text{List}^{T}$ violates
+some of the monoid laws.
To generalize from monoids to other typeclasses, recall the definition
-of a $P$-typeclass (Section~\ref{subsec:P-typeclasses}): For a
-given (covariant) functor $P$, a $P$\textbf{-typeclass} \index{$P$-typeclass}
+of an FM-typeclass (Section~\ref{subsec:P-typeclasses}): For a given
+(covariant) functor $P$, an FM-\textbf{typeclass} \index{FM-typeclass}
has the evidence data equivalent to a value of type $P^{A}\rightarrow A$.
The evidence data for the \lstinline!Monoid! typeclass has type $A\times\left(A\times A\rightarrow A\right)$,
which is equivalent to $P^{A}\rightarrow A$ if we define $P^{A}\triangleq\bbnum 1+A\times A$.
The two parts of the disjunctive type $\bbnum 1+A\times A$ correspond
to the \emph{arguments} of the monoid\textsf{'}s two operations: the empty
value ($e_{A}$) and the binary operation ($\oplus_{A}$). So, we
-imagine that the $P$-typeclass combines all methods of a typeclass
+imagine that the FM-typeclass combines all methods of a typeclass
into a single value (of type $P^{A}\rightarrow A$).
The next step is to generalize the property of \textsf{``}preserving the monoid\textsf{'}s
-operations\textsf{''} to an arbitrary $P$-typeclass. Given two monoids $M$
+operations\textsf{''} to an arbitrary FM-typeclass. Given two monoids $M$
and $N$, a function $f:M\rightarrow N$ that preserves the monoid\textsf{'}s
operations is a monoid morphism\index{monoid morphism} according
to Definition~\ref{subsec:Definition-monoid-morphism}. Can we describe
@@ -3481,7 +3778,7 @@ \subsection{Free constructions for $P$-typeclasses\label{subsec:Free-constructio
This equation is the same as the identity and composition laws in
Definition~\ref{subsec:Definition-monoid-morphism}. It is now clear
how to define the property of \textsf{``}preserving the typeclass operations\textsf{''}
-for an arbitrary $P$-typeclass: we just need to impose Eq.~(\ref{eq:p-algebra-morphism-law}).
+for an arbitrary FM-typeclass: we just need to impose Eq.~(\ref{eq:p-algebra-morphism-law}).
In this way, we have reformulated the typeclass preservation property
in terms of the functor $P$.
@@ -3541,34 +3838,34 @@ \subsubsection{Statement \label{subsec:Statement-category-of-P-algebras}\ref{sub
\end{align*}
$\square$
-We can now formulate our findings about $P$-typeclasses in the language
+We can now formulate our findings about FM-typeclasses in the language
of $P$-functor algebras (using the functor $P$ instead of $F$).
-We say that a $P$\textbf{-typeclass with laws} is\index{$P$-typeclass!with laws}
+We say that an FM-\textbf{typeclass with laws} is\index{FM-typeclass!with laws}
a $P$-algebra whose structure map needs to satisfy the given laws.
The structure map ($p_{M}:P^{M}\rightarrow M$) describes at once
all the typeclass methods and so plays the role of an \emph{evidence
-value} showing that a type $M$ belongs to the $P$-typeclass. If
-$M$ and $N$ are two $P$-algebras and a function $f^{:M\rightarrow N}$
+value} showing that a type $M$ belongs to the FM-typeclass. If $M$
+and $N$ are two $P$-algebras and a function $f^{:M\rightarrow N}$
is a $P$-algebra morphism then we say that $f$ \textsf{``}preserves the
-$P$-typeclass operations\textsf{''}.
+FM-typeclass operations\textsf{''}.
The next step is to generalize the free monoid construction to a \textsf{``}free
-$P$-typeclass\textsf{''} construction. We have seen that there are several
+FM-typeclass\textsf{''} construction. We have seen that there are several
versions, or \textsf{``}encodings\textsf{''} as we called them, of the free monoid.
Different encodings satisfy different subsets of the monoid laws.
By analogy with the free monoid, we list the expected properties of
-an \textsf{``}encoding\textsf{''} of a free $P$-typeclass:
+an \textsf{``}encoding\textsf{''} of a free FM-typeclass:
\begin{itemize}
\item We expect to have a type constructor $E^{T}$ that wraps an arbitrary
-type $T$ and produces a $P$-typeclass instance automatically. (However,
-that $P$-typeclass instance may not obey all of the typeclass laws.)
+type $T$ and produces an FM-typeclass instance automatically. (However,
+that FM-typeclass instance may not obey all of the typeclass laws.)
\item We should be able to convert values of type $T$ into the type $E^{T}$;
in other words, there should be a function of type $T\rightarrow E^{T}$.
-\item Values of type $E^{T}$ represent \textsf{``}$P$-typeclass programs\textsf{''}, that
+\item Values of type $E^{T}$ represent \textsf{``}FM-typeclass programs\textsf{''}, that
is, unevaluated expression trees with primitive values of type $T$.
So, we need a \textsf{``}runner\textsf{''} for evaluating those expression trees into
values of a specific type $C$, as long as a function of type $T\rightarrow C$
-is given. Here, $C$ must be an instance of the $P$-typeclass. The
+is given. Here, $C$ must be an instance of the FM-typeclass. The
\textsf{``}runner\textsf{''} should have the type signature:
\[
\text{run}_{E}^{T,C}:(T\rightarrow C)\rightarrow E^{T}\rightarrow C\quad.
@@ -3593,13 +3890,13 @@ \subsubsection{Statement \label{subsec:Statement-category-of-P-algebras}\ref{sub
be the unique $P$-algebra morphism of that type, at least for all
$C$ that belong to the typeclass.
-We now define a free $P$-typeclass encoding by making these expectations
+We now define a free FM-typeclass encoding by making these expectations
precise:
\subsubsection{Definition \label{subsec:Definition-free-P-typeclass-encoding}\ref{subsec:Definition-free-P-typeclass-encoding}}
-Given a functor $P$, a \textbf{free} $P$\textbf{-typeclass} \textbf{encoding}
-is a functor $E$ such that:
+Given a structure functor $P$, a \textbf{free} FM-\textbf{typeclass}
+\textbf{encoding} is a functor $E$ such that:
\textbf{(a)} For any type $T$, the type $E^{T}$ is a $P$-algebra
with the structure map $p_{E}^{T}:P^{E^{T}}\rightarrow E^{T}$ natural
@@ -3612,9 +3909,9 @@ \subsubsection{Definition \label{subsec:Definition-free-P-typeclass-encoding}\re
is a $P$-algebra morphism.
\textbf{(b)} The function $p_{E}^{T}$ for specific types $T$ may
-obey some (or none) of the laws of the $P$-typeclass. There is only
+obey some (or none) of the laws of the FM-typeclass. There is only
a finite number of typeclass laws; so we may consider the largest
-subset of the $P$-typeclass laws obeyed by $p_{E}^{T}$ for \emph{all}
+subset of the FM-typeclass laws obeyed by $p_{E}^{T}$ for \emph{all}
$T$. We call that subset \textsf{``}the laws \textbf{assured by} $E$\textsf{''}
or \textsf{``}the laws obeyed by $E^{T}$ for all $T$\textsf{''}. (Typically, $E^{T}$
will obey the same set of laws for almost all types $T$. We will
@@ -3626,8 +3923,8 @@ \subsubsection{Definition \label{subsec:Definition-free-P-typeclass-encoding}\re
\textbf{(d)} There exists an \textsf{``}evaluator\textsf{''} function ($\text{eval}_{E}^{C}:E^{C}\rightarrow C$),
where $C$ is required to be a $P$-algebra whose structure map $p_{C}:P^{C}\rightarrow C$
-obeys all the $P$-typeclass laws assured by $E$. To be precise,
-the evaluator function depends on $p_{C}$ and has the full type signature
+obeys all the FM-typeclass laws assured by $E$. To be precise, the
+evaluator function depends on $p_{C}$ and has the full type signature
$(P^{C}\rightarrow C)\rightarrow E^{C}\rightarrow C$. For brevity,
we will write $\text{eval}_{E}^{C}$ instead of $\text{eval}_{E}^{C}(p_{C})$,
making the argument $p_{C}$ implicit.
@@ -3642,11 +3939,11 @@ \subsubsection{Definition \label{subsec:Definition-free-P-typeclass-encoding}\re
\end{align}
The requirement that $C$ should obey \textsf{``}all\textsf{''} the laws assured by
-$E$ means that if a $P$-typeclass law (such as an identity law,
-an associativity law, etc.) is satisfied by $E^{T}$ for all $T$
-then that law must also hold for $C$. (It is acceptable if the type
-$C$ obeys \emph{more} laws than assured by $E$. Section~\ref{subsec:Describing-laws-of-P-typeclasses-as-values}
-will describe $P$-typeclass laws in more detail, but we do not yet
+$E$ means that if an FM-typeclass law (such as an identity law, an
+associativity law, etc.) is satisfied by $E^{T}$ for all $T$ then
+that law must also hold for $C$. (It is acceptable if the type $C$
+obeys \emph{more} laws than assured by $E$. Section~\ref{subsec:Describing-laws-of-P-typeclasses-as-values}
+will describe FM-typeclass laws in more detail, but we do not yet
need the techniques developed there.)
\textbf{(e)} The evaluator function $\text{eval}_{E}^{C}$ has a uniqueness
@@ -3656,11 +3953,11 @@ \subsubsection{Definition \label{subsec:Definition-free-P-typeclass-encoding}\re
The uniqueness property of the evaluator reflects a programmer\textsf{'}s expectation
that there is only one correct way of running (i.e., evaluating) a
-free $P$-typeclass program while preserving the typeclass\textsf{'}s operations.
-However, in practice we need to evaluate not only $P$-typeclass programs
+free FM-typeclass program while preserving the typeclass\textsf{'}s operations.
+However, in practice we need to evaluate not only FM-typeclass programs
of type $E^{C}$ where $C$ is a $P$-algebra and already belongs
-to the typeclass. The usefulness of a free $P$-typeclass construction
-is in supporting $P$-typeclass programs of type $E^{T}$, where $T$
+to the typeclass. The usefulness of a free FM-typeclass construction
+is in supporting FM-typeclass programs of type $E^{T}$, where $T$
is an arbitrary type. To \textsf{``}run\textsf{''} such a program means to evaluate
the typeclass operations into a value of type $C$ (where $C$ already
belongs to the typeclass). For that, we need a function of type $E^{T}\rightarrow C$.
@@ -3672,14 +3969,14 @@ \subsubsection{Definition \label{subsec:Definition-free-P-typeclass-encoding}\re
\]
As long as we are able to map values of $T$ into $C$ (using any
given function $r$ of type $T\rightarrow C$), the \textsf{``}universal runner\textsf{''}
-will evaluate a free $P$-typeclass program of type $E^{T}$ and compute
+will evaluate a free FM-typeclass program of type $E^{T}$ and compute
a result value of type $C$.
The \textsf{``}universal runner\textsf{''} also has a uniqueness property:
\subsubsection{Statement \label{subsec:Statement-some-properties-of-free-P-typeclass-encoding}\ref{subsec:Statement-some-properties-of-free-P-typeclass-encoding}}
-Suppose $E$ is a free $P$-typeclass encoding, $C$ is a $P$-algebra
+Suppose $E$ is a free FM-typeclass encoding, $C$ is a $P$-algebra
that obeys all the laws assured by $E$, and $T$ is any type (not
necessarily a $P$-algebra).
@@ -3730,21 +4027,21 @@ \subsubsection{Statement \label{subsec:Statement-some-properties-of-free-P-typec
\end{align*}
$\square$
-It is important that the definition of a free $P$-typeclass encoding
+It is important that the definition of a free FM-typeclass encoding
$E$ does not require that the free instances $E^{T}$ should obey
-\emph{all} of the $P$-typeclass laws. For instance, we have seen
-that the raw tree encoding of free monads, free monoids, and other
-typeclasses does not obey any of the relevant laws. Because this does
-\emph{not} lead to problems in practical programming, our definition
-of \textsf{``}free $P$-typeclass encodings\textsf{''} admits encodings that obey
-only a subset of typeclass laws (or even none of the laws).
+\emph{all} of the FM-typeclass laws. For instance, we have seen that
+the raw tree encoding of free monads, free monoids, and other typeclasses
+does not obey any of the relevant laws. Because this does \emph{not}
+lead to problems in practical programming, our definition of \textsf{``}free
+FM-typeclass encodings\textsf{''} admits encodings that obey only a subset
+of typeclass laws (or even none of the laws).
The next step is to generalize the raw tree encoding from \lstinline!Monoid!
-to an arbitrary $P$-typeclass and to show that it satisfies the definition
-of a \textsf{``}free $P$-typeclass encoding\textsf{''}. Although the raw tree encoding
+to an arbitrary FM-typeclass and to show that it satisfies the definition
+of a \textsf{``}free FM-typeclass encoding\textsf{''}. Although the raw tree encoding
does not satisfy any typeclass laws, it gives us a valid and usable
encoding that we can use as a starting point to develop other, more
-concise encodings for a free $P$-typeclass.
+concise encodings for a free FM-typeclass.
The raw tree encoding of a free monoid (see Section~\ref{subsec:Free-monoids})
has the type:
@@ -3757,8 +4054,8 @@ \subsubsection{Statement \label{subsec:Statement-some-properties-of-free-P-typec
values of the free monoid type. The structure functor $P$ describes
two of these three ways. This suggests to rewrite the definition of
$\text{FMR}^{T}$ as $\text{FMR}^{T}\triangleq T+P^{\text{FMR}^{T}}$.
-We can now generalize to arbitrary $P$-typeclasses and define the
-raw tree encoding of a free $P$-typeclass (denoted by $\text{FPR}^{T}$)
+We can now generalize to arbitrary FM-typeclasses and define the raw
+tree encoding of a free FM-typeclass (denoted by $\text{FPR}^{T}$)
as:
\[
\text{FPR}^{T}\triangleq T+P^{\text{FPR}^{T}}\quad.
@@ -3773,7 +4070,7 @@ \subsubsection{Statement \label{subsec:Statement-some-properties-of-free-P-typec
\subsubsection{Statement \label{subsec:Statement-free-P-typeclass-raw-tree-encoding}\ref{subsec:Statement-free-P-typeclass-raw-tree-encoding}}
The free monad on $P$, denoted by $\text{FPR}^{T}\triangleq T+P^{\text{FPR}^{T}}$,
-is a free $P$-typeclass encoding. The monad\textsf{'}s \lstinline!flatten!
+is a free FM-typeclass encoding. The monad\textsf{'}s \lstinline!flatten!
method is the same as \lstinline!eval! applied to an argument of
type \lstinline!FPR[FPR[T]]!.
@@ -3906,7 +4203,7 @@ \subsubsection{Statement \label{subsec:Statement-free-P-typeclass-raw-tree-encod
\end{align*}
The two code matrices are now equal due to the assumed law $p_{C}\bef g=g^{\uparrow P}\bef p_{D}$.
-\textbf{(d)} For a given type $C$ with $P$-typeclass instance $p_{C}:P^{C}\rightarrow C$,
+\textbf{(d)} For a given type $C$ with FM-typeclass instance $p_{C}:P^{C}\rightarrow C$,
suppose a function $f:\text{FPR}^{C}\rightarrow C$ satisfies the
left identity law and is a $P$-algebra morphism:
\[
@@ -3946,10 +4243,10 @@ \subsubsection{Statement \label{subsec:Statement-free-P-typeclass-raw-tree-encod
are equal. $\square$
As we will now show, \lstinline!FPR!\textsf{'}s \lstinline!flatten! function
-is a $P$-algebra morphism; in other words, it preserves the $P$-typeclass
-operations. So, it is not useful to apply the free $P$-typeclass
-construction twice, as the result can be reduced to a single layer
-of \lstinline!FPR[T]! while preserving the operations.
+is a $P$-algebra morphism; in other words, it preserves the FM-typeclass
+operations. So, it is not useful to apply the free FM-typeclass construction
+twice, as the result can be reduced to a single layer of \lstinline!FPR[T]!
+while preserving the operations.
\subsubsection{Statement \label{subsec:Statement-free-P-typeclass-monad}\ref{subsec:Statement-free-P-typeclass-monad}}
@@ -3967,12 +4264,12 @@ \subsubsection{Statement \label{subsec:Statement-free-P-typeclass-monad}\ref{sub
$\square$
It is not accidental that the raw tree encoding ($\text{FPR}^{T}$)
-is a monad. It turns out that \emph{all} free $P$-typeclass encodings
+is a monad. It turns out that \emph{all} free FM-typeclass encodings
are monads (although not necessarily free monads):
\subsubsection{Statement \label{subsec:Statement-free-typeclass-encoding-is-a-monad}\ref{subsec:Statement-free-typeclass-encoding-is-a-monad}}
-Any free $P$-typeclass encoding $E$ satisfying Definition~\ref{subsec:Definition-free-P-typeclass-encoding}
+Any free FM-typeclass encoding $E$ satisfying Definition~\ref{subsec:Definition-free-P-typeclass-encoding}
is a monad. The monad $E$\textsf{'}s \lstinline!flatten! function ($\text{ftn}_{E}$)
is equal to the unique $P$-algebra morphism $\text{eval}_{E}^{E^{A}}$
between $P$-algebras $E^{E^{A}}$ and $E^{A}$. The $P$-algebra
@@ -4042,10 +4339,10 @@ \subsubsection{Statement \label{subsec:Statement-free-typeclass-encoding-is-a-mo
\end{align*}
$\square$
-\subsection{Describing laws of $P$-typeclasses as values\label{subsec:Describing-laws-of-P-typeclasses-as-values}}
+\subsection{Describing laws of FM-typeclasses as values\label{subsec:Describing-laws-of-P-typeclasses-as-values}}
Usually, typeclasses impose laws on their methods. We will now develop
-a \textsf{``}first-class\textsf{''} description of $P$-typeclass laws: each law will
+a \textsf{``}first-class\textsf{''} description of FM-typeclass laws: each law will
be represented by a value of a certain type. To make sure we have
really found a representation that adequately captures our understanding
of what typeclass laws are, we will show three type formulas for the
@@ -4087,7 +4384,7 @@ \subsection{Describing laws of $P$-typeclasses as values\label{subsec:Describing
The data in the pair $(\oplus,e)$ is equivalent to a single value
of type $P^{A}\rightarrow A$, where $P^{A}\triangleq\bbnum 1+A\times A$
for the \lstinline!Monoid! typeclass. For other typeclasses, $P$
-will be different. To generalize to arbitrary $P$-typeclasses, let
+will be different. To generalize to arbitrary FM-typeclasses, let
us express the laws as much as possible through $P$ alone. For instance,
the type of the functions $f_{1}$ and $f_{2}$ can be written as
$(P^{A}\rightarrow A)\times A\times A\times A\rightarrow A$. The
@@ -4113,8 +4410,8 @@ \subsection{Describing laws of $P$-typeclasses as values\label{subsec:Describing
needed to formulate a law.
Now we are ready to generalize the definition of the \lstinline!Monoid!
-laws to other $P$-typeclasses. A $P$-typeclass may impose zero or
-more laws. Each law is represented by a function of type $\text{LawF}_{P}$:
+laws to other FM-typeclasses. An FM-typeclass may impose zero or more
+laws. Each law is represented by a function of type $\text{LawF}_{P}$:
\begin{equation}
\text{LawF}_{P}\triangleq\forall A.\,(P^{A}\rightarrow A)\times(\text{Int}\rightarrow A)\rightarrow A\times A\quad.\label{eq:P-typeclass-law-type}
\end{equation}
@@ -4133,7 +4430,7 @@ \subsection{Describing laws of $P$-typeclasses as values\label{subsec:Describing
Another approach to describing typeclass laws is by viewing the two
sides of a law as expression trees. Recall that the raw tree encoding
-of a free $P$-typeclass (which we denoted by $\text{FPR}^{T}$) is
+of a free FM-typeclass (which we denoted by $\text{FPR}^{T}$) is
a type of unevaluated expression trees with leaf values of type $T$
and operations from the functor $P$. We can use a pair of values
of type $\text{FPR}^{T}$ to represent two sides of the law. Given
@@ -4199,7 +4496,7 @@ \subsection{Describing laws of $P$-typeclasses as values\label{subsec:Describing
\end{lstlisting}
We can now generalize the type of expression trees from \lstinline!Monoid!
-to an arbitrary $P$-typeclass. The two sides of the law are functions
+to an arbitrary FM-typeclass. The two sides of the law are functions
that take as arguments one or more arbitrary values of type $T$ and
will return a value of type $\text{FPR}^{T}$. In order to be able
to describe any number of arbitrary values of type $T$, we use an
@@ -4212,10 +4509,10 @@ \subsection{Describing laws of $P$-typeclasses as values\label{subsec:Describing
\end{equation}
A given value \lstinline!et: LawET! specifies a law through the following
-computation: Choose a type $T$ with $P$-typeclass evidence value
-$p_{T}:P^{T}\rightarrow T$. First, we apply \lstinline!et! to an
-arbitrary function \lstinline!v: Int => T! and obtain a pair \lstinline!(lhs, rhs)!
-of expression trees of type \lstinline!FPR[T]!:
+computation: Choose a type $T$ with FM-typeclass evidence value $p_{T}:P^{T}\rightarrow T$.
+First, we apply \lstinline!et! to an arbitrary function \lstinline!v: Int => T!
+and obtain a pair \lstinline!(lhs, rhs)! of expression trees of type
+\lstinline!FPR[T]!:
\begin{lstlisting}
val v: Int => T = ...
val (lhs: FPR[T], rhs: FPR[T]) = et(v)
@@ -4264,7 +4561,7 @@ \subsection{Describing laws of $P$-typeclasses as values\label{subsec:Describing
In this way, a pair of values of type \lstinline!FMR[Int]! encodes
the monoid associativity law.
-Generalizing this to arbitrary $P$-typeclasses, we obtain the type
+Generalizing this to arbitrary FM-typeclasses, we obtain the type
$\text{FPR}^{\text{Int}}\times\text{FPR}^{\text{Int}}$. Each value
of that type represents a possible typeclass law. The integer-valued
indices correspond to different arbitrary variables used in the two
@@ -4322,7 +4619,7 @@ \subsubsection{Statement \label{subsec:Statement-equivalence-law-function-law-ex
within a particular derivation or proof. It is usually easier to work
with the type $\text{FPR}^{\text{Int}}\times\text{FPR}^{\text{Int}}$.
-It turns out that laws of a $P$-typeclass are closely connected with
+It turns out that laws of an FM-typeclass are closely connected with
$P$-algebra morphisms. In particular, $P$-algebra morphisms preserve
the typeclass laws and hide the law violations, in the precise sense
explained in the following statement.
@@ -4336,7 +4633,7 @@ \subsubsection{Statement \label{subsec:Statement-P-algebra-morphisms-and-laws}\r
\textbf{(a)} Suppose that the law holds for $M$ and $\phi$ is \emph{surjective}.
Then the same law also holds for $N$. In this sense, surjective $P$-algebra
-morphisms \textsf{``}preserve\textsf{''} the $P$-typeclass laws.
+morphisms \textsf{``}preserve\textsf{''} the FM-typeclass laws.
\textbf{(b)} Suppose the law holds for $N$ but \emph{not} for $M$.
Suppose a violation of the law for $M$ is found using a specific
@@ -4350,7 +4647,7 @@ \subsubsection{Statement \label{subsec:Statement-P-algebra-morphisms-and-laws}\r
l_{1}\triangleright v^{\uparrow\text{FPR}}\bef\text{eval}_{\text{FPR}}^{M}\bef\phi=l_{2}\triangleright v^{\uparrow\text{FPR}}\bef\text{eval}_{\text{FPR}}^{M}\bef\phi\quad.\label{eq:p-typeclass-law-violation-hidden}
\end{equation}
In this sense, a $P$-algebra morphism \textsf{``}hides\textsf{''} violations of the
-$P$-typeclass laws.
+FM-typeclass laws.
\subparagraph{Proof}
@@ -4411,24 +4708,24 @@ \subsubsection{Statement \label{subsec:Statement-P-algebra-morphisms-and-laws}\r
typeclass operations (i.e., it is a $P$-algebra morphism). Then Statement~\ref{subsec:Statement-P-algebra-morphisms-and-laws}(b)
shows that law violations no longer exist after the runner is applied.
We have proved this explicitly for our free monad DSL in Section~\ref{subsec:A-first-recipe-monadic-dsl}.
-Now we see that this is a general property that applies to all $P$-typeclasses.
+Now we see that this is a general property that applies to all FM-typeclasses.
It is safe to use a free typeclass encoding (even if it violates some
laws) as long as its runner preserves the typeclass operations and
the target type is a lawful typeclass member. In the next section
we will study such \textsf{``}partially lawful\textsf{''} free typeclass encodings
in more detail.
-\subsection{Free $P$-typeclasses that satisfy a subset of the laws\label{subsec:Free--typeclasses-that-satisfy-laws}}
+\subsection{Free FM-typeclasses that satisfy a subset of the laws\label{subsec:Free--typeclasses-that-satisfy-laws}}
In Section~\ref{subsec:Free-monoids}, we have seen four different
encodings of the free monoid (denoted by \lstinline!F1!, \lstinline!F2!,
\lstinline!F3!, and \lstinline!F4!). It turns out that all those
encodings satisfy the requirements of Definition~\ref{subsec:Definition-free-P-typeclass-encoding},
although they obey different subsets of the laws of monoids. We will
-now generalize that situation to $P$-typeclasses and study the properties
-of free $P$-typeclass constructions that satisfy only a subset of
-the typeclass\textsf{'}s laws. The resulting theory will make it simpler to
-prove that a given type constructor $E$ is indeed a valid free $P$-typeclass
+now generalize that situation to FM-typeclasses and study the properties
+of free FM-typeclass constructions that satisfy only a subset of the
+typeclass\textsf{'}s laws. The resulting theory will make it simpler to prove
+that a given type constructor $E$ is indeed a valid free FM-typeclass
encoding as specified by Definition~\ref{subsec:Definition-free-P-typeclass-encoding}.
One important question is whether a free typeclass encoding $E^{T}$
@@ -4468,20 +4765,20 @@ \subsection{Free $P$-typeclasses that satisfy a subset of the laws\label{subsec:
\subsubsection{Statement \label{subsec:Statement-free-typeclass-more-laws}\ref{subsec:Statement-free-typeclass-more-laws}}
-Let $E$ be any free $P$-typeclass encoding.
+Let $E$ be any free FM-typeclass encoding.
\textbf{(a)} If types $T$, $U$ are such that a surjective function
-$f:T\rightarrow U$ exists then $E^{U}$ obeys all the $P$-typeclass
+$f:T\rightarrow U$ exists then $E^{U}$ obeys all the FM-typeclass
laws that $E^{T}$ obeys. (A \textsf{``}larger\textsf{''} type $E^{T}$ satisfies
at least as many laws as a \textsf{``}smaller\textsf{''} type $E^{U}$.)
\textbf{(b)} If $E$ is a polynomial functor and $E^{\text{Int}\times\text{Int}}$
-obeys some law of the $P$-typeclass then $E^{T}$ obeys that law
-for all types $T$.
+obeys some law of the FM-typeclass then $E^{T}$ obeys that law for
+all types $T$.
\textbf{(c)} If $E$ is a polynomial functor and $E^{\text{Int}}$
-obeys some law of the $P$-typeclass then $E^{T}$ obeys that law
-for all types $T$.
+obeys some law of the FM-typeclass then $E^{T}$ obeys that law for
+all types $T$.
It follows that the set of laws \textsf{``}ensured by\textsf{''} $E$ are just the
laws obeyed by $E^{\text{Int}}$.
@@ -4494,7 +4791,7 @@ \subsubsection{Statement \label{subsec:Statement-free-typeclass-more-laws}\ref{s
due to Statement~\ref{subsec:f-Statement-functor-preserves-injective}.
The function $\phi$ is a $P$-algebra morphism due to Definition~\ref{subsec:Definition-free-P-typeclass-encoding}(a).
So, Statement~\ref{subsec:Statement-P-algebra-morphisms-and-laws}(a)
-is applicable and gives the result that $E^{U}$ obeys all the $P$-typeclass
+is applicable and gives the result that $E^{U}$ obeys all the FM-typeclass
laws that $E^{T}$ obeys.
\textbf{(b)} Given a type $T$, a law $l_{1}\times l_{2}:\text{FPR}^{\text{Int}}\times\text{FPR}^{\text{Int}}$,
@@ -4566,15 +4863,15 @@ \subsubsection{Statement \label{subsec:Statement-free-typeclass-more-laws}\ref{s
for natural numbers). $\square$
The restriction to polynomial functors $E$ is not a limitation in
-practice. All known $P$-typeclasses have only a finite set of operations,
+practice. All known FM-typeclasses have only a finite set of operations,
and each operation has a fixed and finite number of arguments. The
functor $P$ describing those operations will be always polynomial,
and so will be the corresponding functor $E$.
-The next statement shows that a functor $E$ is a free $P$-typeclass
+The next statement shows that a functor $E$ is a free FM-typeclass
encoding if it has an injective map into the raw tree encoding (\lstinline!FPR!)
and has certain additional properties. This statement helps us validate
-free $P$-typeclass encodings with less work than by using Definition~\ref{subsec:Definition-free-P-typeclass-encoding}
+free FM-typeclass encodings with less work than by using Definition~\ref{subsec:Definition-free-P-typeclass-encoding}
directly.
\subsubsection{Statement \label{subsec:Statement-compatible-retract-of-free-monad}\ref{subsec:Statement-compatible-retract-of-free-monad}}
@@ -4602,14 +4899,14 @@ \subsubsection{Statement \label{subsec:Statement-compatible-retract-of-free-mona
by $\text{ftn}_{E}\triangleq\text{in}_{E}^{E^{T}}\bef\text{eval}_{\text{FPR}}^{E^{T}}$
is a $P$-algebra morphism (even though $\text{in}_{E}$ is not!).
-5. The $P$-algebra $E^{T}$ satisfies some (or all) of the $P$-typeclass
+5. The $P$-algebra $E^{T}$ satisfies some (or all) of the FM-typeclass
laws but \emph{no other} laws. {*}{*}{*}This is misleading, as in
fact $E^{T}$ does satisfy more laws for some $T$; say for $T=\bbnum 0$.
How do we actually use item 5 as an assumption?{*}{*}{*}To formulate
this requirement precisely, we use law expressions $e:\text{FPR}^{\text{Int}}\times\text{FPR}^{\text{Int}}$
-for describing $P$-typeclass laws (see Section~\ref{subsec:Describing-laws-of-P-typeclasses-as-values}).
-We say that $E^{T}$ obeys \textsf{``}no other laws than those of the $P$-typeclass\textsf{''}
-if for any $P$-algebra $C$ that obeys all the $P$-typeclass laws
+for describing FM-typeclass laws (see Section~\ref{subsec:Describing-laws-of-P-typeclasses-as-values}).
+We say that $E^{T}$ obeys \textsf{``}no other laws than those of the FM-typeclass\textsf{''}
+if for any $P$-algebra $C$ that obeys all the FM-typeclass laws
and for any $e:\text{FPR}^{\text{Int}}\times\text{FPR}^{\text{Int}}$
whose corresponding $e$-law holds for $E^{T}$, the same $e$-law
will also hold for $C$. (A counterexample is an $E^{T}$ that satisfies
@@ -4621,11 +4918,11 @@ \subsubsection{Statement \label{subsec:Statement-compatible-retract-of-free-mona
If assumptions 1-5 hold then:
-\textbf{(a)} The functor $E$ is a free $P$-typeclass encoding. When
+\textbf{(a)} The functor $E$ is a free FM-typeclass encoding. When
the function $\text{in}_{E}$ is itself a $P$-algebra morphism then
the encoding $E$ will be \emph{equivalent} to \lstinline!FPR!. (This
is why we do \emph{not} require $\text{in}_{E}^{T}$ to be a $P$-algebra
-morphism. Then we are able to describe free $P$-typeclass encodings
+morphism. Then we are able to describe free FM-typeclass encodings
$E$ that are different from $\text{FPR}$.)
\textbf{(b)} The universal evaluator $\text{eval}_{E}^{C}$ does not
@@ -4660,19 +4957,19 @@ \subsubsection{Statement \label{subsec:Statement-compatible-retract-of-free-mona
We find that we must have $g_{E}^{T}=\text{id}$. It means that the
$P$-algebra morphisms $\text{in}_{E}^{T}$ and $g$ are inverses
of each other and give a $P$-algebra \emph{isomorphism} (a type equivalence
-that preserves the $P$-typeclass operations) between $E^{T}$ and
-$\text{FPR}^{T}$. So, $E^{T}$ is equivalent to the raw tree encoding
-($\text{FPR}^{T}$) when $\text{in}_{E}$ is a $P$-algebra morphism.
+that preserves the FM-typeclass operations) between $E^{T}$ and $\text{FPR}^{T}$.
+So, $E^{T}$ is equivalent to the raw tree encoding ($\text{FPR}^{T}$)
+when $\text{in}_{E}$ is a $P$-algebra morphism.
-To show that $E$ is a $P$-typeclass encoding, we look at the conditions
+To show that $E$ is an FM-typeclass encoding, we look at the conditions
in Definition~\ref{subsec:Definition-free-P-typeclass-encoding}.
Conditions (a) and (b) of Definition~\ref{subsec:Definition-free-P-typeclass-encoding}
are satisfied by our assumptions 1 and 2.
To verify condition (c), we assume that $C$ is any $P$-algebra that
-obeys all the $P$-typeclass laws that $E$ obeys. We then define
-$\text{eval}_{E}^{C}$ via $\text{eval}_{\text{FPR}}^{C}$:
+obeys all the FM-typeclass laws that $E$ obeys. We then define $\text{eval}_{E}^{C}$
+via $\text{eval}_{\text{FPR}}^{C}$:
\[
\text{eval}_{E}^{C}:E^{C}\rightarrow C\quad,\quad\quad\text{eval}_{E}^{C}\triangleq\text{in}_{E}^{C}\bef\text{eval}_{\text{FPR}}^{C}\quad.
\]
@@ -4796,11 +5093,11 @@ \subsubsection{Statement \label{subsec:Statement-compatible-retract-of-free-mona
obeying the left identity law, namely $\text{eval}_{E}^{C}$. So,
$\text{eval}_{E}^{\prime C}=\text{eval}_{E}^{C}$. $\square$
-\subsection{Imposing laws of $P$-typeclasses via monad algebras\label{subsec:Imposing-laws-of-P-typeclasses-via-monad-algebras}}
+\subsection{Imposing laws of FM-typeclasses via monad algebras\label{subsec:Imposing-laws-of-P-typeclasses-via-monad-algebras}}
We have shown in Statement~\ref{subsec:Statement-free-typeclass-encoding-is-a-monad}
-that any free $P$-typeclass encoding $E$ is always a monad. It turns
-out that we may may use $E$\textsf{'}s monad methods to impose $P$-typeclass
+that any free FM-typeclass encoding $E$ is always a monad. It turns
+out that we may may use $E$\textsf{'}s monad methods to impose FM-typeclass
laws on a given $P$-algebra. The required technique is based on the
notion of a \textsf{``}\index{monad algebra}monad algebra\textsf{''} that comes from
category theory:
@@ -4824,6 +5121,9 @@ \subsubsection{Definition \label{subsec:Definition-monad-algebra}\ref{subsec:Def
The monad algebra\textsf{'}s laws require a certain kind of compatibility between
the structure map $s$ and the monad $E$\textsf{'}s methods.
+{*}{*}{*} How does a monad algebra impose laws? How to write a law
+as explicit equation, given E? give examples.
+
Note that for any monad $E$ and any type $T$, we have the property
that $E^{T}$ is automatically an $E$-functor algebra via the \lstinline!flatten!
method ($\text{ftn}_{E}:E^{E^{T}}\rightarrow E^{T}$). The $E$-monad
@@ -4836,29 +5136,29 @@ \subsubsection{Definition \label{subsec:Definition-monad-algebra}\ref{subsec:Def
{*}{*}{*}Give an example with free semigroups or free monoids that
shows how the monad algebra laws enforce the laws of the typeclass.{*}{*}{*}
-When any type $E^{T}$ is a $P$-functor algebra, we have a special
-relationship between $E$-monad algebras and $P$-functor algebras
-(which we will call for brevity just $P$-algebras):
+When $E^{T}$ is a $P$-functor algebra for all $T$ then one can
+derive a special relationship between $E$-monad algebras and $P$-functor
+algebras (which we will call for brevity just $P$-algebras):
\subsubsection{Statement \label{subsec:Statement-Monad-algebra-is-P-typeclass}\ref{subsec:Statement-Monad-algebra-is-P-typeclass}}
-Suppose $E$ is a free $P$-typeclass encoding according to Definition~\ref{subsec:Definition-free-P-typeclass-encoding}.
+Suppose $E$ is a free FM-typeclass encoding according to Definition~\ref{subsec:Definition-free-P-typeclass-encoding}.
A monad structure for $E$ is given by Statement~\ref{subsec:Statement-free-typeclass-encoding-is-a-monad}.
Then the type of $E$-monad algebras is equivalent to the type of
$P$-algebras that obey all the laws of $E$. In more detail:
{*}{*}{*}rewrite this, using eval instead of run everywhere.{*}{*}{*}
-\textbf{(a)} Any $E$-monad algebra $C$ is also a $P$-algebra. The
-structure map $s:E^{C}\rightarrow C$ is a surjective $P$-algebra
-morphism. Any $E$-monad algebra $C$ will obey all the laws assured
-by $E$.
+\textbf{(a)} Any $E$-monad algebra $C$ is also a $P$-algebra that
+obeys all the laws assured by $E$. The structure map $s:E^{C}\rightarrow C$
+is a surjective $P$-algebra morphism. Any $E$-monad algebra $C$
+will obey all the laws assured by $E$.
-\textbf{(b)} Any $P$-algebra $C$ that satisfies the laws assured
+\textbf{(b)} Any $P$-algebra $C$ that satisfies all the laws assured
by $E$ is also an $E$-monad algebra.
-\textbf{(c)} The $P$-algebras and the $E$-monad algebras are in
-a 1-to-1 correspondence.
+\textbf{(c)} Items \textbf{(a)} and \textbf{(b)} give a a 1-to-1 correspondence
+between $P$-algebras and $E$-monad algebras.
\subparagraph{Proof}
@@ -4878,10 +5178,9 @@ \subsubsection{Statement \label{subsec:Statement-Monad-algebra-is-P-typeclass}\r
{\color{greenunder}P\text{-algebra morphism law~(\ref{eq:P-algebra-morphism-law-of-flatten}) of }\text{ftn}_{E}:}\quad & =\gunderline{\text{pu}_{E}^{\uparrow P}\bef\text{ftn}_{E}^{\uparrow P}}\bef p_{E}^{C}\bef s=(\gunderline{\text{pu}_{E}\bef\text{ftn}_{E}})^{\uparrow P}\bef p_{E}^{C}\bef s\\
{\color{greenunder}\text{left identity law of }E:}\quad & =p_{E}^{C}\bef s\quad.
\end{align*}
-The $E$-monad algebra identity law ($\text{pu}_{E}\bef s=\text{id}$)
-means that $s$ is surjective.
-By Statement~\ref{subsec:Statement-P-algebra-morphisms-and-laws}(a),
+The $E$-monad algebra identity law ($\text{pu}_{E}\bef s=\text{id}$)
+means that $s$ is surjective. By Statement~\ref{subsec:Statement-P-algebra-morphisms-and-laws}(a),
the existence of a surjective $P$-algebra morphism onto $C$ means
that $C$ obeys all the laws assured by $E$.
@@ -4892,7 +5191,8 @@ \subsubsection{Statement \label{subsec:Statement-Monad-algebra-is-P-typeclass}\r
morphism.
\textbf{(b)} If $C$ is a $P$-algebra, we define an $E$-algebra
-structure map $s:E^{C}\rightarrow C$ by:
+structure map $s:E^{C}\rightarrow C$ by:{*}{*}{*}rewrite this proof
+using eval instead of run:
\[
s:E^{C}\rightarrow C\quad,\quad\quad s\triangleq\text{eval}_{E}^{C}\quad.
\]
@@ -4945,7 +5245,7 @@ \subsubsection{Statement \label{subsec:Statement-Monad-algebra-is-P-typeclass}\r
\subsubsection{Exercise \label{subsec:Exercise-P-algebras-monad-algebras}\ref{subsec:Exercise-P-algebras-monad-algebras}\index{exercises}}
-Let $E$ be any free $P$-typeclass encoding by Definition~\ref{subsec:Definition-free-P-typeclass-encoding}.
+Let $E$ be any free FM-typeclass encoding by Definition~\ref{subsec:Definition-free-P-typeclass-encoding}.
\textbf{(a)} If $C$ and $D$ are any given $E$-monad algebras, the
proof of Statement~\ref{subsec:Statement-Monad-algebra-is-P-typeclass}(a)
@@ -4964,13 +5264,13 @@ \subsubsection{Exercise \label{subsec:Exercise-P-algebras-monad-algebras}\ref{su
In the next section, we will use monad algebras to prove that certain
typeclass constructions automatically produce lawful typeclass instances.
-\subsection{Laws for the $P$-typeclass derivation constructions\label{subsec:Laws-for-the-P-typeclass-constructions}}
+\subsection{Laws for the FM-typeclass derivation constructions\label{subsec:Laws-for-the-P-typeclass-constructions}}
In Section~\ref{subsec:P-typeclasses} we have shown certain type
constructions that derive new typeclass instances from previous ones.
-For example, the product of two types that belong to a $P$-typeclass
+For example, the product of two types that belong to an FM-typeclass
will again belong to that typeclass. However, in that chapter we only
-showed that one can compute a $P$-typeclass evidence values for those
+showed that one can compute an FM-typeclass evidence values for those
constructions. Now we have developed a theory that can also prove
that the laws hold automatically for each of those constructions.
This theory justifies automatic typeclass derivation for those cases.
@@ -4982,11 +5282,11 @@ \subsection{Laws for the $P$-typeclass derivation constructions\label{subsec:Law
Instead of dealing with laws explicitly as values, it is more convenient
in these proofs if we impose typeclass laws via monad algebras. As
we have seen in the previous section, a type $T$ is a lawful member
-of a $P$-typeclass if $T$ is an $E$-monad algebra, where the monad
-$E$ is the free $P$-typeclass encoding that assures the laws of
-the typeclass. Using this formulation of laws, it is sufficient to
-prove that a new derived type is again an $E$-monad algebra if so
-are the previously given types.
+of an FM-typeclass if $T$ is an $E$-monad algebra, where the monad
+$E$ is the free FM-typeclass encoding that assures the laws of the
+typeclass. Using this formulation of laws, it is sufficient to prove
+that a new derived type is again an $E$-monad algebra if so are the
+previously given types.
In each of the following statements, $E$ is a fixed monad.
@@ -5151,7 +5451,7 @@ \subsubsection{Statement \label{subsec:Statement-Monad-algebra-exp-1}\ref{subsec
Other than that, we can repeat the proof for part \textbf{(a)} except
for replacing $s(\overline{t})$ by $s$. $\square$
-\subsection{Church encodings of free $P$-typeclasses\label{subsec:Church-encodings-for-free-P-typeclasses}}
+\subsection{Church encodings of free FM-typeclasses\label{subsec:Church-encodings-for-free-P-typeclasses}}
\subsection{Free constructions on more than one generator}
@@ -5578,7 +5878,7 @@ \section{Slides }
Type class $C$ is defined by its operations{\footnotesize{} $C^{X}\rightarrow X$}
(with a suitable $C^{\bullet}$)
-call $C^{\bullet}$ the \textbf{structure functor} of the $P$-typeclass
+call $C^{\bullet}$ the \textbf{structure functor} of the FM-typeclass
$C$
Tree encoding of \textsf{``}free $C$ over $Z$\textsf{''} is recursive, $\text{FreeC}^{Z}\triangleq Z+C^{\text{FreeC}^{Z}}$
@@ -6016,7 +6316,7 @@ \subsubsection{Exercise \label{subsec:Exercise-free-type-2}\ref{subsec:Exercise-
\textsf{``}acts\textsf{''} on $P$ via a function act$:L\rightarrow P\rightarrow P$,
with laws $\text{act}\,x\bef\text{act}\,y=\text{act}\left(x\bef y\right)$
and $\text{act}\left(e_{L}\right)=\text{id}$. - Monoid morphism between
-$L$ and $\text{MF}^{P}$. Show that $\text{Mod}_{L}$ is a $P$-typeclass.
+$L$ and $\text{MF}^{P}$. Show that $\text{Mod}_{L}$ is an FM-typeclass.
Implement a free $L$-module on a type $Z$.
\subsubsection{Exercise \label{subsec:Exercise-free-type-3}\ref{subsec:Exercise-free-type-3}}
diff --git a/sofp-src/tex/sofp-monads.tex b/sofp-src/tex/sofp-monads.tex
index 73e088742..ad37dfaff 100644
--- a/sofp-src/tex/sofp-monads.tex
+++ b/sofp-src/tex/sofp-monads.tex
@@ -10,7 +10,7 @@ \chapter{Computations in functor blocks. II. Semi-monads and monads\label{chap:S
a \lstinline!map! method, filterable type constructors have a \lstinline!filter!
method, and \textbf{semi-monads} are\index{semi-monads} functors
that have a \lstinline!flatMap! method. This chapter begins by developing
-an intuition for the behavior of \lstinline!flatMap!.
+a motivation and an intuition for the use of \lstinline!flatMap!.
\section{Practical use of monads}
@@ -64,8 +64,8 @@ \subsection{Motivation for semi-monads: Nested iteration}
To compute the sum, we need to accumulate all the values from all
the nested lists. So, we need to \textsf{``}flatten\textsf{''} this nested structure
into a simple, non-nested sequence. The standard method for that is
-\lstinline!flatten!, and its combination with \lstinline!map! can
-be replaced by \lstinline!flatMap!:
+\lstinline!flatten!, and its composition with \lstinline!map! is
+known as \lstinline!flatMap!:
\begin{lstlisting}
scala> (1 to 4).map(i => (1 to i).map(j => i * j)).flatten
res1: IndexedSeq[Int] = Vector(1, 2, 4, 3, 6, 9, 4, 8, 12, 16)
@@ -1485,22 +1485,23 @@ \subsection{The \texttt{Reader} monad\label{subsec:The-Reader-monad}}
with the list-like monads whose \lstinline!flatMap! method is motivated
by the requirements of nested iteration. We then looked at tree-like
monads whose \lstinline!flatMap! methods work via tree grafting.
-It turns out that the \lstinline!flatMap! method can be supported
-by many other type constructors useful for various programming tasks
-not necessarily related to nested iteration.
+It turns out that the \lstinline!flatMap! method is supported by
+many other type constructors (not just containers) and may be used
+for various programming tasks not necessarily related to nested iteration.
A general (semi)monad type constructor $L$ no longer represents a
collection of data items. Instead, we regard $L^{A}$ informally as
-a value of type $A$ wrapped in a special \textsf{``}computational effect\textsf{''}.
-We view \textsf{``}computations with an $L$-effect\textsf{''} as functions of type
-$A\rightarrow L^{B}$ (as in \lstinline!flatMap!\textsf{'}s argument type).
-In this view, different monads \textemdash{} such as list-like, pass/fail,
-or tree-like \textemdash{} implement different kinds of effects.
+a value of type $A$ wrapped in type constructor representing a special
+\textsf{``}computational effect\textsf{''}. By \textsf{``}computations with an $L$-effect\textsf{''}
+we simply mean functions of type $A\rightarrow L^{B}$ (as in \lstinline!flatMap!\textsf{'}s
+argument type). In this view, different monads \textemdash{} such
+as list-like, pass/fail, or tree-like \textemdash{} implement different
+kinds of effects.
In this sense, monadic effects are \emph{not} side effects.\index{side effect}
Functions of type $A\rightarrow L^{B}$ are referentially transparent\index{referential transparency}
and behave as values.\index{value-like behavior} Informally, an \textsf{``}$L$-effect\textsf{''}
-describes the information computed by a function of type $A\rightarrow L^{B}$
+describes whatever else is computed by a function of type $A\rightarrow L^{B}$
in addition to a value of type $B$. To make the vague idea of \textsf{``}effect\textsf{''}
concrete, we write the required type of the computation in the form
$A\rightarrow L^{B}$ with a specific type constructor $L$. In this
@@ -1519,7 +1520,7 @@ \subsection{The \texttt{Reader} monad\label{subsec:The-Reader-monad}}
\[
(A\times Z\rightarrow B)\cong(A\rightarrow Z\rightarrow B)\quad,
\]
-which has the form $A\rightarrow L^{B}$ if we define $L^{A}\triangleq Z\rightarrow A$.
+which has the form $A\rightarrow L^{B}$ if we define $L^{B}\triangleq Z\rightarrow B$.
This type constructor is known as the \lstinline!Reader! monad\index{monads!Reader monad@\texttt{Reader} monad}
and is denoted by $\text{Reader}^{Z,A}\triangleq Z\rightarrow A$.
The Scala definition is: \lstinline!type Reader[Z, A] = Z => A!.
@@ -1765,9 +1766,9 @@ \subsection{The \texttt{Writer} monad}
def |+|(other: Logs): Logs = Logs(begin, other.end, message + "\n" + other.message)
} // We assume that timestamps will be monotonically increasing.
\end{lstlisting}
-The type \lstinline!Logs! is not a monoid because its binary operation
-discards some of the input data, so we cannot define an \textsf{``}empty\textsf{''}
-value satisfying the identity laws (see Eq.~(\ref{eq:identity-laws-of-monoid})
+The type \lstinline!Logs! is \emph{not} a monoid because its binary
+operation discards some of the input data, so we cannot define an
+\textsf{``}empty\textsf{''} value satisfying the identity laws (see Eq.~(\ref{eq:identity-laws-of-monoid})
in Example~\ref{subsec:tc-Example-Monoids}).
We can now use the semi-monad \lstinline!Writer[A, Logs]!. Here is
@@ -1926,7 +1927,7 @@ \subsection{The eager/lazy evaluation monad\label{subsec:The-eager-lazy-evaluati
To derive the type constructor we denoted \lstinline!Eval!, note
that lazy values of type $A$ are equivalent to functions of type
$\bbnum 1\rightarrow A$. So, the disjunctive type $\text{Eval}^{A}\triangleq A+\left(\bbnum 1\rightarrow A\right)$
-represents a value that is either lazy or eager:\index{monads!lazy/eager evaluation monad (Eval)@lazy/eager evaluation monad (\texttt{Eval})}
+represents a value that is either lazy or eager:\index{monads!Eval (lazy/eager evaluation monad)@\texttt{Eval} (lazy/eager evaluation monad)}
\begin{lstlisting}
sealed trait Eval[A]
final case class Eager[A](x: A) extends Eval[A]
@@ -4855,8 +4856,8 @@ \subsection{From semi-monads to monads: The identity laws}
\lstinline!flatMap! method, which will \textsf{``}merge\textsf{''} the effects. It
is generally useful to be able to create values with an \textsf{``}empty effect\textsf{''},
such that merging the empty effect leaves other effects unchanged.
-A monad $M$ is a semi-monad that has a method for creating values
-with an \textsf{``}empty effect\textsf{''}. That method is called \lstinline!pure!
+A \textbf{monad} $M$ is a semi-monad that has a method for creating
+values with an \textsf{``}empty effect\textsf{''}. That method is called \lstinline!pure!
(notation $\text{pu}_{M}$):
\begin{wrapfigure}{l}{0.475\columnwidth}%
@@ -4872,15 +4873,18 @@ \subsection{From semi-monads to monads: The identity laws}
\text{pu}_{M}^{A}:A\rightarrow M^{A}\quad.
\]
-To get intuition about the properties of a vaguely defined \textsf{``}empty
-effect\textsf{''}, consider nested iteration over arrays. The \textsf{``}empty effect\textsf{''}
-is an array containing \emph{one} element. An iteration over such
-an array will just need to process that single value. In a functor
-block using arrays, a source line with an \textsf{``}empty effect\textsf{''} (\lstinline!y <- pure(x)!)
-will be equivalent to just \lstinline!y = x! with no iteration. That
-line may occur either before or after another source line. So, we
-need to examine two situations: first, when an empty effect comes
-before another source line:
+To get intuition about the behavior of what we called an \textsf{``}empty
+effect\textsf{''}, consider nested iteration over lists. The \textsf{``}empty effect\textsf{''}
+should correspond to trivial iterations; that is, an iteration through
+a list containing \emph{one} element. Indeed, in a functor block
+using lists, a source line \lstinline!y <- List(x)! is equivalent
+to just \lstinline!y = x! with no extra iterations.
+
+To understand the properties of empty effects more formally, consider
+a functor block with a source line \lstinline!y <- pure(x)!. That
+line may occur either before or after another source line. When an
+empty effect comes before another source line, the code can be simplified
+like this:
\noindent \texttt{\textcolor{blue}{\footnotesize{}}}%
\begin{minipage}[c]{0.475\columnwidth}%
@@ -4973,21 +4977,22 @@ \subsection{From semi-monads to monads: The identity laws}
In fact, \lstinline!pure! is the same method as in the \lstinline!Pointed!
typeclass (Sections~\ref{subsec:Pointed-functors-motivation-equivalence}\textendash \ref{subsec:Pointed-functors:-structural-analysis}).
-So, we could say that a monad is a pointed semi-monad whose \lstinline!pure!
-method obeys the two identity laws~(\ref{eq:monad-left-identity-law-for-flatMap})\textendash (\ref{eq:monad-right-identity-law-for-flatMap}).
+So, a monad is a pointed semi-monad whose \lstinline!pure! method
+obeys the two identity laws~(\ref{eq:monad-left-identity-law-for-flatMap})\textendash (\ref{eq:monad-right-identity-law-for-flatMap}).
Although the \lstinline!pure! method can be replaced by a simpler
\textsf{``}wrapped unit\textsf{''} value ($\text{wu}_{M}$), derivations are easier
when using \lstinline!pure!.
The \lstinline!Pointed! typeclass requires the \lstinline!pure!
method to satisfy the naturality law~(\ref{eq:naturality-law-of-pure}).
-A full monad\textsf{'}s \lstinline!pure! method must also satisfy that naturality
-law, in addition to the two identity laws.
+For the same reason, a monad\textsf{'}s \lstinline!pure! method must also
+satisfy that naturality law (in addition to the two identity laws).
Just as some useful semigroups are not monoids, there exist some useful
semi-monads that are not full monads. A simple example is the \lstinline!Writer!
semi-monad $F^{A}\triangleq A\times W$ whose type $W$ is a semigroup
but not a monoid (see Exercise~\ref{subsec:Exercise-semimonad-not-monad}).
+We will see other examples later in this chapter.
\subsection{The monad identity laws in terms of \texttt{pure} and \texttt{flatten}}
@@ -5037,7 +5042,7 @@ \subsection{The monad identity laws in terms of \texttt{pure} and \texttt{flatte
In the next section, we will give reasons for the names of these laws.
-\subsection{Monad laws in terms of Kleisli functions}
+\subsection{Monad laws in terms of Kleisli functions\label{subsec:Monad-laws-in-Kleisli}}
A \textbf{Kleisli function}\index{Kleisli!functions|textit} is a
function with type signature $A\rightarrow M^{B}$, where $M$ is
@@ -5283,7 +5288,7 @@ \subsubsection{Statement \label{subsec:Statement-equivalence-kleisli-laws-and-fl
The two naturality laws of \lstinline!flatMap! are equivalent to
the three naturality laws of $\diamond_{_{M}}$. We omit those derivations.
-\subsection{Verifying the monad laws using Kleisli functions}
+\subsection{Verifying the monad laws using Kleisli functions\label{subsec:Verifying-the-monad-via-Kleisli-trick}}
When the monad laws are formulated via Kleisli composition, the intuition
behind the laws becomes clearer: they are analogous to the identity
@@ -5294,8 +5299,8 @@ \subsection{Verifying the monad laws using Kleisli functions}
for \lstinline!flatten! has only one. For certain monads, however,
a trick called \index{flipped@\textsf{``}flipped Kleisli\textsf{''} technique|textit}\textbf{flipped
Kleisli} makes direct proofs of laws shorter. That trick applies to
-monads of a function type, such as the continuation and the state
-monads.
+monads of a function type, such as \lstinline!Cont!, \lstinline!State!,
+and some other monads that we will discover later.
\subsubsection{Statement \label{subsec:Statement-continuation-monad-is-lawful}\ref{subsec:Statement-continuation-monad-is-lawful}}
@@ -5417,7 +5422,42 @@ \subsection{Constructions of semi-monads and monads\label{subsec:Structural-anal
by programmers working on specific tasks. Hoping to find systematically
all possible monads, we will now apply structural analysis to semi-monads
and monads. For each type construction, we will prove rigorously that
-the monad laws hold.
+the monad laws hold. The results are summarized in Table~\ref{tab:Constructions-of-monads}.
+
+\begin{table}
+\begin{centering}
+\begin{tabular}{|c|c|c|}
+\hline
+\textbf{\small{}Construction} & \textbf{\small{}Type notation} & \textbf{\small{}Assumptions, results}\tabularnewline
+\hline
+\hline
+{\footnotesize{}fixed type} & {\footnotesize{}$F^{A}\triangleq Z$} & {\footnotesize{}$F$ is a monad if $Z=\bbnum 1$; $F$ is a semi-monad
+for $Z\neq\bbnum 1$}\tabularnewline
+\hline
+{\footnotesize{}identity} & {\footnotesize{}$F^{A}\triangleq A$} & {\footnotesize{}$F$ is a full monad}\tabularnewline
+\hline
+{\footnotesize{}product} & {\footnotesize{}$F^{A}\triangleq P^{A}\times Q^{A}$} & {\footnotesize{}$P$ and $Q$ are (semi-)monads}\tabularnewline
+\hline
+{\footnotesize{}product} & {\footnotesize{}$F^{A}\triangleq A\times P^{A}$} & {\footnotesize{}$F$ is a semi-monad when $P$ is any functor}\tabularnewline
+\hline
+{\footnotesize{}free pointed} & {\footnotesize{}$F^{A}\triangleq A+P^{A}$} & {\footnotesize{}$F$ is a monad when $P$ is a monad}\tabularnewline
+\hline
+{\footnotesize{}function type} & {\footnotesize{}$F^{A}\triangleq Z\rightarrow P^{A}$} & {\footnotesize{}$Z$ is a fixed type, $P$ is a (semi-)monad}\tabularnewline
+\hline
+{\footnotesize{}function type} & {\footnotesize{}$F^{A}\triangleq H^{A}\rightarrow A$} & {\footnotesize{}$F$ is a monad when $H$ is any contrafunctor}\tabularnewline
+\hline
+{\footnotesize{}function type} & {\footnotesize{}$F^{A}\triangleq H^{A}\rightarrow G^{A}$} & {\footnotesize{}$G$ is a (semi-)monad, $H$ is a $G$-filterable
+contrafunctor}\tabularnewline
+\hline
+{\footnotesize{}free monad} & {\footnotesize{}$F^{A}\triangleq A+L^{F^{A}}$} & {\footnotesize{}$L$ is any functor}\tabularnewline
+\hline
+{\footnotesize{}tree semi-monad} & {\footnotesize{}$F^{A}\triangleq L^{A}+L^{F^{A}}$} & {\footnotesize{}$F$ is a semi-monad if $L$ is any functor}\tabularnewline
+\hline
+\end{tabular}
+\par\end{centering}
+\caption{Constructions of semi-monads and monads.\label{tab:Constructions-of-monads}}
+\end{table}
+
\paragraph{Type parameters}
@@ -5826,7 +5866,9 @@ \subsubsection{Statement \label{subsec:Statement-co-product-with-identity-monad}
& A & F^{A}\\
\hline A & \text{id} & \bbnum 0\\
F^{A} & \bbnum 0 & \text{id}
-\end{array}\,=\text{id}\quad,\\
+\end{array}\,=\text{id}\quad,
+\end{align*}
+\begin{align*}
& \text{pu}_{L}^{\uparrow L}\bef\text{ftn}_{L}=\,\begin{array}{|c||ccc|}
& A & F^{A} & F^{L^{A}}\\
\hline A & \text{id} & \bbnum 0 & \bbnum 0\\
@@ -5893,8 +5935,7 @@ \subsubsection{Statement \label{subsec:Statement-co-product-with-identity-monad}
F^{L^{L^{A}}} & \bbnum 0 & \bbnum 0 & \gamma^{\uparrow F}\bef\text{ftn}_{F}
\end{array}\quad.
\end{align*}
-We are ready to verify the associativity law. Simplify both sides
-using matrix compositions:
+We are ready to verify the associativity law:
\begin{align*}
& \text{ftn}_{L}^{\uparrow L}\bef\text{ftn}_{L}=\,\begin{array}{|c||ccc|}
& A & F^{A} & F^{L^{A}}\\
@@ -5907,9 +5948,7 @@ \subsubsection{Statement \label{subsec:Statement-co-product-with-identity-monad}
\hline A & \text{id} & \bbnum 0\\
F^{A} & \bbnum 0 & \text{id}\\
F^{L^{A}} & \bbnum 0 & \gamma^{\uparrow F}\bef\text{ftn}_{F}
-\end{array}
-\end{align*}
-\begin{align*}
+\end{array}\\
& \quad=\,\begin{array}{|c||cc|}
& A & F^{A}\\
\hline A & \text{id} & \bbnum 0\\
@@ -6351,12 +6390,12 @@ \subsubsection{Statement \label{subsec:Statement-monad-construction-4-free-monad
def pure_L[A](a: A): L[A] = Left(a)
def flatMap_L[A, B](la: L[A])(f: A => L[B]): L[B] = la match {
case Left(a) => f(a)
- case Right(fla) => Right(fla.map { (x: L[A]) => flatMap_L(x)(f) }) // Recursive call of flatMap_L.
+ case Right(fla) => Right(fla.map { (x: L[A]) => flatMap_L(x)(f) })
}
def flatten_L[A]: L[L[A]] => L[A] = { // Match on L[L[A]] = Either[Either[A, F[L[A]]], F[L[L[A]]]].
case Left(a) => Left(a)
case Left(Right(fla)) => Right(fla)
- case Right(Right(flla)) => Right(flla.map(x => flatten_L(x))) // Recursive call of flatten_L.
+ case Right(Right(flla)) => Right(flla.map(x => flatten_L(x)))
}
\end{lstlisting}
\[
@@ -6406,8 +6445,8 @@ \subsubsection{Statement \label{subsec:Statement-monad-construction-4-free-monad
F^{L^{L^{L^{A}}}} & \bbnum 0 & \bbnum 0 & \big(\text{ftn}_{L}^{\overline{\uparrow L}}\big)^{\uparrow F}
\end{array}\quad.
\end{align*}
-We can now verify the identity and associativity laws of $\text{pu}_{L}$
-and $\text{ftn}_{L}$. Identity laws:
+We can now verify the laws of $\text{pu}_{L}$ and $\text{ftn}_{L}$.
+Identity laws:
\[
\text{pu}_{L}^{L^{A}}\bef\text{ftn}_{L}=\,\begin{array}{|c||ccc|}
& A & F^{L^{A}} & F^{L^{L^{A}}}\\
@@ -6689,10 +6728,10 @@ \subsubsection{Exercise \label{subsec:Exercise-1-monads-7-not-a-monad}\ref{subse
this is defined by \lstinline!type D[A] = Option[(A, A)]!). Implement
the \lstinline!flatten! and \lstinline!pure! methods for $D$ in
at least two different ways. Show that some of the monad laws fail
-to hold for every implementation.\footnote{There are several implementations of \lstinline!pure! and \lstinline!flatten!
-for $D^{A}\triangleq\bbnum 1+A\times A$, but \emph{none} of them
-obey the monad laws (Hew Wolff, private communication). For details,
-see \texttt{\href{https://stackoverflow.com/questions/49742377/}{https://stackoverflow.com/questions/49742377/}}}
+to hold for every implementation.\footnote{Functors of the form $F^{A}\triangleq\bbnum 1+A\times...\times A$
+are not monads: \emph{none} of the possible implementations of \lstinline!pure!
+and \lstinline!flatten! obey the monad laws (Hew Wolff, private communication).
+For some details, see \texttt{\href{https://stackoverflow.com/questions/49742377/}{https://stackoverflow.com/questions/49742377/}}}
\subsubsection{Exercise \label{subsec:Exercise-1-monads-8}\ref{subsec:Exercise-1-monads-8}}
@@ -7155,12 +7194,12 @@ \subsection{Monads, effects, and runners}
Monads allow us to compose \textsf{``}monadic programs\index{monadic program}\textsf{''}
(i.e., values of type $M^{A}$ for some monad $M$). For list-like
and tree-like monads $M$, a value of type $M^{A}$ represents a collection
-of values of type $A$ and is a result of nested iterations. For a
-pass/fail monad $M$, a value of type $M^{A}$ holds either a result
-of type $A$ or information about a failure. For other monads $M$,
-a monadic program $m:M^{A}$ represents a single value of type $A$
-wrapped by an \textsf{``}effectful wrapper\textsf{''} of some sort. In an application,
-we usually need to extract that value of type $A$ from the \textsf{``}wrapper\textsf{''}.
+of values of type $A$. For a pass/fail monad $M$, a value of type
+$M^{A}$ holds either a result of type $A$ or information about a
+failure. For other monads $M$, a monadic program $m:M^{A}$ represents
+a single value of type $A$ wrapped by an \textsf{``}effectful wrapper\textsf{''}
+of some sort. In an application, we usually need to extract that value
+of type $A$ from the \textsf{``}wrapper\textsf{''}.
To see how this works, consider monads of function type (such as \lstinline!Reader!,
\lstinline!State!, and \lstinline!Cont!). These monads delay their
@@ -7752,7 +7791,7 @@ \subsection{Constructions of polynomial monads\label{subsec:Constructions-of-pol
As an example, consider t the polynomial functor $F^{A}\triangleq\bbnum 1+A\times A$
that \emph{cannot} be made into a monad (Exercise~\ref{subsec:Exercise-1-monads-6}).
-One can also show that $F$ cannot be obtained through the monad constructions
+One can show that $F$ cannot be obtained through the monad constructions
listed above. Indeed, the corresponding polynomial $f(x)=1+x^{2}$
does not contain any first powers of $x$. However, all constructions
either start with a polynomial containing $x$, or add $x$, or take
@@ -7761,10 +7800,9 @@ \subsection{Constructions of polynomial monads\label{subsec:Constructions-of-pol
be subtracted to zero.
By the same logic, we can conclude that $F^{A}\triangleq\bbnum 1+A\times A\times A$
-cannot be obtained through monad constructions. It is likely (although
-this book does not have a proof) that $F^{A}\triangleq\bbnum 1+A\times A\times A$,
-$F^{A}\triangleq\bbnum 1+A\times A\times A\times A$, and all other
-similarly constructed functors are \emph{not} monads.
+cannot be obtained through monad constructions. It is known\footnote{Hew Wolff, private communication (2024).}
+that $F^{A}\triangleq\bbnum 1+A\times A$, $F^{A}\triangleq\bbnum 1+A\times A\times A$,
+and all other similarly constructed functors are \emph{not} monads.
On the other hand, some polynomial functors can be obtained via the
monad constructions in more than one way. A simple example is:
@@ -7813,7 +7851,9 @@ \subsection{Constructions of $M$-filterable functors and contrafunctors\label{su
\end{align*}
This gave us the definitions of $M$-filterable functors and contrafunctors.\index{$M$-filterable contrafunctor}\index{$M$-filterable functor}
-We have shown some examples of $M$-filterable functors in Statement~\ref{subsec:Statement-examples-of-filterable-contrafunctors}.
+The concepts of $M$-filterable functors and contrafunctors are not
+well known and not widely used. To build up intuition, we have shown
+some examples in Statement~\ref{subsec:Statement-examples-of-filterable-contrafunctors}.
Structural analysis can discover other examples of such functors systematically.
As in the case of ordinary filterable functors, it turns out that
we must at the same time analyze $M$-filterable contrafunctors.
@@ -7821,8 +7861,8 @@ \subsection{Constructions of $M$-filterable functors and contrafunctors\label{su
In the following constructions, we assume that $M$ is a fixed, lawful
monad.
-We omit the proofs of all following statements because they are fully
-analogous to the proofs of filterable functor and contrafunctor constructions
+We omit the proofs of all the following statements because they are
+ analogous to the proofs of filterable functor and contrafunctor constructions
in Sections~\ref{subsec:Constructions-of-filterable-functors} and~\ref{subsec:Constructions-of-filterable-contrafunctors}.
In those proofs, we only used the properties of the functions $\text{liftOpt}_{F}$,
which are fully analogous to the properties of the function $\text{lift}_{M,F}$
diff --git a/sofp-src/tex/sofp-reasoning.tex b/sofp-src/tex/sofp-reasoning.tex
index c7a6fa2fe..9f7eb511b 100644
--- a/sofp-src/tex/sofp-reasoning.tex
+++ b/sofp-src/tex/sofp-reasoning.tex
@@ -248,15 +248,15 @@ \subsection{The nine constructions of fully parametric code}
The code notation for this disjunctive function is modeled after the
Scala code:
\[
-\text{compute}^{:\bbnum 1+\text{Int}\rightarrow\bbnum 1+\text{Int}}\triangleq\,\begin{array}{|c||cc|}
+\text{compute}:\bbnum 1+\text{Int}\rightarrow\bbnum 1+\text{Int}\quad,\quad\quad\text{compute}\triangleq\,\begin{array}{|c||cc|}
& \bbnum 1 & \text{Int}\\
\hline \bbnum 1 & \bbnum 0 & \_\rightarrow100\\
\text{Int} & \bbnum 0 & x\rightarrow\frac{x}{2}
\end{array}\quad.
\]
-We will use this example to explain how disjunctive functions are
-written in the matrix notation\index{matrix notation}\index{disjunctive type!matrix notation}.
+We will use this example to explain in detail how disjunctive functions
+are written in the matrix notation\index{matrix notation}\index{disjunctive type!matrix notation}.
Each row of a matrix corresponds to a part of the disjunctive type
matched by one of the \lstinline!case! expressions. The column to
@@ -274,9 +274,8 @@ \subsection{The nine constructions of fully parametric code}
If the return type is not disjunctive, the matrix will have one column.
What are the matrix elements? The idea of the matrix notation is to
-translate the \lstinline!case! expressions line by line. Look at
-the first \lstinline!case! line as if it were a standalone partial
-function:
+represent pattern-matching code, line by line. Look at the first \lstinline!case!
+line as if it were a standalone partial function:
\begin{lstlisting}
{ case None => Some(100) }
\end{lstlisting}
diff --git a/sofp-src/tex/sofp-summary.tex b/sofp-src/tex/sofp-summary.tex
index 5380d1b2a..89f9d45a2 100644
--- a/sofp-src/tex/sofp-summary.tex
+++ b/sofp-src/tex/sofp-summary.tex
@@ -12,7 +12,7 @@ \chapter{Summary of the book\label{chap:Summary-of-the}}
detailed explanations or proofs, referring to the places of the book
where more detail is found.
-\section{Main points and results by chapter}
+\section{Main ideas and results by chapter}
\setcounter{secnumdepth}{1}%
\begin{comment}
@@ -177,26 +177,30 @@ \subsection{Chapter~\ref{chap:Functors,-contrafunctors,-and}}
This chapter begins the second part of the book, which is devoted
to a systematic analysis of various type constructions that produce
-data structures with different properties. The first kind of data
-structure to be analysed is \textsf{``}functors\textsf{''}.
+data structures with certain useful properties. The first kind of
+data structure to be analysed is \textsf{``}functors\textsf{''}.
We begin with a motivation for functors as containers or \textsf{``}wrappers\textsf{''}
-of data. Those containers should have a \lstinline!map! method that
-\textsf{``}lifts\textsf{''} functions of type \lstinline!A => B! into functions of
-type \lstinline!F[A] => F[B]!. We examine a programmer\textsf{'}s expectations
-for the behavior of the \lstinline!map! method for typical containers.
-Those expectations are formulated as mathematical equations (or \textsf{``}laws\textsf{''})
-that an implementation of \lstinline!map! must obey. In this way,
-we arrive at the functor laws: the identity law and the composition
-law.
+of data; a first example is a sequence type such as Scala\textsf{'}s \lstinline!Seq[A]!.
+A typical operation for sequences is a loop over elements of the sequence.
+In functional programming, those loops are implemented by the \lstinline!map!
+method. Generalizing from \lstinline!Seq! to an arbitrary container
+\lstinline!F!, we find that the \lstinline!map! method that \textsf{``}lifts\textsf{''}
+functions of type \lstinline!A => B! into functions of type \lstinline!F[A] => F[B]!.
+We examine a programmer\textsf{'}s expectations for the behavior of the \lstinline!map!
+method for typical containers. Those expectations are formulated as
+mathematical equations (or \textsf{``}laws\textsf{''}) that an implementation of \lstinline!map!
+must obey. In this way, we arrive at the \textsf{``}functor laws\textsf{''}: the identity
+law and the composition law.
Scala supports a special \lstinline!for!/\lstinline!yield! syntax
-for chains of functor operations. In later chapters, we will see how
-this syntax extends to conditionals and nested loops.
+for chains of functor operations. (In later chapters, we will see
+how the \lstinline!for!/\lstinline!yield! syntax can also support
+conditionals and nested loops.)
Looking at examples of some type constructors that \emph{cannot} have
the map method, we find that in certain cases a \lstinline!contramap!
-method can be implemented. This motivates the concept of a contrafunctor
+method can be implemented. This motivates the concept of a \textbf{contrafunctor}\index{contrafunctor}
(short for \textsf{``}contravariant functor\textsf{''}). We show examples where we
implement the \lstinline!map! or the \lstinline!contramap! method
for different type constructors.
@@ -234,7 +238,7 @@ \subsection{Chapter~\ref{chap:Functors,-contrafunctors,-and}}
\subsection{Chapter~\ref{chap:Reasoning-about-code}}
-This book uses certain non-standard notation to write types and code
+This book uses certain non-standard notations to write types and code
more concisely. For instance, type parameters are written as superscripts
($F^{A}$ corresponds to the Scala syntax \lstinline!F[A]!). Functions
lifted via \lstinline!fmap! are denoted by arrows such as $f^{\uparrow F}$.
@@ -254,12 +258,12 @@ \subsection{Chapter~\ref{chap:Reasoning-about-code}}
\subsection{Chapter~\ref{chap:Typeclasses-and-functions}}
-A \textsf{``}typeclass\textsf{''} is a mechanism for constraining type parameters
-in generic functions. We show how a typeclass can be implemented by
-passing evidence values in extra arguments. We show how to define
-functions whose type parameters are constrained to belong to specific
-typeclasses. While the function body is able to use the typeclass
-methods, the types remain arbitrary and unspecified.
+The concept of \textsf{``}typeclass\textsf{''} is motivated as a mechanism for constraining
+type parameters in generic functions. We show how a typeclass can
+be implemented by passing evidence values in extra arguments. We show
+how to define functions whose type parameters are constrained to belong
+to specific typeclasses. While the function body is able to use the
+typeclass methods, the types remain arbitrary and unspecified.
The verbosity of this implementation is reduced if one employs Scala\textsf{'}s
\textsf{``}implicit argument\textsf{''} feature. Another Scala feature is the \textsf{``}extension
@@ -318,7 +322,7 @@ \subsection{Chapter~\ref{chap:Typeclasses-and-functions}}
relations\textsf{''})
\item Inheritance and automatic conversion of typeclasses
\item Why many typeclasses have similar properties as regards typeclass
-derivation; the concept of \textsf{``}$P$-typeclasses\textsf{''}
+derivation; the concept of \textsf{``}FM-typeclasses\textsf{''}
\item How typeclasses unify and generalize both algebraic data types and
object-oriented interfaces
\end{itemize}
@@ -377,43 +381,720 @@ \subsection{Chapter~\ref{chap:Filterable-functors}}
functors to $M$-filterable functors (where $M$ is any monad).
\item We notice the similarity between the laws of several typeclasses and
the standard functor laws, which invites us to take a first glance
-at category theory and its more general definition of functors. We
-show that the laws of typeclasses can be derived from the laws of
-categories and of categorical functors. This gives us assurance that
-the typeclass laws are chosen in a consistent and useful way. We finish
-with a summary of issues for which category theory has been either
-helpful or not helpful in the context of functional programming.
+at category theory that provides a more general definition of a functor.
+We show that the laws of typeclasses can be derived from the laws
+of categories and of categorical functors. This gives us assurance
+that the typeclass laws are chosen in a consistent and useful way.
+We finish with a summary of issues for which category theory has been
+either helpful or not helpful in the context of functional programming.
\end{itemize}
This chapter studies filterable functors by following a pattern that
-all further chapters in Part~II will also follow. Beginning with
-working Scala code involving some operation, we formulate a typeclass
-whose members support that operation. Then we motivate and derive
-the mathematical laws that describe a programmer\textsf{'}s expectations about
-that operation\textsf{'}s behavior. To make the reasoning easier, we simplify
-those laws by introducing other, equivalent operations that have simpler
+all further chapters in Part~II also follow. Beginning with working
+Scala code involving some operation, we formulate a typeclass whose
+member types support that operation. Then we motivate a programmer\textsf{'}s
+expectations about that operation\textsf{'}s behavior, and derive the corresponding
+mathematical laws. To make the reasoning easier, we simplify those
+laws by introducing other, equivalent operations that have simpler
laws. We proceed to structural analysis and discover what type constructions
can support the given operation and its laws. As a result, we obtain
-many examples of types that belong to the typeclass.
+many examples of types that belong to the typeclass (as well as examples
+of types that do not).
\subsection{Chapter~\ref{chap:Semimonads-and-monads}}
-{*}{*}{*}
+\textsf{``}Semi-monads\textsf{''} are introduced as functors that support a \lstinline!flatMap!
+method. This is motivated by considering how functional programming
+can represent nested loops. Simple loops are translated into an application
+of a \lstinline!map! function to sequences; similarly, nested loops
+are translated into applications of \lstinline!flatMap! and \lstinline!map!
+functions.
+
+Scala\textsf{'}s \lstinline!for! / \lstinline!yield! syntax (which is itself
+modeled on a mathematical notation) is equivalent to nested \lstinline!map!
+and \lstinline!flatMap! calls. We give examples for using these functions
+(either directly or via the \lstinline!for! / \lstinline!yield!
+syntax) for implementing various iterative computations with sequences
+and other \textsf{``}list-like\textsf{''} monads such as \lstinline!Array! and \lstinline!Set!.
+
+Computations with sequences and other list-like types is the first
+step towards generalizing the \lstinline!map! and \lstinline!flatMap!
+functions to other data structures. The next step is to consider \lstinline!Option!
+and \lstinline!Either! types (the \textsf{``}pass/fail\textsf{''} monads). Computations
+with those types are also expressible via \lstinline!map! and \lstinline!flatMap!
+calls, and can benefit from using the \lstinline!for! / \lstinline!yield!
+syntax.
+
+We then turn to tree-like monads and show how computations with binary
+trees and abstract syntax trees are naturally expressed via a special
+implementation of \lstinline!flatMap!.
+
+Further generalization is motivated by the idea of viewing functions
+of type $A\rightarrow L^{B}$ a \textsf{``}computation with an $L$-effect\textsf{''}.
+By that we mean not a side effect, but any extra computational work
+that is done in a function of type $A\rightarrow L^{B}$ other than
+computing a result value of type $B$.
+
+With this picture in mind, we are able to derive the monad types that
+represent certain special computational situations: computing a value
+while reading another given value (the \lstinline!Reader! monad);
+computing a value while writing out another value (the \lstinline!Writer!
+monad); computing a value while updating another value (the \lstinline!State!
+monad); and computing a value but passing it to a given callback function
+(\lstinline!Cont!, the continuation monad). Finally, the \lstinline!Eval!
+monad represents the possibilities of computing a result eagerly or
+lazily. We look at code examples to illustrate the practical use of
+all those well-known monads.
+
+Next, we consider the laws that the \lstinline!flatMap! operation
+should obey. To derive those laws, we look at several code patterns
+that a programmer would intuitively expect to behave in certain ways.
+Each of those code patterns gives rise to a specific law of \lstinline!flatMap!.
+In this way, we derive an associativity law and two naturality laws
+for \lstinline!flatMap!. Analogous laws for the \lstinline!map!
+operation were derived in Chapter~\ref{chap:Functors,-contrafunctors,-and},
+where we defined functors as type constructors with a lawful \lstinline!map!
+method. Functors with a lawful \lstinline!flatMap! method are \textbf{semi-monads}.
+In this way, we find that the functor type involved in a \lstinline!for!
+/ \lstinline!yield! block (in this book, we call them \textbf{functor
+blocks}) must be in general a semi-monad.
+
+The three laws of \lstinline!flatMap! are equivalent to just two
+laws if we pass to a simpler function known in Scala as \lstinline!flatten!.
+We derive the laws of \lstinline!flatten! and prove that they are
+equivalent to the laws of \lstinline!flatMap!. A formal proof of
+type equivalence between \lstinline!flatMap! and \lstinline!flatten!
+(Statement~\ref{subsec:Statement-flatten-equivalent-to-flatMap})
+requires assuming one naturality law of \lstinline!flatMap!.
+
+We show how to verify the associativity law of \lstinline!flatten!
+for the \lstinline!Either!, \lstinline!Reader!, \lstinline!List!,
+and \lstinline!Writer! monads.
+
+Almost all semi-monads we considered are in fact \textsf{``}full monads\textsf{''},
+as they support an additional operation called \lstinline!pure!.
+We motivate this operation by considering an \textsf{``}empty effect\textsf{''}; for
+instance, an iteration over a list of length $1$. Then we derive
+the laws of \lstinline!pure! by looking at how we expect functor
+block code to behave when using \lstinline!pure!. The laws of \lstinline!pure!
+have a simpler form when written using \lstinline!flatten! instead
+of \lstinline!flatMap!. As we derive those simpler forms, we introduce
+Kleisli functions (of type $A\rightarrow M^{B}$) and the Kleisli
+composition operation ($\diamond_{_{M}}$) for a given monad $M$.
+Section~\ref{subsec:Monad-laws-in-Kleisli} derives the laws of the
+Kleisli composition operation from the laws of \lstinline!pure! and
+\lstinline!flatten! and also proves a full formal equivalence between
+the formulations of the monad operations and laws via Kleisli functions
+and via \lstinline!pure! / \lstinline!flatten!.
+
+Formulating monads via Kleisli functions has certain advantages when
+verifying laws of monads involving function types. Section~\ref{subsec:Verifying-the-monad-via-Kleisli-trick}
+shows how the \textsf{``}flipped / curried Kleisli\textsf{''} trick makes the proofs
+of monad laws shorter and clearer for the continuation monad and the
+state monad.
+
+We pass on to structural analysis of semi-monads and monads. The resulting
+type constructions are shown in Table~\ref{tab:Constructions-of-monads}.
+Some constructions only give semi-monads, but most create full monads.
+
+The chapter concludes by some further theoretical developments:
+\begin{itemize}
+\item Monads must be functors: it is impossible to define nontrivial monads
+that are contrafunctors.
+\item In this and the previous chapters, we proved the type isomorphisms
+between \lstinline!pure! and \lstinline!wu! (for pointed functors),
+between \lstinline!liftOpt! and \lstinline!deflate! (for filterable
+functors), and between \lstinline!flatMap! and \lstinline!flatten!
+(for semi-monads). It turns out that all those isomorphisms are special
+cases of more general type isomorphisms, known as the Yoneda identities.
+\item For monads that are not containers, a \textsf{``}runner\textsf{''} is needed to extract
+result values. It turns out that \textsf{``}runners\textsf{''} are functions that
+need to satisfy certain laws, known as the laws of \textsf{``}monad morphisms\textsf{''}.
+\item Monad morphisms and their laws are known in category theory; they
+are the morphisms in the category of monads. Monad morphisms are natural
+transformations between monads that map one monad\textsf{'}s \lstinline!pure!
+and \lstinline!flatten! operations onto the same operations of another
+monad. We show some examples to build up intuition about monad morphisms.
+\item Each monad gives rise to a category we denote by \textsf{``}$M$-Kleisli\textsf{''};
+morphisms in that category are Kleisli functions.
+\item Polynomial functors are sometimes monads (but sometimes not; one example
+is $F^{A}\triangleq\bbnum 1+A\times A\times...\times A$). We list
+the known type constructions that build up polynomial monads.
+\item One of the monad constructions involves the notion of an $M$-filterable
+contrafunctor. They can be motivated as generalizations of filterable
+contrafunctors when we replace the \lstinline!Option! monad in the
+type signature of \lstinline!filter! by an arbitrary monad $M$.
+We show formal definitions of $M$-filterable functors and contrafunctors,
+and briefly explore their structural analysis.
+\end{itemize}
\subsection{Chapter~\ref{chap:8-Applicative-functors,-contrafunctors}}
-{*}{*}{*}
+We begin by looking at the familiar \lstinline!zip! operation for
+sequences (which are functors). It turns out that \lstinline!zip!
+can be generalized to work with many other types. Type constructors
+that support a \lstinline!zip! method satisfying suitable laws are
+called \textsf{``}applicative\textsf{''}. This chapter will develop a rigorous description
+of applicative functors, contrafunctors, and profunctors.
+
+We begin with examples of practical use of the \lstinline!zip! method,
+showing how \lstinline!zip! can be used to combine polynomial data
+types, binary trees, and even some non-covariant type constructors.
+Other uses of \lstinline!zip! include gathering multiple errors while
+validating data; performing multiple computations in parallel; and
+transposing matrices. We arrive at an intuition that applicative functors
+express combination of effects that are independent of previously
+computed values. For that reason, effects can be sometimes evaluated
+and combined in parallel. The condition for that is called \textsf{``}commutativity\textsf{''}
+of applicative functors. This property will be formally defined and
+studied later in this chapter.
+
+Another practically useful function is \lstinline!map2!. We show
+that \lstinline!map2! can be expressed via \lstinline!zip!, and
+that analogous methods \lstinline!map3!, \lstinline!map4!, etc.,
+may be defined via \lstinline!zip3!, \lstinline!zip4!, etc. We can
+avoid having to implement all those functions via boilerplate code
+if we instead implement a method known as \lstinline!ap!. However,
+this trick works only for covariant functors. Non-covariant functors
+must define methods such as \lstinline!xmap2!, \lstinline!xmap3!,
+etc., separately.
+
+We show further use cases for applicative functors: the applicative
+\lstinline!Reader! functor; \textsf{``}fusion\textsf{''} of \lstinline!fold!-like
+operations into single traversals; and parsing via parsing combinators.
+To build up intuition, we show code that contrasts the applicative
+and the monadic approaches to fold fusion and to parsing combinators.
+
+Applicative operations may be used in functor blocks as explicit \lstinline!zip!
+operations. Scala does not have a widely accepted special syntax for
+applicative functor blocks, although some experimental proposals exist
+(Section~\ref{subsec:Functor-block-syntax-for-applicative}).
+
+We turn to the derivation of the laws for \lstinline!zip!. First,
+we show that the methods \lstinline!ap!, \lstinline!map2!, and \lstinline!zip!
+are equivalent as types if we assume suitable naturality laws. We
+prefer to define the \lstinline!Zippable! typeclass via the \lstinline!zip!
+method, for the reason that the same typeclass will be usable with
+non-covariant functors.
+
+The laws of \lstinline!map2! follow from the monad laws if we implement
+\lstinline!map2! through \lstinline!flatMap!. Of course, applicative
+functors do not necessary have \lstinline!flatMap!; but this derivation
+allows us to motivate a reasonable set of laws for \lstinline!map2!.
+These are the associativity law and the two identity laws. We then
+derive the corresponding laws of \lstinline!zip!.
+
+We formally define the property of commutativity for applicative functors
+and show how it simplifies the other laws. Most applicative functors
+used in practice are commutative and are suitable for parallel evaluation.
+
+Many applicative functors are at the same time monads. However, most
+monads used in practice are \emph{not} commutative. For this reason,
+it is typically not the case that applicative functors have their
+\lstinline!zip! functions derived from \lstinline!flatMap!. For
+example, the \lstinline!List! and \lstinline!Either! are monads
+whose standard \lstinline!zip! methods do not follow from the \lstinline!flatMap!
+code for those monads.
+
+Having derived the laws of \lstinline!zip!, the next step is to perform
+structural analysis and to discover type constructions that create
+new applicative type constructors. The results for applicative functors
+are shown in Table~\ref{tab:Constructions-of-applicative-functors},
+for applicative contrafunctors in Table~\ref{tab:Constructions-of-applicative-contrafunctors},
+and for applicative profunctors in Table~\ref{tab:Constructions-of-applicative-profunctors}.
+
+Usually, there will be several inequivalent but lawful implementations
+for the \lstinline!zip! method; so, the applicative typeclass instances
+are not unique. Another consequence of structural analysis is that
+all exponential-polynomial \emph{contravariant} functors are applicative.
+It is perhaps surprizing that a lawful \lstinline!zip! method can
+be defined for a wide range of profunctors that are neither covariant
+nor contravariant. One practical use case for this property is shown
+in Example~\ref{subsec:Example-applicative-profunctor}.
+
+Further theoretical developments at the end of this chapter include:
+\begin{itemize}
+\item We have previously seen several examples of methods that are equivalent
+as types: \lstinline!flatMap! and \lstinline!flatten!, \lstinline!map2!
+and \lstinline!zip!, and so on. Now we clarify and formulate rigorously
+what it means that two typeclass methods are \textsf{``}isomorphic as types
+assuming some laws hold\textsf{''}.
+\item All monads are applicative at least in one way (but not all applicative
+functors are monads). In many cases, the applicative instance derived
+from the monad instance is not as useful in applications as a different,
+inequivalent applicative instance for the same type constructor. We
+show some examples illustrating this.
+\item We motivate and define the concept of \textsf{``}applicative morphism\textsf{''}:
+a mapping between two applicative functors that preserves the applicative
+methods.
+\item The laws of \lstinline!ap! are easier to derive if we get some help
+from category theory. For an applicative functor $L$, we define the
+\textsf{``}$L$-ap\textsf{''} category whose morphisms have type $L^{A\rightarrow B}$
+and are composed using the special operation ($\odot$). In this formulation,
+the laws of \lstinline!ap! follow from the category laws of $L$-ap.
+\item We summarize various typeclass methods and laws defined in this and
+the previous chapter and examine the patterns in their type signatures
+(see Table~\ref{tab:functorial-typeclasses}). It turns out that
+the laws of each typeclass are equivalent to the standard functor
+laws, if we consider a certain categorical functor defined in a suitable
+way for that typeclass. This provides a general and abstract picture
+justifying the choice of typeclass laws.
+\end{itemize}
\subsection{Chapter~\ref{chap:9-Traversable-functors-and}}
-{*}{*}{*}
+We begin by considering the standard \lstinline!reduce! method for
+sequences. Traversable functors are found by a generalization that
+we motivate in several steps. As a first step, we pass from \lstinline!reduce!
+to \lstinline!foldMap!, which is parameterized by an arbitrary monoid
+$M$. The next step generalizes from sequences to functors that support
+an analogous \lstinline!foldMap! method. The final step is to replace
+the monoid $M$ by an arbitrary applicative functor with a type parameter.
+The result is a powerful operation known as \lstinline!traverse!.
+
+The \lstinline!traverse! function can be implemented for any polynomial
+functor (we will prove that rigorously later in that chapter). To
+build up intuition, we show several examples of implementing \lstinline!traverse!
+for different data types, such as lists and trees.
+
+Another useful function equivalent to \lstinline!foldMap! is \lstinline!toList!:
+it extracts all data from a functor in a certain fixed order into
+a \lstinline!List!.
+
+We illustrate the usage of \lstinline!foldMap!, \lstinline!toList!,
+and \lstinline!traverse! for tasks such as depth-first or breadth-first
+aggregations and \textsf{``}decorations\textsf{''} on trees. A typical \textsf{``}decoration\textsf{''}
+function is \lstinline!zipWithIndex!: it adds integer labels to data
+according to the traversal order. We show how \lstinline!traverse!
+makes implementing \lstinline!zipWithIndex! simpler. Different traversal
+orders correspond to different implementations of \lstinline!traverse!,
+while the \textsf{``}decoration\textsf{''} logic remains the same.
+
+Defining the \lstinline!Traversable! typeclass via the \lstinline!traverse!
+method, we show how to implement various traversal-like operations
+such as \lstinline!zipWithIndex! and \lstinline!scanLeft! using
+that typeclass.
+
+Then we give examples of tasks that cannot be performed via \lstinline!traverse!
+because it cannot obtain certain required information while traversing
+the data structure. To overcome this difficulty, we introduce a generalized
+\lstinline!fold! operation that depends on the pattern functor of
+a recursive type. The \lstinline!fold! operation is a \textbf{recursion
+scheme}\index{recursion scheme}: a higher-order function that supplies
+recursive behavior and is parameterized by a calculation that needs
+to be performed repeatedly. We give some examples of using \lstinline!fold!
+for implementing tasks such as depth labeling (\lstinline!zipWithDepth!)
+and pretty-printing.
+
+A recursion scheme opposite to \lstinline!fold! is \lstinline!unfold!:
+it creates a new recursive structure by following specified logic.
+We give examples of using unfold for creating lists and trees of specified
+shape.
+
+Unlike \lstinline!fold! that always terminates, the termination of
+\lstinline!unfold! is not guaranteed, as it can go on indefinitely
+creating new parts of recursive structures. This problem can be avoided
+by using lazy data structures that delay evaluation of recursive parts.
+We show how to define a \textsf{``}lazy\textsf{''} binary tree that can simulate trees
+of unbounded depth.
+
+We turn to investigating the laws and formal properties of folding
+and traversal operations. First, we show formally that \lstinline!reduce!,
+\lstinline!foldLeft!, \lstinline!foldMap!, and \lstinline!toList!
+are isomorphic as types if we assume suitable naturality laws. When
+formulating those laws, we find it necessary to introduce \textsf{``}monoid
+morphisms\textsf{''}: functions mapping one monoid to another such that the
+monoid operations are preserved.
+
+In Section~\ref{subsec:The-missing-laws-of-foldMap-and-reduce} we
+discuss the problem that the naturality laws alone do not guarantee
+useful behavior of \lstinline!reduce!, \lstinline!foldMap!, and
+\lstinline!toList!. However, it does not appear possible to formulate
+any new laws. Instead, we will formulate a law for \lstinline!traverse!
+and derive the folding operations from \lstinline!traverse!.
+
+The lack of laws is not a serious issue since foldable functors can
+be characterized in a simple way: they are just all polynomial functors.
+We show that all polynomial functors support a \lstinline!toList!
+operation (and therefore all the other equivalent operations).
+
+We now turn to studying the laws of the \lstinline!traverse! operation.
+First, we note that an equivalent simpler operation is \lstinline!sequence!.
+Then we formulate several laws of traverse: the applicative naturality
+law, the identity law, and the composition law. We motivate those
+laws by formal considerations and also show that these laws do not
+hold for certain incorrect implementations of \lstinline!traverse!.
+
+Then we derive the corresponding simpler laws for \lstinline!sequence!.
+Using those laws, we perform structural analysis and prove that all
+polynomial functors are traversable. (We also explain why non-polynomial
+functors are not traversable.)
+
+In that proof, we needed a notion of \textsf{``}bitraversable\textsf{''} bifunctors.
+We define that property formally and show that all polynomial bifunctors
+are bitraversable.
+
+In the last section of the chapter, we explore some further questions:
+\begin{itemize}
+\item The recursion schemes \lstinline!fold! and \lstinline!unfold! generate
+\textsf{``}structure-preserving\textsf{''} maps between types. We define formally
+the notions of functor algebras and functor co-algebras to show how
+the property of being \textsf{``}structure-preserving\textsf{''} can be formulated
+via equations.
+\item Some laws of \lstinline!traverse! are still missing, as we are not
+able to use the existing laws for proving certain expected properties
+of \lstinline!zipWithIndex!. One needs a \textsf{``}representation theorem\textsf{''}
+for \lstinline!traverse! (Statement~\ref{subsec:Statement-Bird-representation-theorem-for-traversal}).
+A detailed proof of that theorem is beyond the scope of this book.
+Using that theorem, we can prove the required properties of \lstinline!zipWithIndex!.
+We also show that a traversable functor always allows us to write
+an explicit indexed table for all the data it contains (Statement~\ref{subsec:Statement-polynomial-functors-Int-A}).
+\item We show that nontrivial traversable contrafunctors and profunctors
+do not exist.
+\item We show how to implement traversals for nested recursive types, and
+illustrate with an example implementation of square-shaped nested
+lists.
+\end{itemize}
\subsection{Chapter~\ref{chap:Free-type-constructions}}
+A \textsf{``}free typeclass\textsf{''} is an advanced design pattern in functional
+programming. The chapter begins by developing the \textsf{``}free monad\textsf{''}
+organically by implementing embedded domain-specific languages (DSLs).
+We consider two example DSLs: one for computations with complex numbers,
+and another for reading files. In the next few sections, we evolve
+the DSLs to make them type-safe and to add the ability to bind variables
+to results of previous DSL computations.
+
+Refactoring the final code for the two DSLs, we divide the code into
+one part that implements the custom DSL operations and another part
+performing just the monadic functionality. That second part is what
+is known as the \textsf{``}free monad\textsf{''}, meaning it is free from any domain-specific
+code. This allows us to formulate a general recipe for creating DSL
+of this kind and to write generic code that creates and runs DSL programs.
+
+We notice that the DSL type constructor looks like a monad but fails
+some of the monad laws. However, the monad laws hold after we apply
+a runner to a DSL program; runners \textsf{``}hide\textsf{''} law violations. Because
+of that, using a law-violating DSL code is not problematic in practice.
+Nevertheless, the code of the free monad can be modified so that the
+monad laws hold. We show that this actually simplifies the code as
+there are fewer case classes needed.
+
+A monadic DSL can be evaluated (\textsf{``}run\textsf{''}) into another monad. It
+turns out that the corresponding runner is \textsf{``}universal\textsf{''} in that
+it works in the same way for all target monads. We show how to implement
+a universal runner for monadic DSLs. The universal runner translates
+a free monad\textsf{'}s \lstinline!pure! and \lstinline!flatMap! operations
+into the corresponding operations of another monad.
+
+Section~\ref{sec:Different-encodings-of-free-monad} introduces the
+notion of an \textsf{``}encoding\textsf{''} of the free monad. In Section~\ref{subsec:Motivation-free-monad-different-encodings},
+we show that there have been different versions of \textsf{``}free monad\textsf{''}
+presented in different sources. Are these versions all correct, are
+they equivalent, or is one version of a monadic DSL better than another?
+To resolve these questions, we look at four different implementations
+(\textsf{``}encodings\textsf{''}) of a free monad and find out if they could be mapped
+to each other. One of the encodings (the \textsf{``}raw tree\textsf{''} encoding,
+\lstinline!Free4!) obeys \emph{none} of the monad laws while other
+encodings are smaller and do obey some of the laws. We show how one
+can derive a smaller (\textsf{``}reduced\textsf{''}) encoding from a larger one by
+imposing one of the monad laws. We also show that smaller encodings
+have injective maps to larger ones.
+
+We take a digression to introduce the notion of existential type quantifiers
+(Section~\ref{subsec:Types-with-existential-quantifiers}). This
+is necessary in order to describe in a formal way the kinds of types
+that free monad encodings require. We show how existentially quantified
+types can be expressed through universal quantifiers in Equations~(\ref{eq:existential-via-universal})
+and~(\ref{eq:existential-via-universal-Yoneda}). Finally, we show
+that the \textsf{``}smallest\textsf{''} free monad encoding (\lstinline!Free1!) is
+equivalent to \lstinline!Free2! when $F$ is a functor.
+
+Having studied the free monad at length, we now turn to free constructions
+for other typeclasses. Before we generalize from the monad to other
+typeclasses, we need to understand what general properties a free
+construction must satisfy. To that end, Section~\ref{sec:Expected-properties-of-free-typeclass}
+examines the properties of the free monad construction and generalizes
+those properties to other typeclasses.
+
+We introduce an important notion of a function that \textsf{``}preserves the
+typeclass operations\textsf{''}. It is due to this property that a runner
+function removes monad law violations in a free monad.
+
+With this motivation, we formulate laws that we expect to hold for
+other free typeclass constructions. Those laws are generally applicable
+for all typeclasses.
+
+Armed with this information, we proceed to show the types and the
+code for various free typeclass constructions of different complexity.
+For each typeclass, we will first construct the raw tree encoding
+
+The first example of a free typeclass is \textsf{``}free pointed type\textsf{''} (Section~\ref{subsec:Free-pointed-type}).
+We show that the properties of the free pointed type are a reformulation
+of the properties of the standard \lstinline!Option! monad.
+
+Since a pointed type has no laws, the raw tree encoding is only one
+free typeclass encoding for this typeclass.
+
+Next, we consider the \lstinline!Semigroup! typeclass (Section~\ref{subsec:Free-semigroup}).
+We begin by implementing the raw tree encoding and its evaluator.
+Then we impose the associativity law and arrive at the reduced encoding.
+We prove that the reduced encoding can be mapped (in several ways)
+to the raw tree encoding, and all those maps are injective but do
+not preseve the semigroup\textsf{'}s methods. The converse map (from the raw
+tree encoding to the reduced encoding) is found as an application
+of the universal runner and preserves the semigroup\textsf{'}s methods.
+
+Later we will show that this situation is found in general for all
+FM-typeclasses: a reduced encoding can be injected into the raw tree
+encoding by many functions, neither of which preserves the typeclass
+methods.
+
+The next more complicated typeclass is \lstinline!Monoid! (Section~\ref{subsec:Free-monoids}).
+We again start with the raw tree encoding and then discover several
+reduced encodings by imposing different subsets of laws. To illustrate
+the relationships between reduced encodings of a free typeclass, we
+write down the code for 4 different encodings of the free monoid (denoted
+by $F_{1}$, $F_{2}$, $F_{3}$, $F_{4}$). We find that a given free
+monoid encoding can be injectively mapped into any other encoding
+that obeys \emph{fewer} laws; but those injective maps do not preserve
+the monoid operations. A given encoding may be mapped surjectively
+onto another encoding that satisfies the same laws (and possibly more
+laws).
+
+As there are 3 monoid laws, we can construct 8 different free monoid
+encodings that obey each of the 8 possible subsets of the three laws.
+To illustrate the required techniques, we show two more encodings:
+$F_{5}$ obeying the left identity law and the associativity law,
+and $F_{6}$ obeying only the left identity law but no other monoid
+laws.
+
+{*}{*}{*}
+
{*}{*}{*}
\subsection{Chapter~\ref{chap:monad-transformers}}
-{*}{*}{*}
+This chapter is an in-depth study of monad transformers.
+
+To motivate monad transformers, we begin by trying to use two different
+monads in a single functor block; we find that the code becomes hard
+to work with. The code can be simplified if we manage to combine two
+monads into a single larger monad. One way of combining monads is
+by functor composition, for example as \lstinline!Future[Option[A]]!.
+Table~\ref{tab:Correct-and-incorrect-compositions} shows some examples
+of working and non-working functor composition of monads. In some
+cases (such as Future and State), functor composition completely fails.
+
+This suggests a different approach where one monad is fixed (the \textsf{``}base
+monad\textsf{''} $L$) and the other (\textsf{``}foreign\textsf{''}) monad $M$ is considered
+as a parameter. This is known as the \textsf{``}monad transformer\textsf{''} approach.
+The result of combining $L$ and $M$ is a \textsf{``}larger\textsf{''} monad (denoted
+by $L\varangle M$ in this book) that can express the effects of both
+monads $L$, $M$. The \textsf{``}monad transformer\textsf{''} of the base monad $L$
+is the operation $L\varangle$ that can be applied to any foreign
+monad $M$ to obtain the new monad $L\varangle M$. The code of $L\varangle$
+is written once for every base monad $L$; the same code will then
+work for all foreign monads $M$. This avoids the need for writing
+custom code that combines every pair of monads. Monad transformer
+code is written only once per base monad.
+
+Table~\ref{tab:Known-monad-transformers} shows the types of monad
+transformers for a number of known monads. Then we go through some
+examples, showing how monad transformers are implemented in practice.
+
+In addition to having the code for the transformed monad $L\varangle M$,
+in practice one needs to be able to use the effects of each of the
+two monads ($L$, $M$) within a functor block of type $L\varangle M$.
+For that, we need functions that transform values of types $L^{A}$
+and $M^{A}$ into values of type $(L\varangle M)^{A}$. Those functions
+are called the \textsf{``}base lift\textsf{''} ($L\leadsto L\varangle M$) and the
+\textsf{``}foreign lift\textsf{''} ($M\leadsto L\varangle M$).
+
+In order to extract final results from monadic programs, one uses
+functions called \textsf{``}runners\textsf{''}. Those functions execute a monad\textsf{'}s
+effects and deliver resulting values, sometimes wrapped in another,
+simpler monad. If we have runners for $L$ and $M$, we would need
+a way to obtain the corresponding runners for the combined monad $L\varangle M$.
+Showing examples with the \lstinline!Reader!, \lstinline!List!,
+\lstinline!State!, and some other monad transformers, we motivate
+introducing a \textsf{``}base runner\textsf{''} ($L\varangle M\leadsto M$) and a
+\textsf{``}foreign runner\textsf{''} ($L\varangle M\leadsto L\varangle N$). Those
+runners execute the effects of one monad while keeping the effects
+of another.
+
+Not all transformers support both lifts and both runners. For instance,
+we show that the continuation monad\textsf{'}s transformer does not allow us
+to implement a base lift or any runners.
+
+The properties required for a monad transformer can be formulated
+by defining a typeclass we denote \lstinline!MTrans! (Section~\ref{subsec:A-typeclass-for-monad-transformers}).
+
+We turn to combining more than two monads, noticing that monad transformers
+can be applied one after another; for example, as $K\varangle(L\varangle M)$
+or as $K\varangle(L\varangle(M\varangle N))$. The resulting combined
+monad is called a \textsf{``}monad stack\textsf{''}. It is a new, \textsf{``}larger\textsf{''} monad
+that can describe the effects of all its constituent monads ($K$,
+$L$, $M$, ...).
+
+We define monad transformer for the monad $K\varangle L$ by $(K\varangle L)\varangle M\triangleq K\varangle(L\varangle M)$.
+This makes the operation $\varangle$ associative, so that we may
+write $K\varangle L\varangle M$ without ambiguity. We also motivate
+the properties $\text{Id}\varangle M\cong M$ and $M\varangle\text{Id}\cong M$.
+Later in this chapter we will rigorously prove those and other properties
+for all known monad transformers.
+
+Building a monad stack in a different order ($K\varangle L$ or $L\varangle K$)
+will, as a rule, produce inequivalent monads. Table~\ref{tab:Examples-of-monad-stacks}
+shows some examples where transformers are applied in different orders.
+
+To write code in a large monad stack $P\triangleq M_{1}\varangle M_{2}\varangle...\varangle M_{k}$,
+we need functions that can lift any of the monads $M_{i}$ to the
+stack, as well as functions that run the effects of a certain monad
+$M_{i}$ while keeping all other effects. We can construct the necessary
+lifts if all monads in the stack (except possibly the last one, $M_{k}$)
+have transformers supporting their individual lift functions. However,
+the resulting code is difficult to write because it is a composition
+of up to $k$ individual lifts that have to be combined in exactly
+correct way.
+
+To make working with monad stacks easier, there are several techniques
+that generate the necessary lifts automatically. The first of these
+techniques (Section~\ref{subsec:Constructing-lifts-via-type-relations})
+obtains lifts from a type relation constructed automatically via typeclass
+derivation. The second of these techniques is known as MTL-style programming
+(\ref{subsec:Combining-monads-via-mtl-style}). It requires the programmer
+to define a typeclass for each monad, encapsulating the \textsf{``}operations\textsf{''}
+that characterize working with that monad. (Table~\ref{tab:effectful-operations-for-some-monads}
+shows what those \textsf{``}operations\textsf{''} are for a few well-known monads.)
+The programmer needs to write all code in terms of those typeclasses
+and operations, rather than in terms of specific monads.
+
+We turn to formulating the laws required of monad transformers. We
+motivate those laws via examples of practical use. Having obtained
+a large number of laws, we simplify and streamline their formulations,
+using inspiration from category theory. The result is a quip: \textsf{``}a
+monad transformer is a pointed endofunctor in the category of monads\textsf{''}
+(Section~\ref{subsec:Category-theoretic-properties-of-lifts-and-runners-functors-in-category-of-monads}).
+This formula expresses concisely the 18 laws of monad transformers
+that we summarize in more detail in Section~\ref{subsec:Laws-of-monad-transformers}.
+
+The formulated laws can be verified for any given construction that
+is claimed to give a monad transformer. To illustrate that a law violation
+means failing to provide a required functionality, we show a number
+of examples that do not satisfy the laws of monad transformers. In
+Section~\ref{subsec:Examples-of-failure-of-generic-monad-transformer}
+we list several failing attempts to construct a general monad transformer
+that could work for all monads at once. Only one construction (the
+Church-encoded co-product in the category of monads) satisfies all
+laws of a general transformer, but is unfortunately unusable in mainstream
+programming languages due to lack of first-class support for typeclass
+laws.
+
+In Sections~\ref{subsec:Stacking-two-monads}\textendash \ref{subsec:Stacking-any-number-of-monads}
+we prove that all laws hold for monad stacks involving any number
+of monads, assuming that all the constituent monad transformers are
+lawful.
+
+The next sections will prove the laws for monad transformers of the
+individual monads. We begin with the \textsf{``}compositional\textsf{''} transformers
+that work by composing the foreign monad as a functor either inside
+or outside the base monad. Both kinds of compositional transformers
+have common properties that we begin to study in Section~\ref{sec:Monad-transformers-that-use-composition}.
+The key to simplifying the proofs for compositional transformers is
+to consider the special \lstinline!swap! function (Section~\ref{subsec:Motivation-for-the-swap-function}).
+The required laws of \lstinline!swap! are motivated and derived in
+Section~\ref{subsec:Deriving-the-necessary-laws-for-swap}. The laws
+of \lstinline!swap! are easier to verify for specific monads. We
+show in Section~\ref{subsec:Deriving-swap-from-flatten} that the
+\lstinline!swap! function is type-isomorphic to the \lstinline!flatten!
+method of the composed monad (either $L\circ M$ or $M\circ L$),
+assuming that their respective laws hold.
+
+We proceed to prove the laws of compositional monad transformers by
+assuming that the laws of \lstinline!swap! already hold. This proves
+at once the validity of all composed-inside and composed-outside monad
+transformers. It remains to verify the laws of \lstinline!swap! for
+specific monads.
+
+Section~\ref{sec:transformers-linear-monads} considers \textsf{``}linear
+monads\textsf{''} (in the sense of being linear polynomials as functors) and
+proves that the laws of \lstinline!swap! hold for those monads. This
+covers \lstinline!Option!, \lstinline!Either!, \lstinline!Writer!,
+and their compositions.
+
+Section~\ref{sec:transformers-rigid-monads} turns to monads whose
+transformers compose the foreign monad outside the base monad. Those
+monads are called \textsf{``}rigid\textsf{''} in this book.\footnote{See the discussion here: \texttt{\href{https://stackoverflow.com/questions/39649497/}{https://stackoverflow.com/questions/39649497/}}}
+The only well-known example of a rigid monad is \lstinline!Reader!.
+To build up intuition, we show some type constructions that create
+new rigid monads and obtain further examples. Then we prove that the
+laws of \lstinline!swap! hold for all rigid monads. This ensures
+the correctness of their monad transformers.
+
+Apart from functor composition, transformers for other monads do not
+follow any general patterns. The rest of the chapter goes over various
+known constructions that work for specific kinds of monads. The known
+patterns will be summarized in Section~\ref{subsec:Summary-of-monad-transformer-constructions}.
+
+Section~\ref{sec:Transformers-for-products-and-free-pointed} proves
+the laws for transformers of product monads (see Statement~\ref{subsec:Statement-monad-semimonad-product})
+and the \textsf{``}free pointed\textsf{''} monads (see Statement~\ref{subsec:Statement-co-product-with-identity-monad}).
+
+Section~\ref{sec:Transformers-for-recursive-monads} proves the laws
+for transformers of two recursively defined monads. One such monad
+is the \textsf{``}free monad\textsf{''} on a given functor (see Statement~\ref{subsec:Statement-monad-construction-4-free-monad}).
+We also prove (Statement~\ref{subsec:Statement-free-monad-transformer-coproduct})
+that two free monads combine via their transformers to a free monad
+on a co-product of functors. This is an important property that makes
+free monads easier to combine.
+
+The other recursive monad is the standard \lstinline!List! monad
+whose associativity law was verified in Statement~\ref{subsec:Example-flatten-verify-for-monad-1-1}.
+The \lstinline!List! monad\textsf{'}s transformer is complicated, and a proof
+of its laws takes some work (Section~\ref{subsec:Transformer-for-the-List-monad}).
+
+We now turn to \textsf{``}incomplete\textsf{''} monad transformers that lack certain
+features.
+
+The first of those is the transformer for the \lstinline!State! monad
+(Statement~\ref{subsec:Statement-state-monad-transformer}). The
+only deficiency of the \lstinline!StateT! transformer is the violation
+of monad morphism laws by the base runner. (This means that the \lstinline!StateT!
+transformer is a pointed but \emph{not} a co-pointed endofunctor in
+the category of monads.) Accordingly, running a monadic program involving
+a \lstinline!StateT! must run all \lstinline!State! effects at once;
+it is incorrect to run the \lstinline!State! effects for parts of
+a program and then compose the results.
+
+The next sections prove the laws of the monad transformers for the
+continuation monad, the generalized search monad, and the codensity
+monad. Those transformers do not support base lifts, base runners,
+or foreign runners; they are \emph{not} endofunctors in the category
+of monads. Because of this, programmers cannot lift effects of different
+monads into a transformed monad and cannot run effects in an arbitrary
+order unless the problematic monads (continuation, search, codensity,
+etc.) are in the deepest position in the monad stack.
+
+The chapter concludes by considering several directions of developing
+the theory further:
+\begin{itemize}
+\item Show some examples of monads that have more than one transformer.
+As a rule, one transformer is complete and all others are incomplete.
+\item Prove some general properties of monad morphisms that are useful for
+proofs of laws of monad transformers.
+\item \textsf{``}Rigid\textsf{''} monad transformers are built via \lstinline!swap! functions.
+Do compositions of arbitrary rigid monads always have a corresponding
+\lstinline!swap! function? This question is not yet fully answered
+(Problem~\ref{par:Problem-monads-5-1}).
+\item The requirements for \textsf{``}rigid\textsf{''} monads can be relaxed to yield \textsf{``}rigid\textsf{''}
+functors. We outline their properties and show some applications:
+the \textsf{``}functor-valued \lstinline!flatMap!\textsf{''} and the \textsf{``}refactor-to-monad\textsf{''}
+transformation.
+\item The \textsf{``}MTL-style\textsf{''} monadic programming can be made more general via
+the \textsf{``}monadically natural lifting\textsf{''} of monad operations to monad
+stacks. We prove the theoretical results underlying this technique.
+\end{itemize}
\subsection{Appendix~\ref{app:Proofs-of-naturality-parametricity}}
@@ -421,45 +1102,164 @@ \subsection{Appendix~\ref{app:Proofs-of-naturality-parametricity}}
all fully parametric code. Those properties are a mathematical expression
of the idea that a fully parametric function works \textsf{``}in the same
way\textsf{''} for all types. This appendix develops the necessary theory
-and technique in order and proves the following results:
-
-A given type constructor may have one fully parametric and lawful
-implementation of the \lstinline!Functor! or \lstinline!Contrafunctor!
-typeclass instance. (For most other typeclasses, such as \lstinline!Filterable!
-or \lstinline!Monad!, type constructors often have several inequivalent
-and lawful typeclass instances.) The unique implementations are used
-in the type constructions shown in Sections~\ref{subsec:f-Functor-constructions}
-and~\ref{subsec:f-Contrafunctor-constructions}.
-
-The lifting methods of any fully parametric bifunctor or profunctor
-obey the commutativity law such as Eq.~(\ref{eq:f-fmap-fmap-bifunctor-commutativity}).
-
-Any fully parametric expression $t:\forall A.\,Q^{A}$ satisfies the
-relational naturality law~(\ref{eq:relational-naturality-law-1}).
-In general, the relational naturality law expresses a property of
-\emph{relations} rather than functions and is not equivalent to any
-equation satisfied by $t$. The chapter explains how relations are
-defined and what operations are available for relations, and shows
-the proof of the relational naturality law.
-
-All fully parametric functions of type $P^{A,A}\rightarrow Q^{A,A}$
-(where $P$, $Q$ are profunctors) obey the dinaturality law~(\ref{eq:dinaturality-law-for-profunctors}).
-The form of the law depends only on the function\textsf{'}s type signature
-and applies to all fully parametric implementations of that type signature.
-
-If the type signature of $t$ satisfies the conditions of Statements~\ref{subsec:Statement-post-wedge-entails-strong-dinaturality}
-or~\ref{subsec:Statement-functor-post-pre-wedge}, the function $t$
-satisfies the \textsf{``}strong dinaturality\textsf{''} law~(\ref{eq:strong-dinaturality-law}).
-Strong dinaturality gives more information than the ordinary dinaturality
-law and is simpler to use than the general relational naturality law~(\ref{eq:relational-naturality-law-1}).
+and technique to show how one can prove a number of results used in
+other parts of the book.
+
+First, we show that a given type constructor may have at most one
+fully parametric and lawful implementation of the \lstinline!Functor!
+or \lstinline!Contrafunctor! typeclass instance. (For most other
+typeclasses, such as \lstinline!Filterable! or \lstinline!Monad!,
+type constructors often have several inequivalent and lawful typeclass
+instances.) The unique implementations are used in the type constructions
+shown in Sections~\ref{subsec:f-Functor-constructions} and~\ref{subsec:f-Contrafunctor-constructions}.
+
+We show that the lifting methods of any fully parametric bifunctor
+or profunctor will automatically obey the commutativity law such as
+Eq.~(\ref{eq:f-fmap-fmap-bifunctor-commutativity}).
+
+Section~\ref{sec:Parametricity-theorem-for-relations} begins the
+study of the central theorem from which all applications of parametricity
+will follow. This theorem (the \textsf{``}parametricity theorem\textsf{''}) says that
+any fully parametric expression $t:\forall A.\,Q^{A}$ will automatically
+obey a certain relational naturality law, shown in Eq.~(\ref{eq:relational-naturality-law-1}).
+
+We explain how relations are defined and introduce certain combinators
+that manipulate relations: the relational product, the relational
+co-product, and the \textsf{``}pair mapper\textsf{''} combinators. Using those combinators
+and an important technical tool we call \textsf{``}simultaneous relational
+lifting\textsf{''} (Definition~\ref{subsec:Definition-simultaneous-relational-lifting}),
+Section~\ref{subsec:Relational-parametricity-theorem} arrives at
+an inductive proof of the relational naturality law.
+
+The relational naturality law expresses a property of \emph{relations}
+(rather than functions) and is not always equivalent to any equation
+satisfied by $t$. Because of that, the relational naturality law
+is often hard to use directly. Programmers are more interested in
+proving that a fully parametric function satisfies some equation (a
+\textsf{``}law\textsf{''}). Several shortcuts are available that, in most cases, quickly
+produce equational laws automatically satisfied by fully parametric
+expressions.
+
+One shortcut is the dinaturality law~(\ref{eq:dinaturality-law-for-profunctors})
+obeyed by all fully parametric functions of type $P^{A,A}\rightarrow Q^{A,A}$
+(where $P$, $Q$ are profunctors). The form of the law depends only
+on the function\textsf{'}s type signature and applies to all fully parametric
+implementations of that type signature. The dinaturality law is a
+generalization of the naturality law from type signatures of the form
+$F^{A}\rightarrow G^{A}$ (where $F$ and $G$ are both covariant
+or both contravariant) to arbitrary type signatures of the form $P^{A,A}\rightarrow Q^{A,A}$.
+
+Another useful shortcut the \textsf{``}strong dinaturality\textsf{''} law~(\ref{eq:strong-dinaturality-law}).
+That law holds whenever the type signature of $t$ satisfies the conditions
+of Statements~\ref{subsec:Statement-post-wedge-entails-strong-dinaturality}
+or~\ref{subsec:Statement-functor-post-pre-wedge}. Strong dinaturality
+gives more information than the ordinary dinaturality law.
+
+The strong dinaturality law is the first of the parametricity techniques
+that go beyond naturality laws and Yoneda identities. Section~\ref{subsec:Strong-dinaturality.-General-properties}
+is an in-depth study of strongly dinatural transformations. We use
+structural analysis to look for possible function types $P^{A,A}\rightarrow Q^{A,A}$
+for which the strong dinaturality law will hold. The results of this
+analysis are used for proving properties of Church encodings as well
+as in the proof of the type isomorphism between \lstinline!foldMap!
+and \lstinline!reduce!.
+
+Section~\ref{subsec:Universal-type-quantifiers} begins a further
+study of parametricity-based techniques for simplifying types that
+contain universal quantifiers. The Yoneda identities already provide
+such simplifications for a wide range of such types, of which we show
+a number of examples. We also show how the universal quantifier and
+the function types can encode other type constructions (void type,
+unit type, products, co-products, existentially quantified types,
+and recursive types).
+
+Category theory proves an abstract version of the Yoneda identity
+(the \textsf{``}Yoneda lemma\textsf{''}) for all categories. The two Yoneda identities
+involving covariant and contravariant functors are the most important
+practical applications of the Yoneda lemma to programming. Other applications
+used in this book are Yoneda identities for type constructors (see
+Section~\ref{subsec:The-Yoneda-identities-for-type-constructors})
+and for lawful FM-typeclasses (used in Section~\ref{subsec:The-Jaskelioff-OConnor-theorem}
+in the proof of the Jaskelioff-O\textsf{'}Connor theorem).
+
+We turn to further applications of parametricity that go beyond what
+the Yoneda identities can achieve. Section~\ref{subsec:The-Church-encoding-of-recursive-types}
+gives full proofs of the Church encoding of a recursive type defined
+as the least fixpoint ($\mu A.\,F^{A}$) of a pattern functor $F$.
+It is also shown (Statement~\ref{subsec:Statement-existence-of-church-encoding-type})
+that the least fixpoint is non-void if and only if the type $F^{\bbnum 0}$
+is non-void. This section develops the machinery of $F$-functor algebras,
+catamorphisms, and defining the recursive type $\mu A.\,F^{A}$ via
+the standard functions \lstinline!fix! and \lstinline!unfix!.
+
+Section~\ref{subsec:The-Church-Yoneda-identity} proves a useful
+isomorphism that generalizes both the Church encoding and the Yoneda
+identity:
+\[
+G^{\mu A.\,F^{A}}\cong\forall A.\,(F^{A}\rightarrow A)\rightarrow G^{A}\quad.
+\]
+In this book, this is called the \textsf{``}Church-Yoneda\textsf{''} identity. One
+application of that identity is in proving the \textsf{``}nested fixpoint
+lemma\textsf{''} (Statement~\ref{subsec:Statement-nested-fixpoints}):
+\[
+\mu A.\,(\mu B.\,N^{A,B})\cong\mu B.\,N^{B,B}\quad.
+\]
+Another is to establish the formula for the Church encoding of mutually
+recursive types (Section~\ref{subsec:Least-fixpoints-of-mutually-recursive-types}).
-{*}{*}{*}
+A general property of universal quantifiers is distributivity with
+respect to products, co-products, and function types (Statement~\ref{subsec:Statement-general-identities-forall}).
+Distributivity with respect to co-products,
+\[
+\forall A.\,F^{A}+G^{A}\cong(\forall A.\,F^{A})+(\forall A.\,G^{A})\quad,
+\]
+can be generalized to the following isomorphism:
+\[
+\forall A.\,P^{A}\rightarrow F^{A}+G^{A}\cong(\forall A.\,P^{A}\rightarrow F^{A})+(\forall A.\,P^{A}\rightarrow G^{A})\quad.
+\]
+This holds for type constructors $P$ that are, in our terminology,
+\textsf{``}non-disjunctive\textsf{''}. Section~\ref{subsec:Non-disjunctive-type-constructors}
+gives a formal definition of that property and goes through structural
+analysis, discovering various non-disjunctive type constructors. Some
+recipes for building non-disjunctive type constructors are shown in
+Example~\ref{subsec:Example-undisjunctive-type-constructors} and
+are generalized in Table~\ref{tab:Non-disjunctive-type-constructions}.
+
+We turn to a brief study of existentially quantified types. Section~\ref{subsec:Existential-type-quantifiers}
+proves the two co-Yoneda identities and establishes some other fundamental
+properties of existential types. Then Section~\ref{subsec:The-greatest-fixpoints-and-Church-co-Yoneda}
+shows that the greatest fixpoint of a functor $F$ is given by the
+Church encoding:
+\[
+\nu A.\,F^{A}\cong\exists A.\,(A\rightarrow F^{A})\times A\quad,
+\]
+and also proves the Church-co-Yoneda identity: for any functors $F$
+and $G$,
+\[
+G^{\nu A.\,F^{A}}\cong\exists A.\,(A\rightarrow F^{A})\times G^{A}\quad.
+\]
+This identity allows us to derive the nested fixpoint lemma and the
+mutual recursion formula for the greatest fixpoints.
+
+These techniques allow us to derive a number of properties for types
+with universal and existential quantifiers. Tables~\ref{tab:Type-identities-proved-by-Yoneda}\textendash \ref{tab:Type-identities-for-existential-types}
+summarize the type isomorphisms proved in this Appendix by various
+techniques.
+
+The final sections of the Appendix study the Jaskelioff-O\textsf{'}Connor theorem
+and its applications to problems raised in this book. One of those
+applications is a proof that the identity function of type $\forall A.\,M^{A}\rightarrow M^{A}$
+is the only monad morphism between a monad $M$ and itself that obeys
+the monadic naturality law with respect to $M$. This property means
+that the non-degeneracy law of base runners (derived in Chapter~\ref{chap:monad-transformers})
+is always satisfied automatically and does not need to be verified
+separately for each monad transformer.
\setcounter{secnumdepth}{3}%
\begin{comment}
Restore the normal numbering of subsections and subsubsections
\end{comment}
-
+)
\section{Topics not covered in this book}
@@ -470,7 +1270,7 @@ \section{Topics not covered in this book}
\subsection{Trampolines and stack-safe recursion in functor blocks}
-Recursion with applicative and monadic functors (say, a loop with
+Recursion with applicative and monadic functors (say, a loop within
the free monad) can lead to stack overflows when the nesting of \lstinline!flatMap!
methods becomes too deep. There are certain tricks that can be used
to ensure stack safety. One of those tricks is known as \textsf{``}trampolines\textsf{''}.
@@ -479,10 +1279,10 @@ \subsection{Trampolines and stack-safe recursion in functor blocks}
Despite the practical significance of those techniques, this book
does not discuss them in detail. Trampolines are already well described
in the book \textsf{``}Functional programming in Scala\textsf{''}. Stack-safe implementations
-of standard monads have better performance but are mathematically
-equivalent to the same monads implemented via simple, non-stack-safe
-code. There is no new theory to be developed and no new laws to be
-proved about code that is specially engineered to be stack-safe.
+of standard monads are complicated but are mathematically equivalent
+to the same monads implemented via simple, non-stack-safe code. There
+is no new theory to be found and no new laws to be proved about code
+that is specially engineered to be stack-safe.
\subsection{Strictness and laziness}
@@ -505,7 +1305,7 @@ \subsection{Combined typeclasses and their laws}
Sequences and trees are perhaps the most frequently used data structures.
Those data structures have at once the properties of several typeclasses:
-\lstinline!Functor!, \lstinline!Filterable!, \lstinline!Monad!,
+\lstinline!Functor!, \lstinline!Monad!, \lstinline!Filterable!,
\lstinline!Applicative!, and \lstinline!Traversable!. It turns out
that the methods of various typeclasses satisfy not only the laws
of their own typeclass but also additional laws that express a kind
@@ -539,16 +1339,27 @@ \subsection{Comonads and comonad transformers}
\text{ex}_{F}:\forall A.\,F^{A}\rightarrow A\quad,\quad\quad\text{dupl}_{F}:\forall A.\,F^{A}\rightarrow F^{F^{A}}\quad.
\]
The type signatures of those methods are similar to the type signatures
-of the monads\textsf{'} methods \lstinline!pure! and \lstinline!flatten!
+of the monadic methods \lstinline!pure! and \lstinline!flatten!,
except that the function arrows point in the opposite direction:
\[
\text{pu}_{F}:\forall A.\,A\rightarrow F^{A}\quad,\quad\quad\text{ftn}_{F}:\forall A.\,F^{F^{A}}\rightarrow F^{A}\quad.
\]
-The comonad\textsf{'}s methods must also satisfy the appropriate laws. Similarly
-to monads, two comonads can be combined via \textsf{``}comonad transformers\textsf{''}
-into a larger comonad. An example of a comonad is the non-empty list
-(\lstinline!NEL!). There is also a \textsf{``}co-free comonad\textsf{''} construction,
-similar to the free monad.
+The \textsf{``}co-Kleisli\textsf{''} functions have type $F^{A}\rightarrow B$ and
+are composed via the \textsf{``}co-Kleisli composition\textsf{''} operation that has
+the type signature:
+\[
+(F^{A}\rightarrow B)\rightarrow(F^{B}\rightarrow C)\rightarrow F^{A}\rightarrow C\quad.
+\]
+
+The comonad\textsf{'}s methods must also satisfy the appropriate laws. An example
+of a comonad is the non-empty list (\lstinline!NEL!). Some comonads
+are analogous to known monads: for instance, there is a \textsf{``}reader
+comonad\textsf{''} $F^{A}=R\rightarrow A$ (where $R$ needs to be a monoid),
+the \textsf{``}writer comonad\textsf{''} $F^{A}\triangleq A\times W$ (this time,
+$W$ does not need to be a monoid), and the \textsf{``}store comonad\textsf{''} $F^{A}\triangleq S\times(S\rightarrow A)$.
+There is also a \textsf{``}co-free comonad\textsf{''} construction, similarly to the
+free monad construction. Similarly to monads, two comonads can be
+combined via \textsf{``}comonad transformers\textsf{''} into a larger comonad.
Although the properties of comonads have many similarities to those
of monads, this book does not develop the corresponding theory because
@@ -587,6 +1398,12 @@ \subsection{Linear types}
\subsection{Effect systems}
Algebraic effects are currently an active topic of research and experimentation.
+Programming with \textsf{``}effects\textsf{''} and \textsf{``}handlers\textsf{''} is intended to replace
+the monad-based design patterns and in particular avoid the need for
+monad transformers, which have proved to be complicated and hard to
+use. Effect systems can be viewed also as a way of incorporating the
+\textsf{``}free monad\textsf{''} design pattern more directly into a programming language.
+
The basic idea of an effect system is to use type signatures that
indicate precisely what side effects a function may execute when it
is evaluated. For instance, there is one effect type for printing
@@ -605,6 +1422,51 @@ \subsection{Effect systems}
have been created recently. It is perhaps too early to say what form
of effect-oriented programming will gain wide use.
+\subsection{Programming language theory}
+
+Certain theoretical questions are of interest to designers of programming
+languages but not to users of those languages. Here are some examples
+of such questions:
+\begin{itemize}
+\item Proving that type inference and type checking are terminating procedures.
+\item Proving that evaluation will be always error-free once an expression
+has been type-checked. (\textsf{``}Soundness\textsf{''} of the type system.)
+\item Proving that evaluating an expression will always give the same results
+regardless of which part of the expression is evaluated first; or
+providing precise conditions for that to be true.
+\item Proving that composition of functions is associative by using a rigorous
+definition of what it means for functions to be equal.
+\item Defining a rigorous mathematical semantics for each construction of
+a programming language and proving its properties (for example, that
+it is equivalent, or not equivalent, to the semantics of some other
+language).
+\end{itemize}
+This book does not pursue those topics.
+
+\subsection{Bibliography}
+
+This book does not include a list of references at the end. Instead,
+throughout the book there are footnote references to books, papers,
+video presentations, and blog posts that have some relevance to the
+material being discussed.
+
+The lack of bibliography is appropriate because this book is a pedagogical
+tutorial, not an academic treatise. One of the purposes of an academic
+treatise is to demonstrate ample continuity with previously published
+research. An academic bibliography helps reviewers understand in what
+new direction the presented research goes, without having to read
+the text itself. It also helps other academic authors whose career
+depends on increased citation counts. For those purposes, it is convenient
+to see a bibliography showing tens or hundreds of references to established
+academic literature.
+
+In contrast, the vision of this book is to present a sequence of pedagogically
+accessible steps that will help readers to learn the theoretical material
+relevant for the practice of functional programming. All explanations
+are self-contained; it is not assumed that the reader will first learn
+from some other books or papers on FP before embarking on this book.
+So, a bibliography section will not help the readers.
+
\section{Additional exercises and open problems\label{chap:Exercises-in-AFTT}}
The following is a sample set of problems that can be solved using
@@ -844,7 +1706,7 @@ \subsubsection{Exercise \label{par:Exercise-additional-12}\ref{par:Exercise-addi
\subsubsection{Exercise \label{par:Problem-monads-1}\ref{par:Problem-monads-1}}
-\footnote{This was an open problem but it was solved by Hew Wolff.}
+\footnote{This was an open problem solved in 2024 by Hew Wolff (private communication).}
Prove that $L^{A}\triangleq\bbnum 1+\underbrace{A\times A\times...\times A}_{n\text{ times}}$
cannot be made into a monad if $n\ge2$.
@@ -883,16 +1745,6 @@ \subsubsection{Exercise \label{par:Exercise-additional-14}\ref{par:Exercise-addi
Implement \lstinline!Functor!, \lstinline!Applicative!, and \lstinline!Traversable!
instances for \lstinline!Triang!.
-\subsubsection{Exercise \label{par:Exercise-additional-15}\ref{par:Exercise-additional-15}}
-
-Simplify the type $\forall A.\,((A\rightarrow A)\rightarrow A)\rightarrow A$,
-or in Scala:
-\begin{lstlisting}
-def f[A]: ((A => A) => A) => A
-\end{lstlisting}
-into a type expression that contains no quantifiers. Show how to implement
-all possible values of this type. \footnote{See \texttt{\href{https://cstheory.stackexchange.com/questions/53855/}{https://cstheory.stackexchange.com/questions/53855/}}}
-
\subsubsection{Exercise \label{par:Problem-Peirce-law}\ref{par:Problem-Peirce-law}}
Consider the functor $F$ defined by:
@@ -910,8 +1762,8 @@ \subsubsection{Exercise \label{par:Problem-Peirce-law}\ref{par:Problem-Peirce-la
\subsubsection{Exercise \label{par:Problem-Peirce-law-2}\ref{par:Problem-Peirce-law-2}}
-Prove the following type equivalences (assuming a fixed type $P$):
-
+Prove the following type equivalences (here $P$ is a fixed type):
+\begin{center}
\begin{tabular}{|c|c|}
\hline
\textbf{\footnotesize{}Quantified type} & \textbf{\footnotesize{}Equivalent type}\tabularnewline
@@ -926,6 +1778,7 @@ \subsubsection{Exercise \label{par:Problem-Peirce-law-2}\ref{par:Problem-Peirce-
$\forall A.\,((A\rightarrow A)\rightarrow A)\rightarrow P$ & $P$\tabularnewline
\hline
\end{tabular}
+\par\end{center}
\subsubsection{Exercise \label{par:Exercise-additional-16-2}\ref{par:Exercise-additional-16-2}}
@@ -961,6 +1814,22 @@ \subsubsection{Exercise \label{par:Exercise-additional-16-3}\ref{par:Exercise-ad
\]
+\subsubsection{Exercise \label{par:Exercise-additional-16-3-1}\ref{par:Exercise-additional-16-3-1}}
+
+This is a generalization of Example~\ref{subsec:Example-strong-dinaturality-show-void}.
+
+\textbf{(a)} For any (covariant) functors $F$ and $G$, show that:
+\[
+\forall A.\,(A\times G^{A}\rightarrow A)\rightarrow F^{A}\cong F^{\bbnum 0}\quad.
+\]
+
+\textbf{(b)} For any contrafunctor $H$ and a type constructor $G$
+that is either covariant or contravariant, show that:
+\[
+\forall A.\,(G^{A}\rightarrow A)\rightarrow H^{A}\cong H^{\bbnum 1}\quad.
+\]
+
+
\subsubsection{Exercise \label{par:Exercise-additional-16}\ref{par:Exercise-additional-16}}
Define a monad transformer $\text{Cod}_{F}^{L}\varangle M$ for the
@@ -1046,7 +1915,8 @@ \subsubsection{Problem \label{subsec:Statement-filtering-recursive-type-church}\
such that that suitable laws hold:
\begin{align*}
{\color{greenunder}\text{naturality-identity law}:}\quad & \text{liftE}_{S}^{A,B,R}(f^{:A\rightarrow B}\bef\text{pu}_{\text{Opt}}^{B})=f^{\uparrow S^{\bullet,R}}\bef(s^{:S^{B,R}}\rightarrow\bbnum 0^{:R}+s)\quad,\\
-{\color{greenunder}\text{composition law}:}\quad & \text{liftE}_{S}^{A,B,R}(f^{:A\rightarrow\bbnum 1+B})\bef\,???\,\bef\text{liftE}_{S}^{B,C,R}(g^{:B\rightarrow\bbnum 1+C})=\text{liftE}_{S}^{A,C,R}(f\diamond_{_{\text{Opt}}}g)\quad,\\
+{\color{greenunder}\text{composition law}:}\quad & \text{liftE}_{S}^{A,B,R}(f^{:A\rightarrow\bbnum 1+B})\bef\,???\,\bef\text{liftE}_{S}^{B,C,R}(g^{:B\rightarrow\bbnum 1+C})\\
+ & \quad=\text{liftE}_{S}^{A,C,R}(f\diamond_{_{\text{Opt}}}g)\quad,\\
{\color{greenunder}\text{naturality law in }R:}\quad & (g^{:Q\rightarrow R})^{\uparrow S^{A,\bullet}}\bef\text{liftE}_{S}^{A,B,R}(f)=\text{liftE}_{S}^{A,B,Q}(f)\bef g^{\uparrow U^{B,\bullet}}\quad.
\end{align*}
Here, the bifunctor $U$ is defined by:
@@ -1167,11 +2037,12 @@ \subsubsection{Problem \label{par:Problem-monads-2}\ref{par:Problem-monads-2}}
\subsubsection{Problem \label{par:Problem-monads-5-1}\ref{par:Problem-monads-5-1}}
-For certain monads $L$, the monad transformers $T_{L}$ can be defined
-using a suitable \lstinline!swap! function. Is this always the case
-for any monad stacks built out of such monads? If each of the monads
-$L_{1}$, $L_{2}$, ..., $L_{k}$ admits a transformer defined via
-a lawful \lstinline!swap! function, will the monad $L_{1}\varangle L_{2}\varangle...\varangle L_{k}$
+For certain monads $L$ (such as the \textsf{``}rigid\textsf{''} monads), the corresponding
+monad transformers $L\varangle$ can be defined using a suitable \lstinline!swap!
+function. Is this always the case for any monad stacks built out of
+such monads? If each of the monads $L_{1}$, $L_{2}$, ..., $L_{k}$
+admits a transformer defined via a lawful \lstinline!swap! function,
+will the monad $L_{1}\varangle L_{2}\varangle...\varangle L_{k}$
also admit a transformer with a \lstinline!swap! function? (See Section~\ref{subsec:Does-a-composition-have-swap}
for some partial results.)
@@ -1216,8 +2087,8 @@ \subsubsection{Problem \label{par:Problem-monads-5-2}\ref{par:Problem-monads-5-2
\subsubsection{Problem \label{par:Problem-monads-5-2-1}\ref{par:Problem-monads-5-2-1}}
-Consider the monad transformer \lstinline!ListT! (here denoted just
-by $T$):
+Consider the monad transformer \lstinline!ListT! (here denoted by
+$T$):
\[
T^{A}\triangleq M^{L^{A}}\quad,\quad\quad L^{A}\triangleq\bbnum 1+A\times M^{L^{A}}\quad,
\]
@@ -1242,13 +2113,14 @@ \subsubsection{Problem \label{par:Problem-monads-5-2-1}\ref{par:Problem-monads-5
type signature $M^{L^{R}}\rightarrow M^{R}$ aggregates all elements
of the effectful list into a single value of type $M^{R}$ (which
is also a monoid type):
-\[
-\text{brunE}:M^{L^{R}}\rightarrow M^{R}\quad,\quad\quad\text{brunE}\triangleq\text{flm}_{M}\bigg(\,\begin{array}{|c||c|}
+\begin{align*}
+ & \text{brunE}:M^{L^{R}}\rightarrow M^{R}\quad,\\
+ & \text{brunE}\triangleq\text{flm}_{M}\bigg(\,\begin{array}{|c||c|}
& M^{R}\\
\hline \bbnum 1 & 1\rightarrow\text{pu}_{M}(e_{R})\\
R\times M^{L^{R}} & h\times t\rightarrow\text{pu}_{M}(h)\oplus_{M}\overline{\text{brunE}}\,(t)
\end{array}\,\bigg)\quad.
-\]
+\end{align*}
Here, we use the binary operation $\oplus_{M}$ of the monoid $M^{R}$,
which is defined by:
\[
@@ -1266,8 +2138,8 @@ \subsubsection{Problem \label{par:Problem-monads-5-2-1}\ref{par:Problem-monads-5
{\color{greenunder}\text{for all monoid types }A:}\quad & a^{:A}\triangleright\text{pu}_{T}\bef\text{brunE}=a^{:A}\triangleright\text{pu}_{M}\quad,\\
{\color{greenunder}\text{composition law}:}\quad & p^{:T^{T^{A}}}\triangleright\text{ftn}_{T}\bef\text{brunE }=p^{:T^{T^{A}}}\triangleright\text{brunE}\bef\text{brunE}^{\uparrow M}\bef\text{ftn}_{M}\quad.
\end{align*}
-(If so, Exercise~\ref{subsec:Exercise-traversables-10-1} would show
-that \lstinline!brunE! is also a \emph{monoid} morphism $M^{L^{A}}\rightarrow M^{A}$.)
+(If so, \lstinline!brunE! will be also a \emph{monoid} morphism $M^{L^{A}}\rightarrow M^{A}$
+by Exercise~\ref{subsec:Exercise-traversables-10-1}.) %
\begin{comment}
Failed attempts to verify the composition law:
@@ -1366,8 +2238,10 @@ \subsubsection{Problem \label{subsec:Problem-monatron-lift-reset-and-shift}\ref{
The continuation monad\textsf{'}s operations \lstinline!reset! and \lstinline!shift!
are defined by:
\begin{align*}
- & \text{reset}:\forall S.\,\text{Cont}^{R,R}\rightarrow\text{Cont}^{S,R}\quad,\quad\quad\text{reset}\triangleq c^{:\left(R\rightarrow R\right)\rightarrow R}\rightarrow k^{:R\rightarrow S}\rightarrow k(c(\text{id}))\quad,\\
- & \text{shift}:\forall A.\,((A\rightarrow R)\rightarrow\text{Cont}^{R,R})\rightarrow\text{Cont}^{R,A}\quad,\quad\quad\text{shift}\triangleq g^{:\left(A\rightarrow R\right)\rightarrow\text{Cont}^{R,R}}\rightarrow k^{:A\rightarrow R}\rightarrow g(k)(\text{id})\quad.
+ & \text{reset}:\forall S.\,\text{Cont}^{R,R}\rightarrow\text{Cont}^{S,R}\quad,\\
+ & \text{reset}\triangleq c^{:\left(R\rightarrow R\right)\rightarrow R}\rightarrow k^{:R\rightarrow S}\rightarrow k(c(\text{id}))\quad,\\
+ & \text{shift}:\forall A.\,((A\rightarrow R)\rightarrow\text{Cont}^{R,R})\rightarrow\text{Cont}^{R,A}\quad,\\
+ & \text{shift}\triangleq g^{:\left(A\rightarrow R\right)\rightarrow\text{Cont}^{R,R}}\rightarrow k^{:A\rightarrow R}\rightarrow g(k)(\text{id})\quad.
\end{align*}
How to lift these operations to an arbitrary monad stack $P$ that
contains a continuation monad?\footnote{See \texttt{\href{https://github.com/renormalist/pugs/blob/master/src/Pugs/AST/Eval.hs}{https://github.com/renormalist/pugs/blob/master/src/Pugs/AST/Eval.hs}}
@@ -1398,10 +2272,40 @@ \subsubsection{Problem \label{par:Problem-Peirce-law-1}\ref{par:Problem-Peirce-l
\[
F^{P,Q}\triangleq\forall A.\,((A\rightarrow A)\rightarrow P)\rightarrow Q\cong P\rightarrow Q\quad,
\]
-where functions of type $F^{P,Q}$ are required to be fully parametric.\footnote{See \texttt{\href{https://cstheory.stackexchange.com/questions/55588/}{https://cstheory.stackexchange.com/questions/55588/}}}
+where functions of type $F^{P,Q}$ are required to be fully parametric.
+
+An equivalent statement\footnote{See \texttt{\href{https://cstheory.stackexchange.com/questions/55588/}{https://cstheory.stackexchange.com/questions/55588/}}}
+is:
+\[
+\forall A.\,F^{A\rightarrow A}\cong F^{\bbnum 1}
+\]
+for any covariant functor $F$, under assumptions of parametricity.
+(Use this isomorphism with $F^{A}\triangleq(A\rightarrow P)\rightarrow Q$
+to obtain the previous formula.)
+
+Note that the last identity already holds for any \emph{strictly}
+\emph{positive} $F$; see Example~\ref{subsec:Example-simplify-quantifier-A-A}(a).
+Solving this problem would show if that identity holds for all covariant
+functors $F$ (not necessarily strictly positive).
An equivalent (but not actually simpler) question is to prove that:
\[
P\cong\exists A.\,(A\rightarrow A)\rightarrow P\quad.
\]
+
+\subsubsection{Problem \label{par:Problem-Peirce-law-1-1}\ref{par:Problem-Peirce-law-1-1}}
+
+Consider the following type isomorphisms:
+\begin{align*}
+ & \forall A.\,\forall B.\,F^{A\times B}\cong\forall C.\,F^{C}\quad,\\
+ & \forall A.\,\forall B.\,F^{A+B}\cong\forall C.\,F^{C}\quad,\\
+ & \forall A.\,\forall B.\,F^{A\rightarrow B}\cong\forall C.\,F^{C}\quad.
+\end{align*}
+For which $F$ do they hold or fail to hold (assuming parametricity)?
+
+The question is easy to decide when $F$ is purely covariant or purely
+contravariant. In those cases, all isomorphisms hold except for the
+one with $F^{A+B}$ when $F$ is contravariant.
+
+The question remains open when $F$ is neither covariant nor contravariant.
diff --git a/sofp-src/tex/sofp-transformers.tex b/sofp-src/tex/sofp-transformers.tex
index 921ddc740..59774bfad 100644
--- a/sofp-src/tex/sofp-transformers.tex
+++ b/sofp-src/tex/sofp-transformers.tex
@@ -11,13 +11,13 @@ \section{Practical use}
\subsection{Combining monadic effects via functor composition}
Monads describe effects that depend on previously computed values.
-It is often necessary to combine effects of several monads in one.
-For example, the effect of \lstinline!Future! is to compute values
-concurrently, while \lstinline!Option! represents a possibly missing
-value. We would like to describe a possibly missing value that is
-computed concurrently. The type constructors \lstinline!Future! and
-\lstinline!Option! are not compatible (not subtypes of each other),
-so we cannot simply use them together in one functor block:
+It is often necessary to combine effects of several monads. For example,
+the effect of \lstinline!Future! is to compute values concurrently,
+while \lstinline!Option! represents a possibly missing value. We
+would like to describe a possibly missing value that is computed concurrently.
+The type constructors \lstinline!Future! and \lstinline!Option!
+are not compatible (not subtypes of each other), so we cannot simply
+use them together in one functor block:
\begin{lstlisting}
for {
x <- Future(1)
@@ -56,7 +56,7 @@ \subsection{Combining monadic effects via functor composition}
We are forced to use pattern matching with nested functor blocks,
since that is the only way of getting access to values of type \lstinline!A!
within \lstinline!Future[Option[A]]!. The code is repetitive and
-deeply nested, which makes it hard to read and to change.
+deeply nested, which makes it hard to work with.
The first step towards solving the problem is to rewrite this monadic
program as a direct chain of computations depending on the results
@@ -1339,7 +1339,7 @@ \subsubsection{Example \label{subsec:Example-monad-stack}\ref{subsec:Example-mon
Throughout this chapter, we will build transformers for every monad
considered in this book.
-\subsection{A typeclass for monad transformers}
+\subsection{A typeclass for monad transformers\label{subsec:A-typeclass-for-monad-transformers}}
Transformers such as \lstinline!EitherT! and \lstinline!StateT!
are type constructors that depend on an arbitrary foreign monad $M$
@@ -1350,16 +1350,19 @@ \subsection{A typeclass for monad transformers}
typeclass can look like this:
\begin{lstlisting}[mathescape=true]
type Id[A] = A // The identity monad$\color{dkgreen}\texttt{'}$s typeclass instance must be defined elsewhere.
-trait MTrans[T[_[_]]] { // The type parameter T is a type constructor with 2 parameters.
+trait MTrans[T[_[_]]] { // The type parameter T has kind $(*\rightarrow*)\rightarrow *\rightarrow*$.
def monadT[M[_]: Monad]: Monad[T[M, *]] // A monad instance must exist for T[M, *].
def flift[M[_]: Monad, A]: M[A] => T[M, A]
def blift[M[_]: Monad, A]: T[Id, A] => T[M, A] = frun[Id, M, A](Monad[M].pure)
def frun[M[_]: Monad, N[_]: Monad, A](phi: M[A] => N[A]): T[M, A] => T[N, A]
}
\end{lstlisting}
-The transformer\textsf{'}s code is parametric in the foreign monad $M$ (but
-not in the base monad $L$). Although \lstinline!blift! can be implemented
-via \lstinline!frun! as $\text{blift}_{L}^{M}\triangleq\text{frun}_{L}^{\text{Id},M}(\text{pu}_{M})$,
+The transformer\textsf{'}s code is parametric in the foreign monad $M$ but
+not in the base monad $L$; in fact, the code of \lstinline!MTrans!
+does not refer to $L$ at all.
+
+Although \lstinline!blift! can be implemented via \lstinline!frun!
+as $\text{blift}_{L}^{M}\triangleq\text{frun}_{L}^{\text{Id},M}(\text{pu}_{M})$,
it is convenient to keep all three methods defined separately in the
typeclass.
@@ -1490,7 +1493,7 @@ \subsection{Lifts and runners for monad stacks}
stack support the foreign and base runners, we can run the effects
of any chosen monad, e.g., like this:
\[
-\text{frun}_{K}^{L\varangle M\varangle N}(\text{frun}_{L}^{M\varangle N}(\text{brun}_{M}^{N}(\theta_{M}))):K\varangle L\varangle M\varangle N\leadsto K\varangle L\varangle N\quad.
+\text{frun}_{K}^{L\varangle M\varangle N,L\varangle N}(\text{frun}_{L}^{M\varangle N,N}(\text{brun}_{M}^{N}(\theta_{M}))):K\varangle L\varangle M\varangle N\leadsto K\varangle L\varangle N\quad.
\]
As in the case of lifts, the implementations of the runners depend
on the order of monads in the stack and will have to be changed if
@@ -3325,7 +3328,7 @@ \section{Common properties of compositional transformers \label{sec:Monad-transf
laws for the runners \lstinline!frun! and \lstinline!brun!, which
we will need to derive separately for each of the two kinds of transformers.
-\subsection{Motivation for the \texttt{swap} function}
+\subsection{Motivation for the \texttt{swap} function\label{subsec:Motivation-for-the-swap-function}}
The first task is to verify the monad laws; that is, to show that
$T\triangleq L\circ M$ is a lawful monad. For that, we need to define
@@ -3446,7 +3449,8 @@ \subsection{Motivation for the \texttt{swap} function}
operation.\footnote{The paper \textsf{``}\emph{Composing monads}\textsf{''} (\texttt{\href{http://web.cecs.pdx.edu/~mpj/pubs/RR-1004.pdf}{http://web.cecs.pdx.edu/$\sim$mpj/pubs/RR-1004.pdf}})
studied the \lstinline!swap! operation.}
-\subsection{Deriving the necessary laws for \texttt{swap}}
+\subsection{Deriving the necessary laws\label{subsec:Deriving-the-necessary-laws-for-swap}
+for \texttt{swap}}
The first law is that \texttt{}\lstinline!swap! must be a natural
transformation. Since \texttt{}\lstinline!swap! has only one type
@@ -4772,12 +4776,11 @@ \section{Composed-outside transformers. Rigid monads\label{sec:transformers-rigi
Section~\ref{sec:transformers-linear-monads} shows that the composed-inside
transformers are available for monads\index{monads!linear} of the
-form $M^{A}=P+Q\times A$ and $M^{A}=Q\times\left(P+A\right)$, called
-\textsf{``}linear\textsf{''}. No other examples of composed-inside transformers are
-known. It turns out that the composed-\emph{outside} transformers
+form $M^{A}=P+Q\times A$. No other examples of composed-inside transformers
+are known. It turns out that the composed-\emph{outside} transformers
are available for a significantly wider range of monads. Those monads
-are called \textsf{``}rigid\textsf{''} in this book\footnote{Monads of this kind do not seem to have an already accepted name.}
-because one of their general properties is having a single, fixed
+are called \textsf{``}rigid\textsf{''} in this book\footnote{Monads of this kind do not seem to have an already accepted name.
+See the discussion here: \texttt{\href{https://stackoverflow.com/questions/39649497/}{https://stackoverflow.com/questions/39649497/}}} because one of their general properties is having a single, fixed
\textsf{``}data shape\textsf{''} (see Statement~\ref{subsec:Statement-rigid-functor-wrapped-unit-is-unit}
below).\index{monads!rigid}
@@ -4793,7 +4796,8 @@ \subsubsection{Definition \label{subsec:Definition-rigid-monad}\ref{subsec:Defin
Two examples of rigid monads are the \lstinline!Reader! monad and
the \lstinline!Sel! (selector)\index{monads!Sel (selector) monad@\texttt{Sel} (selector) monad}
-monad:\footnote{See \href{http://math.andrej.com/2008/11/21/}{http://math.andrej.com/2008/11/21/}}
+monad:\footnote{See \href{http://math.andrej.com/2008/11/21/}{http://math.andrej.com/2008/11/21/}
+for a discussion of the selector monad.}
\begin{align*}
\text{(the \texttt{Reader} monad)} & :\quad\quad\text{Reader}^{Z,A}\triangleq Z\rightarrow A\quad,\\
\text{(the \texttt{Sel} monad)} & :\quad\quad\text{Sel}^{Z,A}\triangleq\left(A\rightarrow Z\right)\rightarrow A\quad,
@@ -5444,7 +5448,7 @@ \subsubsection{Statement \label{subsec:Statement-choice-monad-swap}\ref{subsec:S
This concludes the proof of the laws for the \textsf{``}choice\textsf{''} monad\textsf{'}s
transformer.
-\section{Transformers for other monad constructions}
+\section{Transformers for other monad constructions\label{sec:Transformers-for-products-and-free-pointed}}
\subsection{Transformer for products of monads. Proofs}
@@ -6458,7 +6462,7 @@ \subsubsection{Statement \label{subsec:Statement-monad-morphism-composition-theo
This derivation concludes the proof of the laws of the free pointed
monad transformer.
-\section{Transformers for recursive monads}
+\section{Transformers for recursive monads\label{sec:Transformers-for-recursive-monads}}
\subsection{Transformer for free monads. Proofs}
@@ -6487,7 +6491,7 @@ \subsubsection{Statement \label{subsec:Statement-free-monad-transformer}\ref{sub
\paragraph{Monad laws}
-Heuristically we may say that the recursively defined type $(\text{Free}\varangle M)^{A}$
+Heuristically we may that the recursively defined type $(\text{Free}\varangle M)^{A}$
contains \textsf{``}infinitely many\textsf{''} nested layers of the monad $M$ composed
with the functor $F$. Denote by $L$ the type constructor defined
recursively by:
@@ -6845,9 +6849,9 @@ \subsubsection{Statement \label{subsec:Statement-free-monad-transformer}\ref{sub
To implement the base runner, we use the similarity between the two
disjunctive types:
\[
-L^{A}\triangleq\text{Free}^{F\circ M,A}=A+F^{M^{\text{Free}^{F\circ M,A}}}=A+(F\circ M\circ L)^{A}\:\text{ and }\:\text{Free}^{F,M^{A}}=M^{A}+F^{\text{Free}^{F,M^{A}}}\quad.
+L^{A}\triangleq\text{Free}^{F\circ M,A}=A+F^{M^{\text{Free}^{F\circ M,A}}}=A+(F\circ M\circ L)^{A}\text{ and }\text{Free}^{F,M^{A}}=M^{A}+F^{\text{Free}^{F,M^{A}}}\quad.
\]
-The code for the base runner is:
+ The code for the base runner is:
\begin{align*}
& \text{brun}:(\text{Free}^{F}\leadsto\text{Id})\rightarrow M^{L^{A}}\rightarrow M^{A}\quad,\\
& \text{brun}\,(\theta^{:\text{Free}^{F}\leadsto\text{Id}})\triangleq\\
@@ -8727,8 +8731,8 @@ \subsubsection{Statement \label{subsec:Statement-laws-of-prod-for-effectful-list
\section{Incomplete transformers}
-A monad transformer that obeys the laws of a pointed and co-pointed
-functor in the category of monads (see Section~\ref{subsec:Category-theoretic-properties-of-lifts-and-runners-functors-in-category-of-monads})
+A monad transformer that obeys the laws of a pointed functor in the
+category of monads (see Section~\ref{subsec:Category-theoretic-properties-of-lifts-and-runners-functors-in-category-of-monads})
will give the programmer full flexibility of combining monadic effects.
We may call such transformers \textbf{complete}.\index{monad transformers!completeness}
The monad transformers for linear monads, rigid monads, product monads,
@@ -9038,7 +9042,7 @@ \subsubsection{Statement \label{subsec:Statement-state-monad-transformer}\ref{su
\end{align*}
-\subsection{Transformer for the continuation monad. Proofs}
+\subsection{Transformer for the continuation monad. Proofs\label{subsec:Transformer-for-the-continuation-monad}}
The continuation monad transformer\textsf{'}s type constructor \lstinline!ContT[R, M[_], *]!
is defined by:
@@ -9131,13 +9135,13 @@ \subsection{Transformer for the continuation monad. Proofs}
\subsection{Transformer for the generalized \texttt{Search} monad. Proofs\label{subsec:Transformer-for-the-generalized-search-monad}}
-The generalized\index{monads!generalized Search monad@generalized \texttt{Search} monad}
+The generalized\index{monads!Search monad@\texttt{Search} monad}
\lstinline!Search! monad is defined, for a fixed monad $L$ and a
fixed type $Q$, by:
\[
\text{Search}^{L,Q,A}\triangleq(A\rightarrow L^{Q})\rightarrow L^{A}\quad.
\]
-The ordinary \lstinline!Search! monad is obtained with $L\triangleq\text{Opt}$
+The ordinary \lstinline!Search! monad is obtained with $L^{A}\triangleq\bbnum 1+A$
and $Q\triangleq\bbnum 1$.
\subsubsection{Statement \label{subsec:Statement-generalized-search-monad}\ref{subsec:Statement-generalized-search-monad}}
@@ -9154,20 +9158,19 @@ \subsubsection{Statement \label{subsec:Statement-generalized-search-monad}\ref{s
\subparagraph{Proof}
-We assume that $L\varangle$ already satisfies all the necessary transformer
-laws.
+We assume that $L\varangle$ already satisfies all the laws of transformers.
\paragraph{Monad laws}
The monad laws hold for $\text{Search}^{L,Q,A}$ due to Statement~\ref{subsec:Statement-monad-construction-3},
-where we use the $L$-filterable contrafunctor $H^{A}\triangleq A\rightarrow L^{Q}$
+where we use the $L$-filterable contrafunctor $K^{A}\triangleq A\rightarrow L^{Q}$
(see Statement~\ref{subsec:Statement-examples-of-filterable-contrafunctors}).
Similarly, we find that the monad laws hold for \lstinline!Search!$\,\varangle M$
if we use the $L\varangle M$-filterable contrafunctor $H^{A}\triangleq A\rightarrow(L\varangle M)^{Q}$,
where we assume that $L\varangle M$ is a lawful monad. We will use
-this definition of $H^{A}$ in the proof below. For brevity, we will
-denote the transformed monad \lstinline!Search!$\,\varangle M$ by
-just $T$ (the foreign monad $M$ is fixed throughout the derivations).
+this definition of $H$ in the proof below. We denote the transformed
+monad \lstinline!Search!$\,\varangle M$ by just $T$ for brevity
+(the foreign monad $M$ is fixed throughout the derivations).
The monad methods of $T$ are defined according to Statement~\ref{subsec:Statement-monad-construction-3}:
\begin{align*}
@@ -9357,11 +9360,11 @@ \subsection{The codensity monad and its transformer. Proofs\label{subsec:The-cod
\subsubsection{Statement \label{subsec:Statement-monad-with-quantifier}\ref{subsec:Statement-monad-with-quantifier}}
-Assume a monad $K^{R,\bullet}$ with an extra type parameter $R$.
-In other words, $K^{R,A}$ is a lawful monad with respect to the type
-parameter $A$ and with a fixed $R$. Then: \textbf{(a)} $L^{A}\triangleq\forall R.\,K^{R,A}$
+Assume $K^{R,A}$ is a lawful monad with respect to the type parameter
+$A$ and with a fixed type $R$. Then: \textbf{(a)} $L^{A}\triangleq\forall R.\,K^{R,A}$
is also a lawful monad. \textbf{(b)} For any fixed $R$, there is
-a monad morphism of type $L^{\bullet}\leadsto K^{R,\bullet}$.
+a monad morphism of type $L^{\bullet}\leadsto K^{R,\bullet}$ (that
+is, $\forall A.\,L^{A}\rightarrow K^{R,A}$).
\subparagraph{Proof}
@@ -9642,6 +9645,8 @@ \subsubsection{Statement \label{subsec:Statement-codensity-monad-transformer}\re
$S$ is unrestricted. So, the same laws will hold for \lstinline!flift!
where $S$ is restricted to types of the form $F^{R}$.
+\section{Further developments}
+
\subsection{Examples of monads with several different transformers\label{subsec:Examples-of-monads-with-two-different-transformers}}
As a rule, a monad has only one monad transformer. This section shows
@@ -9713,7 +9718,7 @@ \subsection{Examples of monads with several different transformers\label{subsec:
(\text{FTC}\varangle M)^{A}\triangleq\forall X^{:\text{TC}}.\,(A\rightarrow M^{X})\rightarrow M^{X}\quad.
\]
Note that $\text{FTC}^{A}$ is always a monad (by Statement~\ref{subsec:Statement-monad-with-quantifier}
-and, for $P$-typeclasses, by Statement~\ref{subsec:Statement-free-typeclass-encoding-is-a-monad}).
+and, for $FM$-typeclasses, by Statement~\ref{subsec:Statement-free-typeclass-encoding-is-a-monad}).
For some typeclasses, $\text{FTC}^{A}$ is equivalent to a simpler
known monad $G^{A}$. Specific examples are found with \lstinline!TC!$\,=\,$\lstinline!Monoid!
and $G$$\,=\,$\lstinline!List! (see Exercise~\ref{par:Exercise-additional-16-1}(e)),
@@ -9722,8 +9727,6 @@ \subsection{Examples of monads with several different transformers\label{subsec:
a new transformer for the monad $G$ that is not equivalent to $G$\textsf{'}s
\textsf{``}standard\textsf{''} transformer.
-\section{Further developments}
-
\subsection{Some properties of monad morphisms}
In this section we prove some properties of monad morphisms needed
@@ -11901,30 +11904,43 @@ \subsubsection{Example \label{subsec:Example-monatron-free-monad-operation}\ref{
the given operations. But a free monad cannot describe an operation
that is not equivalent to a \textsf{``}simple\textsf{''} one.
-\subsection{Summary of monad transformer constructions}
+\subsection{Summary of monad transformer constructions\label{subsec:Summary-of-monad-transformer-constructions}}
-Monad transformers seen in this chapter fall into one of the 6 cases:
+All known monad transformers fall into one of the 7 cases:
1. Compositional transformers that work by functor composition in
one or another order. This applies to \lstinline!Either!, \lstinline!Writer!,
\lstinline!Reader!, and the \textsf{``}rigid\textsf{''} monads.
-2. The special monads \lstinline!State!, \lstinline!Cont!, \lstinline!Cod!,
-\lstinline!Search!, whose transformers are not fully-featured.
+2. The special \lstinline!State! monad has a special, fully featured
+transformer. The only deficiency is that the transformer \lstinline!StateT!
+has no lawful base runner.
+
+3. The \textsf{``}continuation-like\textsf{''} monads have transformers that are incomplete,
+having no foreign runners or base lifts. These are the transformers
+for the continuation monad (Section~\ref{subsec:Transformer-for-the-continuation-monad}),
+the search monad (Section~\ref{subsec:Transformer-for-the-generalized-search-monad}),
+the codensity monad (Section~\ref{subsec:The-codensity-monad}),
+and the \textsf{``}composed codensity\textsf{''} monad (Exercise~\ref{subsec:Exercise-combined-codensity-monad}).
-3. The \lstinline!List! monad and the free monad have recursively
+4. The \lstinline!List! monad and the free monad have recursively
defined transformers.
-4. The transformer for a Cartesian product of monads is the Cartesian
-product of transformers.
+5. The transformer for a product of monads is the product of transformers.
-5. The free pointed monad has its special transformer.
+6. The free pointed monad has its special transformer.
-6. Monad stacks (monads of the form $K\varangle L\varangle...\varangle P$
-where $K$, $L$, ..., $P$ are given monads).
+7. Monad stacks (monads of the form $K\varangle L\varangle...\varangle P$
+where $K$, $L$, ..., $P$ are given monads) have transformers defined
+via larger monad stacks, making the operation $\varangle$ associative.
-No one knows any explicit examples of monads that do not fit into
-one of these cases.
+Known monad transformers are complete (that is, they are pointed endofunctors
+in the category of monads) for all monads except the \textsf{``}continuation-like\textsf{''}
+monads whose type signatures have the form $(A\rightarrow P^{...})\rightarrow Q^{...}$.
+These are \lstinline!Cont!, \lstinline!Cod!, \lstinline!Search!,
+and the composed codensity monads. The transformers for those monads
+have type signatures of the form $(A\rightarrow M^{P^{...}})\rightarrow M^{Q^{...}}$,
+which is not covariant with respect to $M$.
\subsection{Exercises\index{exercises}}
@@ -12011,10 +12027,9 @@ \subsubsection{Exercise \label{subsec:Exercise-monad-transformer-extra-layer-3}\
x <- m
} yield x
\end{lstlisting}
-\begin{align*}
-m^{:M^{A}}\triangleright\text{dbl} & \triangleq m\triangleright\text{flm}_{M}(\_^{:A}\rightarrow m)\\
- & =m\triangleright(\_\rightarrow m)^{\uparrow M}\bef\text{ftn}_{M}\quad.
-\end{align*}
+\[
+m^{:M^{A}}\triangleright\text{dbl}\triangleq m\triangleright\text{flm}_{M}(\_^{:A}\rightarrow m)\quad.
+\]
This function \textsf{``}doubles\textsf{''} the $M$-effect in a given monadic value
$m$ while keeping the value $x^{:A}$ from the second copy of $m$.
@@ -12047,7 +12062,7 @@ \subsubsection{Exercise \label{subsec:Exercise-monad-morphism-reader-writer-morp
\subsubsection{Exercise \label{subsec:Exercise-monad-morphism-reader-state}\ref{subsec:Exercise-monad-morphism-reader-state}}
Consider the monads $\text{Reader}^{R,A}$ and $\text{State}^{R,A}$
-(where $R$ is a fixed type).\index{monads!State monad@\texttt{State} monad}\index{monads!Reader monad@\texttt{Reader} monad}
+($R$ is a fixed type).\index{monads!State monad@\texttt{State} monad}\index{monads!Reader monad@\texttt{Reader} monad}
\textbf{(a)} Implement a monad morphism $\text{inS}:\text{Reader}^{R,A}\rightarrow\text{State}^{R,A}$
and prove that the laws hold.
@@ -12089,17 +12104,13 @@ \subsubsection{Exercise \label{subsec:Exercise-monad-transformer-extra-layer-2}\
\[
U^{A}\triangleq L^{(L\varangle M)^{A}}\quad,\quad\quad V^{A}\triangleq M^{(L\varangle M)^{A}}\quad.
\]
-In a shorter notation, $U\triangleq L\circ(L\varangle M)$ and $V\triangleq M\circ(L\varangle M)$.
-We have the \lstinline!swap! functions:
-\begin{align*}
-\text{sw}_{L,T} & :(L\varangle M)\circ L\leadsto L\circ(L\varangle M)\quad,\\
-\text{sw}_{M,T} & :(L\varangle M)\circ M\leadsto(M\circ L)\varangle M\quad,
-\end{align*}
-defined using the already given methods \lstinline!flift! and \lstinline!blift!
-of $L\varangle M$ as:
+For brevity, denote $T\triangleq L\varangle M$, $U\triangleq L\circ T$,
+and $V\triangleq M\circ T$. The \lstinline!swap! functions are expressed
+using the already given methods \lstinline!flift! and \lstinline!blift!
+of $T$ as:
\begin{align*}
-\text{sw}_{L,T} & =\text{blift}^{\uparrow T}\bef\text{ftn}_{T}\bef\text{pu}_{L}\quad,\\
-\text{sw}_{M,T} & =\text{flift}^{\uparrow T}\bef\text{ftn}_{T}\bef\text{pu}_{M}\quad.
+\text{sw}_{L,T}:T\circ L\leadsto L\circ T\quad,\quad\quad\text{sw}_{L,T} & =\text{blift}^{\uparrow T}\bef\text{ftn}_{T}\bef\text{pu}_{L}\quad,\\
+\text{sw}_{M,T}:T\circ M\leadsto M\circ T\quad,\quad\quad\text{sw}_{M,T} & =\text{flift}^{\uparrow T}\bef\text{ftn}_{T}\bef\text{pu}_{M}\quad.
\end{align*}
We can define the monad methods $\text{ftn}_{U}$ and $\text{ftn}_{V}$
using these \lstinline!swap! functions. Will $U$ and/or $V$ be
@@ -12108,8 +12119,8 @@ \subsubsection{Exercise \label{subsec:Exercise-monad-transformer-extra-layer-2}\
\subsubsection{Exercise \label{par:Exercise-1-interchange-laws-for-ftn-T}\ref{par:Exercise-1-interchange-laws-for-ftn-T}}
For any two monads $L$ and $M$ and a natural transformation \lstinline!swap!$\,:M\circ L\leadsto L\circ M$,
-assume that the method $\text{ftn}_{T}$ of the monad $T\triangleq L\circ M$
-is \emph{defined} via \lstinline!swap! by Eq.~(\ref{eq:define-flatten-via-swap}).
+assume that $T\triangleq L\circ M$ is a lawful monad whose method
+$\text{ftn}_{T}$ is \emph{defined} via \lstinline!swap! by Eq.~(\ref{eq:define-flatten-via-swap}).
Show that the two interchange laws will then hold for $\text{ftn}_{T}$:
\begin{align*}
{\color{greenunder}\text{inner interchange law}:}\quad & \text{ftn}_{L}\bef\text{ftn}_{T}=\text{ftn}_{T}^{\uparrow L}\bef\text{ftn}_{L}\quad,\\
@@ -12138,7 +12149,7 @@ \subsubsection{Exercise \label{par:Exercise-2-prove-compat-laws-for-T-from-swap}
\subsubsection{Exercise \label{subsec:Statement-search-and-selector-monads}\ref{subsec:Statement-search-and-selector-monads}}
Define a \textsf{``}\index{monads!Search monad@\texttt{Search} monad}search
-monad\textsf{''} by $\text{Search}^{P,A}\triangleq\left(A\rightarrow\bbnum 1+P\right)\rightarrow\bbnum 1+A$.
+monad\textsf{''} by $\text{Search}^{P,A}\triangleq(A\rightarrow\bbnum 1+P)\rightarrow\bbnum 1+A$.
The function:
\begin{lstlisting}
def finder[A, P](s: (A => Option[P]) => A): (A => Option[P]) => Option[A] = {
@@ -12155,7 +12166,7 @@ \subsubsection{Exercise \label{subsec:Statement-search-and-selector-monads}\ref{
\end{align*}
transforms a \index{monads!Sel (selector) monad@\texttt{Sel} (selector) monad}selector
monad $\text{Sel}^{\bbnum 1+P,A}$ to the search monad. Show that
-\lstinline!finder! is \emph{not} a monad morphism $\text{Sel}^{\bbnum 1+P,\bullet}\leadsto\text{Search}^{P,\bullet}$.
+\lstinline!finder! is \emph{not} a monad morphism of type $\text{Sel}^{\bbnum 1+P,\bullet}\leadsto\text{Search}^{P,\bullet}$.
\subsubsection{Exercise \label{subsec:Exercise-selector-and-continuation-monads}\ref{subsec:Exercise-selector-and-continuation-monads}}
@@ -12168,8 +12179,8 @@ \subsubsection{Exercise \label{subsec:Exercise-selector-and-continuation-monads}
\text{scc}:\text{Sel}^{P,A}\rightarrow\text{Cont}^{P,A}\quad,\quad\quad\text{scc}\,(s^{:(A\rightarrow P)\rightarrow A})\triangleq f^{:A\rightarrow P}\rightarrow f(s(f))\quad.
\]
-Hint: Use the flipped Kleisli technique to simplify the proof of the
-composition law.\index{flipped@\textsf{``}flipped Kleisli\textsf{''} technique}
+Hint: Use the flipped Kleisli technique for the proof of the composition
+law.\index{flipped@\textsf{``}flipped Kleisli\textsf{''} technique}
\subsubsection{Exercise \label{subsec:Exercise-monad-product}\ref{subsec:Exercise-monad-product}}
@@ -12177,7 +12188,7 @@ \subsubsection{Exercise \label{subsec:Exercise-monad-product}\ref{subsec:Exercis
is again a monad.
\textbf{(b)} Show that the type isomorphism $(K^{A}\times L^{A})\times M^{A}\cong K^{A}\times(L^{A}\times M^{A})$
-is also a \emph{monad} isomorphism.
+has \emph{monad} \emph{morphisms} in both directions.
\subsubsection{Exercise \label{par:Exercise-mt-3-1}\ref{par:Exercise-mt-3-1}}
@@ -12200,6 +12211,13 @@ \subsubsection{Exercise \label{par:Exercise-mt-3}\ref{par:Exercise-mt-3}}
show that there exists a corresponding monad morphism $\psi:L\leadsto N$
between free pointed monads $L^{A}\triangleq A+K^{A}$ and $N^{A}\triangleq A+M{}^{A}$.\index{monads!free pointed}
+\subsubsection{Exercise \label{par:Exercise-mt-3-4}\ref{par:Exercise-mt-3-4}}
+
+For any monad $M$, implement a natural transformation of type $\forall(A,B).\,M^{A+M^{B}}\rightarrow M^{A+B}$.
+Show that this transformation is monadically natural with respect
+to a suitable law involving arbitrary monads $M$, $N$ and an arbitrary
+monad morphism $\phi:M\leadsto N$.
+
\subsubsection{Exercise \label{par:Exercise-mt-3-3}\ref{par:Exercise-mt-3-3}}
\textbf{(a)} Given two natural transformations $\phi:K^{A}\rightarrow M^{A}$
@@ -12229,8 +12247,8 @@ \subsubsection{Exercise \label{par:Exercise-mt-3-2-1}\ref{par:Exercise-mt-3-2-1}
\textbf{(a)} Show that the monad transformer for $L$ \emph{cannot}
be defined as the monad $(L\varangle M)^{A}\triangleq A+(K\varangle M)^{A}$
-because then (at least for some monads $K$ and $M$) there is no
-monad morphism $\text{flift}:M\leadsto(L\varangle M)^{A}$.
+because then there will be no monad morphism of type $M^{A}\rightarrow A+(K\varangle M)^{A}$,
+at least for some monads $K$ and $M$.
\textbf{(b)} Given a runner $\theta_{K}:K\leadsto M$, where $M$
is an arbitrary (but fixed) target monad, implement a runner $\theta_{L}:L\leadsto M$
@@ -12241,7 +12259,7 @@ \subsubsection{Exercise \label{par:Exercise-mt-3-2-1}\ref{par:Exercise-mt-3-2-1}
morphism $\theta_{K}:K\leadsto M$ given a monad morphism $\theta_{L}:L\leadsto M$,
at least for some monads $K$ and $M$.
-\textbf{(d){*}} Given a monad morphism $\theta_{L}:L^{A}\rightarrow A$,
+\textbf{(d)} Given a monad morphism $\theta_{L}:L^{A}\rightarrow A$,
implement a lawful monad morphism $\theta_{K}:K^{A}\rightarrow A$.
\subsubsection{Exercise \label{par:Exercise-mt-3-2}\ref{par:Exercise-mt-3-2}}
@@ -12254,13 +12272,13 @@ \subsubsection{Exercise \label{par:Exercise-mt-3-2-2}\ref{par:Exercise-mt-3-2-2}
It follows from Statement~\ref{subsec:Statement-monad-with-quantifier}
that adding a type quantifier to a monad gives again a monad. Show
-that adding a type quantifier to any $P$-typeclass (Section~\ref{subsec:P-typeclasses})
-gives again a $P$-typeclass. In detail: assume a $P$-typeclass defined
-via a structure functor $S^{R,\bullet}$ that has an extra type parameter
-$R$. All methods of the typeclass are then contained in a value of
-type $S^{R,A}\rightarrow A$, where the type $R$ is fixed. Show that
-$\forall R.\,S^{R,A}\rightarrow A$ is again a $P$-typeclass (with
-a different choice of the structure functor).
+that adding a type quantifier to any $FM$-typeclass (Section~\ref{subsec:P-typeclasses})
+gives again an $FM$-typeclass. In detail: assume an $FM$-typeclass
+defined via a structure functor $S^{R,\bullet}$ that has an extra
+type parameter $R$. All methods of the typeclass are then contained
+in a value of type $S^{R,A}\rightarrow A$, where the type $R$ is
+fixed. Show that $\forall R.\,S^{R,A}\rightarrow A$ is again an $FM$-typeclass
+(with a different choice of the structure functor).
\subsubsection{Exercise \label{subsec:Exercise-effectful-list-not-monad}\ref{subsec:Exercise-effectful-list-not-monad}}
@@ -12293,31 +12311,32 @@ \subsubsection{Exercise \label{subsec:Exercise-effectful-list-not-monad}\ref{sub
\subsubsection{Exercise \label{subsec:Exercise-combined-codensity-monad}\ref{subsec:Exercise-combined-codensity-monad}}
\textbf{(a)} The\index{monads!composed codensity monad} \textbf{composed}
-\textbf{codensity monad} $\text{Cod}_{F}^{L,A}$ is defined by:
+\textbf{codensity monad} $\text{Cod}_{F}^{M,\bullet}$ is defined
+by:
\[
-\text{Cod}_{F}^{L,A}\triangleq\forall X.\,(A\rightarrow F^{X})\rightarrow F^{L^{X}}\quad,
+\text{Cod}_{F}^{M,A}\triangleq\forall X.\,(A\rightarrow F^{X})\rightarrow F^{M^{X}}\quad,
\]
-where $L$ is any monad and $F$ is any functor. One may define the
-monad instance for $\text{Cod}_{F}^{L,A}$ via the flipped Kleisli
-composition:
+where $M$ is any given monad and $F$ is any given functor. The monad
+methods for $\text{Cod}_{F}^{M,\bullet}$ are defined via the flipped
+Kleisli composition:
\[
-f^{:\forall X.\,(B\rightarrow F^{X})\rightarrow A\rightarrow F^{L^{X}}}\tilde{\diamond}\,\,g^{:\forall Y.\,(C\rightarrow F^{Y})\rightarrow B\rightarrow F^{L^{Y}}}\triangleq\forall Z.\,k^{:C\rightarrow F^{Z}}\rightarrow\big(k\triangleright g^{Z}\triangleright f^{L^{Z}}\big)\bef\text{ftn}_{L}^{\uparrow F}\quad.
+f^{:\forall X.\,(B\rightarrow F^{X})\rightarrow A\rightarrow F^{M^{X}}}\tilde{\diamond}\,\,g^{:\forall Y.\,(C\rightarrow F^{Y})\rightarrow B\rightarrow F^{M^{Y}}}\triangleq\forall Z.\,k^{:C\rightarrow F^{Z}}\rightarrow\big(k\triangleright g^{Z}\triangleright f^{M^{Z}}\big)\bef\text{ftn}_{M}^{\uparrow F}\quad.
\]
-Prove that the type constructor $\text{Cod}_{F}^{L,\bullet}$ is a
+Prove that the type constructor $\text{Cod}_{F}^{M,\bullet}$ is a
lawful monad.
Hints: Use the flipped Kleisli formulation of the monad laws. Assume
-that values of type $\text{Cod}_{F}^{L,A}$ are natural transformations
-obeying the appropriate naturality law.
+that values of type $\text{Cod}_{F}^{M,A}$ are natural transformations
+obeying their naturality laws.
-\textbf{(b)} Show that the quantifier $\forall X$ cannot be removed
-from the definition of $\text{Cod}_{F}^{L,A}$ even if $F^{A}\triangleq A$:
-for a fixed type $X$ and for some $L^{\bullet}$, the type constructor
-$P^{A}\triangleq(A\rightarrow X)\rightarrow L^{X}$ is \emph{not}
-a monad.
+\textbf{(b)} Show that the quantifier $\forall X$ \emph{cannot} be
+removed from the definition of $\text{Cod}_{F}^{M,\bullet}$ even
+if $F^{X}\triangleq X$: for a fixed type $X$ and for some monad
+$M$, the functor $P^{A}\triangleq(A\rightarrow X)\rightarrow M^{X}$
+is not a monad.
\textbf{(c)} Show that in general there is \emph{no} monad morphism
-$L^{A}\rightarrow\text{Cod}_{F}^{L,A}$.
+of type $\forall A.\,M^{A}\rightarrow\text{Cod}_{F}^{M,A}$.
\subsubsection{Exercise \label{subsec:Exercise-pair-functor-is-rigid}\ref{subsec:Exercise-pair-functor-is-rigid}}
diff --git a/sofp-src/tex/sofp-traversable.tex b/sofp-src/tex/sofp-traversable.tex
index 86f6811b1..7cf8cbf05 100644
--- a/sofp-src/tex/sofp-traversable.tex
+++ b/sofp-src/tex/sofp-traversable.tex
@@ -15,8 +15,8 @@ \section{Motivation}
and \lstinline!zip!) and generalized them to many different type
constructors. This chapter adopts the same approach to examine and
generalize the \lstinline!reduce! method, which will lead to the
-concept of \textsf{``}traversable functors\textsf{''}. In this way, we will complete
-a theoretical study of the \lstinline!map!/\lstinline!reduce! programming
+concept of \textsf{``}traversable functors\textsf{''}. In this way, we complete a
+theoretical study of the \lstinline!map!/\lstinline!reduce! programming
style.
\subsection{From \texttt{reduce} and \texttt{foldLeft} to \texttt{foldMap} and
@@ -2243,14 +2243,16 @@ \subsubsection{Statement \label{subsec:relational-property-for-foldFn}\ref{subse
\begin{equation}
\text{if }x\triangleright(h^{:A\rightarrow A}\rightarrow f\bef h)^{\uparrow L}=y\triangleright(g^{:B\rightarrow B}\rightarrow g\bef f)^{\uparrow L}\quad\text{then}\quad f\bef\phi(x)=\phi(y)\bef f\quad.\label{eq:strong-dinaturality-law-of-phi-with-f}
\end{equation}
-We need to choose $A$, $B$, and $f$ appropriately in order to be
-able to derive Eq.~(\ref{eq:first-special-law-of-phi}). After some
-guessing and trying, one finds that a good choice is $B\triangleq A\rightarrow A$
-and $f^{:B\rightarrow A}$ defined by:
+We will now choose $A$, $B$, and $f$ in this equation appropriately,
+in order to derive Eq.~(\ref{eq:first-special-law-of-phi}). After
+some guessing and trying, one finds that a useful choice is to define
+$B\triangleq A\rightarrow A$. Then we choose $f^{:B\rightarrow A}$
+as the following function:
\begin{equation}
f:(A\rightarrow A)\rightarrow A\quad,\quad\quad f\triangleq k^{:A\rightarrow A}\rightarrow k(a_{0})\quad\text{with a fixed }a_{0}:A\quad.\label{eq:f-for-relational-law-of-foldFn-derivation1}
\end{equation}
-Each value $a_{0}$ of type $A$ gives us a function $f_{a_{0}}:(A\rightarrow A)\rightarrow A$
+Here, we assume that a value $a_{0}$ of type $A$ is given (and $A\neq\bbnum 0$).
+Each $a_{0}$ specifies a different function $f_{a_{0}}:(A\rightarrow A)\rightarrow A$
for which the law~(\ref{eq:strong-dinaturality-law-of-phi-with-f})
holds.
@@ -2535,7 +2537,8 @@ \subsubsection{Statement \label{subsec:Statement-reduceE-toList-equivalence}\ref
\end{align*}
The two sides are now equal. $\square$
-\subsection{The missing laws of \texttt{foldMap} and \texttt{reduce}}
+\subsection{The\label{subsec:The-missing-laws-of-foldMap-and-reduce} missing
+laws of \texttt{foldMap} and \texttt{reduce}}
The equivalence of \lstinline!foldLeft!, \lstinline!foldMap!, \lstinline!reduce!,
and \lstinline!toList! is ensured by assuming various naturality
@@ -3633,8 +3636,8 @@ \subsection{All polynomial functors are traversable\label{subsec:All-polynomial-
\text{seq}_{L}^{F,A}:S^{F^{A},L^{F^{A}}}\rightarrow F^{S^{A,L^{A}}}\quad,\quad\quad\text{seq}_{L}^{F,A}\triangleq\big(\overline{\text{seq}}_{L}^{F,A}\big)^{\uparrow S^{F^{A},\bullet}}\bef\text{seq2}_{S}^{F,A,L^{A}}\quad.
\]
This definition uses a recursive call to $\overline{\text{seq}}_{L}^{F,A}$
-lifted with respect to the type parameter $R$ of $S^{A,R}$. The
-inductive assumption is that the recursively called $\overline{\text{seq}}_{L}^{F,A}$
+lifted with respect to the type parameter $R$ of $S^{F^{A},R}$.
+The inductive assumption is that the recursively called $\overline{\text{seq}}_{L}^{F,A}$
already obeys the laws we are proving.
To verify the identity law~(\ref{eq:identity-law-of-sequence}),
diff --git a/sofp-src/tex/sofp-typeclasses.tex b/sofp-src/tex/sofp-typeclasses.tex
index 8463b0f6b..7ce34c2c9 100644
--- a/sofp-src/tex/sofp-typeclasses.tex
+++ b/sofp-src/tex/sofp-typeclasses.tex
@@ -5628,7 +5628,7 @@ \subsection{Inheritance and automatic conversions of typeclasses\label{subsec:In
Goes.} So far, it is not known whether any encoding can solve all issues
that come from multiple inheritance of typeclasses.
-\subsection{$P$-typeclasses, their laws and structure\label{subsec:P-typeclasses}}
+\subsection{FM-typeclasses, their laws and structure\label{subsec:P-typeclasses}}
We have seen that many typeclasses have similar structural properties.
For instance, a product of semigroups is again a semigroup, a product
@@ -5663,7 +5663,7 @@ \subsection{$P$-typeclasses, their laws and structure\label{subsec:P-typeclasses
\hline
\end{tabular}
\par\end{centering}
-\caption{Structure of typeclass instance values for various $P$-typeclasses.\label{tab:Types-of-typeclass-instance-values}}
+\caption{Structure of typeclass instance values for various FM-typeclasses.\label{tab:Types-of-typeclass-instance-values}}
\end{table}
The \lstinline!Semigroup! typeclass has a single method ($\oplus_{_{A}}$)
@@ -5682,24 +5682,25 @@ \subsection{$P$-typeclasses, their laws and structure\label{subsec:P-typeclasses
the empty value ($e_{_{A}}$) and the binary operation ($\oplus_{_{A}}$)
of the monoid $A$.
-This motivates the definition of \index{$P$-typeclass|textit} a $P$-\textbf{typeclass}:
+This motivates the definition of \index{FM-typeclass|textit} an FM-\textbf{typeclass}:
it is a typeclass whose instance values have type $P^{T}\rightarrow T$.
The functor $P$ is called the \index{structure functor of a typeclass}\index{typeclass!structure functor}\textbf{structure
-functor} of the typeclass.
+functor} of the typeclass. (The name \textsf{``}FM\textsf{''} stands for \textsf{``}functor/monad\textsf{''}
+and will be justified later.)
We can implement this definition by the Scala code:
\begin{lstlisting}
-final case class PTypeclass[P[_]: Functor, A](methods: P[A] => A)
+final case class FMTypeclass[P[_]: Functor, A](methods: P[A] => A)
\end{lstlisting}
-The code allows us to declare any $P$-typeclass. For example, the
-\lstinline!Monoid! typeclass can be declared by first defining a
-type constructor corresponding to the monoid\textsf{'}s structure functor ($P^{A}\triangleq\bbnum 1+A\times A$)
+The code allows us to declare any FM-typeclass. For example, the \lstinline!Monoid!
+typeclass can be declared by first defining a type constructor corresponding
+to the monoid\textsf{'}s structure functor ($P^{A}\triangleq\bbnum 1+A\times A$)
and then using that functor to define a type constructor for evidence
values (\lstinline!PMonoid!):
\begin{lstlisting}
final case class MonoidSF[A](s: Option[(A, A)])
val functorMonoidSF: Functor[MonoidSF] = ... /* implementation */
-type PMonoid[A] = PTypeclass[MonoidSF, A]
+type FMMonoid[A] = FMTypeclass[MonoidSF, A]
\end{lstlisting}
Typeclasses for type constructors (\lstinline!Functor!, \lstinline!Pointed!,
@@ -5714,23 +5715,22 @@ \subsection{$P$-typeclasses, their laws and structure\label{subsec:P-typeclasses
the additional type parameters. The laws of type constructor typeclasses
are also more complicated because they often involve multiple type
parameters and arbitrary functions. To simplify the presentation in
-this section, we will only consider $P$-typeclasses for simple types,
+this section, we will only consider FM-typeclasses for simple types,
such as \lstinline!Semigroup! or \lstinline!Monoid!.
Implementing the \lstinline!Monoid! typeclass via a structure functor
-$P$ and a function $P^{A}\rightarrow A$ is inconvenient for practical
-programming. But the form $P^{A}\rightarrow A$ is useful for reasoning
-about general properties of typeclasses. To illustrate that kind of
-reasoning, we will now show that the product-type, the function-type,
-and the recursive-type constructions work for all $P$-typeclasses.
+$P$ and a function of type $P^{A}\rightarrow A$ is inconvenient
+for practical programming. But the form $P^{A}\rightarrow A$ is useful
+for reasoning about general properties of typeclasses. To illustrate
+that kind of reasoning, we will now show that the product-type, the
+function-type, and the recursive-type constructions work for all FM-typeclasses.
\paragraph{Products}
-Consider an arbitrary $P$-typeclass \lstinline!TC! defined via a
-structure functor \lstinline!P!. If two types $A$, $B$ have an
-instance of the typeclass \lstinline!TC!, an instance for the product
-type $A\times B$ can be derived automatically using the function
-\lstinline!productTC!:
+Consider an arbitrary FM-typeclass \lstinline!TC! defined via a structure
+functor \lstinline!P!. If two types $A$, $B$ have an instance of
+the typeclass \lstinline!TC!, an instance for the product type $A\times B$
+can be derived automatically using the function \lstinline!productTC!:
\begin{lstlisting}
def productTC[A, B](u: P[A] => A, v: P[B] => B): P[(A, B)] => (A, B) = {
p => ( u(p.map(_._1)), v(p.map(_._2)) )
@@ -5741,24 +5741,23 @@ \subsection{$P$-typeclasses, their laws and structure\label{subsec:P-typeclasses
\text{productTC} & \triangleq(u^{:P^{A}\rightarrow A}\times v^{:P^{B}\rightarrow B})\rightarrow p^{:P^{A\times B}}\rightarrow(p\triangleright\pi_{1}^{\uparrow P}\triangleright u)\times(p\triangleright\pi_{2}^{\uparrow P}\triangleright v)\quad.
\end{align*}
-This argument does \emph{not} prove that the typeclass laws will also
+This argument does not prove that the typeclass \emph{laws} will also
hold for $A\times B$. We will prove that in Section~\ref{subsec:Laws-for-the-P-typeclass-constructions}
after developing some advanced techniques for formal reasoning about
-$P$-typeclass laws.
+FM-typeclass laws.
-We note that the co-product construction does \emph{not} work for
-arbitrary $P$-typeclasses: given evidence values of types $P^{A}\rightarrow A$
-and $P^{B}\rightarrow B$, we cannot always find a suitable value
-of type $P^{A+B}\rightarrow A+B$. Later we will see that some $P$-typeclasses,
-such as monads or applicative functors, do not support the co-product
-construction. The co-product of two monads is not always a lawful
-monad; the co-product of two applicative functors is not always an
-applicative functor.
+The co-product construction does \emph{not} work for arbitrary FM-typeclasses:
+given evidence values of types $P^{A}\rightarrow A$ and $P^{B}\rightarrow B$,
+we cannot always find a suitable value of type $P^{A+B}\rightarrow A+B$.
+Later we will see that some FM-typeclasses, such as monads or applicative
+functors, do not support the co-product construction. The co-product
+of two monads is not always a monad; the co-product of two applicative
+functors is not always an applicative functor.
\paragraph{Functions}
-The function-type construction creates a $P$-typeclass instance for
-the type $E\rightarrow A$ if the type $A$ belongs to the $P$-typeclass.
+The function-type construction creates an FM-typeclass instance for
+the type $E\rightarrow A$ if the type $A$ belongs to the FM-typeclass.
Using the fact that $P$ is a functor, an evidence value of type $P^{E\rightarrow A}\rightarrow E\rightarrow A$
can be computed from an evidence value of type $P^{A}\rightarrow A$
like this:
@@ -5773,7 +5772,7 @@ \subsection{$P$-typeclasses, their laws and structure\label{subsec:P-typeclasses
\paragraph{Recursive types}
Consider a recursive type $T$ defined by a type equation $T\triangleq S^{T}$,
-where the functor $S$ \textsf{``}preserves\textsf{''} $P$-typeclass instances: if
+where the functor $S$ \textsf{``}preserves\textsf{''} FM-typeclass instances: if
$A$ has an instance then $S^{A}$ also does, as we saw in all our
examples in this chapter. In other words, we have a function $\text{tcS}:(P^{A}\rightarrow A)\rightarrow P^{S^{A}}\rightarrow S^{A}$
that creates evidence values of type $P^{S^{A}}\rightarrow S^{A}$
@@ -5801,7 +5800,7 @@ \subsection{$P$-typeclasses, their laws and structure\label{subsec:P-typeclasses
def tcS: TC[A] => TC[S[A]] = ... // Compute instances for S[A] given instances for A.
def tcT: P[T] => T = p => T(tcS(tcT)(p.map(_.s))) // The recursive instance.
\end{lstlisting}
-In this way, the recursive-type construction works for any $P$-typeclass.
+In this way, the recursive-type construction works for any FM-typeclass.
(We will prove in Section~\ref{subsec:Laws-for-the-P-typeclass-constructions}
that the laws will hold automatically for the new typeclass instances.)
@@ -5809,48 +5808,49 @@ \subsection{$P$-typeclasses, their laws and structure\label{subsec:P-typeclasses
their properties are more difficult to prove. This book shows that
the product-type, the function-type, and the recursive-type constructions
work for functors, contrafunctors, pointed functors, and pointed contrafunctors,
-as well as for other important $P$-typeclasses such as filterable
-functors (Chapter~\ref{chap:Filterable-functors}), monads (Chapter~\ref{chap:Semimonads-and-monads}),
+as well as for other important FM-typeclasses such as filterable functors
+(Chapter~\ref{chap:Filterable-functors}), monads (Chapter~\ref{chap:Semimonads-and-monads}),
and applicative functors (Chapter~\ref{chap:8-Applicative-functors,-contrafunctors}).
We will see in Chapter~\ref{chap:Free-type-constructions} that another
-general construction also works for all $P$-typeclasses, \textemdash{}
+general construction also works for all FM-typeclasses, \textemdash{}
the \textsf{``}free\textsf{''} type construction.
-Some typeclasses \emph{cannot} be viewed as $P$-typeclasses. The
-\lstinline!Extractor! typeclass (see Section~\ref{subsec:Extractors-typeclasses})
-has instances of type $A\rightarrow Z$, which is not of the form
-$P^{A}\rightarrow A$ for any functor $P$. Another example is the
-\lstinline!Copointed! typeclass whose method of type $\forall A.\,F^{A}\rightarrow A$
-is not of the form $P^{F}\rightarrow F$ even if we add more type
-parameters. Instead, the evidence values of these typeclasses are
-of type $F\rightarrow P^{F}$ with a suitable functor $P$. This type
-signature can be obtained for \textsf{``}extractor\textsf{''} typeclasses, for \lstinline!Copointed!
-functors, and also for \lstinline!Traversable! functors (Chapter~\ref{chap:9-Traversable-functors-and}).
-We may call those typeclasses \textbf{co-}$P$\textbf{-typeclasses}.\index{co-$P$-typeclasses}
+Some typeclasses \emph{cannot} be viewed as FM-typeclasses. The \lstinline!Extractor!
+typeclass (see Section~\ref{subsec:Extractors-typeclasses}) has
+instances of type $A\rightarrow Z$, which is not of the form $P^{A}\rightarrow A$
+for any functor $P$. Another example is the \lstinline!Copointed!
+typeclass whose method of type $\forall A.\,F^{A}\rightarrow A$ is
+not of the form $P^{F}\rightarrow F$ even if we add more type parameters.
+Instead, the evidence values of these typeclasses are of type $F\rightarrow P^{F}$
+with a suitable functor $P$. This type signature can be obtained
+for \textsf{``}extractor\textsf{''} typeclasses, for \lstinline!Copointed! functors,
+and also for \lstinline!Traversable! functors (Chapter~\ref{chap:9-Traversable-functors-and}).
+We may call those typeclasses \textbf{co-}FM-\textbf{typeclasses}.\index{co-FM-typeclasses}
For all typeclasses whose evidence values have type $A\rightarrow P^{A}$,
some general properties will also hold. For example, the \emph{co-product}
construction (rather than the product construction) works for them.
Given evidence values of types $A\rightarrow P^{A}$ and $B\rightarrow P^{B}$,
-we can produce a value of type $A+B\rightarrow P^{A+B}$, i.e., a
-$P$-typeclass evidence for the co-product $A+B$. Similarly to $P$-typeclasses,
+we can produce a value of type $A+B\rightarrow P^{A+B}$, i.e., an
+FM-typeclass evidence for the co-product $A+B$. Similarly to FM-typeclasses,
the typeclass laws will hold automatically for the type $A+B$. A
-detailed description of co-$P$-typeclasses is beyond the scope of
-this book.
+detailed description of co-FM-typeclasses is beyond the scope of this
+book.
An example of a typeclass to which neither description applies is
the \lstinline!Eq! typeclass. Its evidence values have type $A\times A\rightarrow\bbnum 2$,
-which is neither of the form $P^{A}\rightarrow A$ nor $A\rightarrow P^{A}$.
+which is neither of the form $P^{A}\rightarrow A$ nor $A\rightarrow P^{A}$
+(where $P$ must be a covariant functor).
\subsection{Typeclasses, object-oriented interfaces, and algebraic data types}
-Typeclasses can be viewed as a way of managing various sets of methods
-that a data type must support. Scala supports two other features for
-managing data methods: object-oriented interfaces\index{object-oriented interfaces}
+Typeclasses can be viewed as a way of managing the methods that various
+data types must support. Scala has two other features for managing
+methods: object-oriented interfaces\index{object-oriented interfaces}
(OOIs) and algebraic data types\index{algebraic data types} (ADTs).
We will now compare the expressive power of all those features. We
will find that typeclasses can be seen as a generalization of both
-OOIs and ADTs, transcending their specific limitations.
+OOIs and ADTs, overcoming their specific limitations.
We begin by formulating typeclasses, OOIs, and ADTs purely in terms
of types.
@@ -5898,41 +5898,42 @@ \subsection{Typeclasses, object-oriented interfaces, and algebraic data types}
use the information from the value itself. So, the type-centric view
must consider \lstinline!isSmallerThan! as a function of \emph{two}
arguments: an argument denoted by \lstinline!this! and an argument
-\lstinline!size: Int!. To call that function, we use the syntax \lstinline!c.isSmallerThan(1000)!.
-Similarly, we must consider \lstinline!isEmpty! as a function of
-one argument (\lstinline!this!), even though it is declared without
-any arguments in the interface code.
+\lstinline!size: Int!. We use that function with the syntax \lstinline!c.isSmallerThan(1000)!
+to pass the arguments $c$ and $1000$. Similarly, we must consider
+\lstinline!isEmpty! as a function of one argument (\lstinline!this!),
+even though it is declared without any arguments in the interface
+code.
Methods in an OOI may use an automatically defined value denoted by
the keyword \lstinline!this!. In some other object-oriented languages,
-method signatures must have an explicit first argument called \lstinline!self!,
-\lstinline!this!, or similar. When we analyze OOIs as types, we must
-make all argument types explicit, even though the Scala syntax does
-not do that. For convenience, let us therefore assume that each method
-in an OOI definition has an additional \emph{first} argument (corresponding
-to Scala\textsf{'}s \lstinline!this! keyword).
+method signatures must have an explicit first argument, usually called
+\lstinline!self!, \lstinline!this!, or similar. When we analyze
+OOIs as types, we must make all argument types explicit, even though
+the Scala syntax does not do that. For this reason, we will view the
+types of methods in an OOI definition as having an additional first
+argument (corresponding to Scala\textsf{'}s \lstinline!this! keyword).
We have expressed the type of an interface as a tuple of some function
-types. The first argument of each function is the type of a class
+types. The first argument of each function has the type of a class
that will later implement that interface. That type is unknown within
the scope of an interface definition, and so we have to denote that
type by a type parameter $T$. Then all functions in an interface
will have types of the form $T\times(...)\rightarrow(...)$, with
a first argument of type $T$. Using curried function types equivalent
-to those type signatures, we can make $T$ a curried first argument
-and we obtain a description of an OOI type as a tuple of types of
-the form $T\rightarrow U_{1}$, $T\rightarrow U_{2}$, ..., $T\rightarrow U_{n}$,
-where $U_{1}$, ..., $U_{n}$ are some type expressions that might
-also use $T$. Note that the $U_{i}$ correspond to the type expressions
-as seen in the Scala interface definition, where the first argument
-of type $T$ is not written out.
+to those type signatures, we can make $T$ a \emph{curried} first
+argument. Then we obtain a description of an OOI type as a tuple of
+types of the form $T\rightarrow U_{1}$, $T\rightarrow U_{2}$, ...,
+$T\rightarrow U_{n}$, where $U_{1}$, ..., $U_{n}$ are some type
+expressions that might also depend on $T$. Note that the $U_{i}$
+exactly correspond to the type expressions specified in the Scala
+interface definition, where the first argument of type $T$ is not
+written out.
Using a standard type equivalence such as:
\[
(T\rightarrow U_{1})\times(T\rightarrow U_{2})\cong T\rightarrow U_{1}\times U_{2}\quad,
\]
-and similarly for other $U_{i}$, we can simplify the type of an OOI
-to a single function:
+we can simplify the type of an OOI to a single function:
\[
(T\rightarrow U_{1})\times...\times(T\rightarrow U_{n})\cong T\rightarrow U_{1}\times...\times U_{n}=T\rightarrow U^{T}\quad,
\]
@@ -5953,8 +5954,8 @@ \subsection{Typeclasses, object-oriented interfaces, and algebraic data types}
The types $\bbnum 2$ and $\text{Int}\rightarrow\bbnum 2$ exactly
correspond to the type signatures of the methods \lstinline!isEmpty!
-and \lstinline!isSmallerThan! in the interface definition, where
-the first argument (of type $T$) is not written.
+and \lstinline!isSmallerThan! in the Scala interface definition,
+where the first argument (of type $T$) is not written.
Now we can see the similarity between OOIs and typeclasses. If a type
$T$ belongs to a typeclass with method signature $\text{Sig}$ then
@@ -5966,8 +5967,8 @@ \subsection{Typeclasses, object-oriented interfaces, and algebraic data types}
of type $T\rightarrow U^{T}$. In this way, we find that an OOI is
similar to a special case of a typeclass whose method signature has
the form $\text{Sig}^{T}=T\rightarrow U^{T}$. In such a typeclass,
-all methods are \textsf{``}extension methods\textsf{''} whose first argument has type
-$T$.
+all methods are \textsf{``}extension methods\textsf{''} since their first arguments
+have type $T$.
Not all typeclasses have signatures of that form. As we have just
seen, the \lstinline!Monoid! typeclass has this signature:
@@ -6042,61 +6043,62 @@ \subsection{Typeclasses, object-oriented interfaces, and algebraic data types}
We have achieved a description that presents ADTs as a special case
of typeclasses whose method signature has the form $\text{Sig}^{T}=P^{T}\rightarrow T$.
-(This book calls them \textsf{``}$P$-typeclasses\textsf{''}.)
+(This book calls them \textsf{``}FM-typeclasses\textsf{''} for reasons explained in
+Chapter~\ref{chap:Free-type-constructions}.)
Not all typeclasses have signatures of this form. For example, the
equality typeclass (\lstinline!Eq!) has the method signature $\text{Sig}_{\text{Eq}}^{T}=T\times T\rightarrow\bbnum 2$,
which is not equivalent to $P^{T}\rightarrow T$ with any definition
-of $T$.
+of $P$.
-\paragraph{Summary}
+\paragraph{Inheritance}
-Object-oriented interfaces and algebraic data types are particular
-cases of typeclasses, if we consider only the type signatures of the
-required methods.
-
-At that level of abstraction, we can also show that the inheritance
-of typeclasses corresponds to the object-oriented inheritance of interfaces.
-Let us describe inheritance in the language of method signatures.
+We have been reasoning about typeclasses and OOIs purely in terms
+of type signatures. At that level of abstraction, the inheritance
+of typeclasses corresponds to the object-oriented inheritance of interfaces,
+as we will now show.
A typeclass with signature $\text{Sig}_{1}$ inherits from a typeclass
with signature $\text{Sig}_{2}$ if $\text{Sig}_{1}^{T}=\text{Sig}_{2}^{T}\times Q^{T}$
-for some $Q$. (The type constructor $Q$ describes the additional
+for some $Q$. (The type constructor $Q$ describes all the additional
methods that the new typeclass has.) So, typeclass inheritance corresponds
to taking products of method signatures.
Object-oriented inheritance of interfaces turns out to be exactly
-of the same nature. To see that, consider a first OOI with method
-signature $T\rightarrow U^{T}$ that inherits from a second OOI with
-method signature $T\rightarrow V^{T}$. The first OOI may not change
-any type signatures that it inherited; it may only add new methods.
-Recall that the interface declarations $U^{T}$ and $V^{T}$ involve
-type signatures without the hidden first argument. If we denote by
-$W^{T}$ the type signatures added by the first OOI then it follows
-that $U^{T}=V^{T}\times W^{T}$. So, we find:
+similar. To see that, consider a first OOI with method signature $T\rightarrow U^{T}$
+that inherits from a second OOI with method signature $T\rightarrow V^{T}$.
+The first OOI may not change any type signatures that it inherits;
+it may only add new methods. Recall that the interface declarations
+$U^{T}$ and $V^{T}$ involve type signatures without the hidden first
+argument. If we denote by $W^{T}$ the type signatures added by the
+first OOI then it follows that $U^{T}=V^{T}\times W^{T}$. So, we
+find:
\[
T\rightarrow U^{T}=T\rightarrow V^{T}\times W^{T}\cong(T\rightarrow V^{T})\times(T\rightarrow W^{T})\quad.
\]
-We see that inheritance of OOIs involves products of method signatures,
-just as inheritance of typeclasses does.
+We see that inheritance of OOIs also involves products of method signatures.
-A similar situation exists when ADTs are extended by new constructors.
-Given an ADT with method signature $P^{T}\rightarrow T$, we may add
-new constructors with combined type signatures $Q^{T}\rightarrow T$.
-The result is the ADT with method signature $P^{T}+Q^{T}\rightarrow T$,
-because adding new constructors corresponds to adding another part
-of a disjunctive type. Then we use a standard type equivalence:
+Let us now turn to ADTs. Given an ADT with method signature $P^{T}\rightarrow T$,
+we may add new constructors with combined type signatures $Q^{T}\rightarrow T$.
+The result is an ADT with method signature $P^{T}+Q^{T}\rightarrow T$,
+because adding new constructors corresponds to adding more parts to
+a disjunctive type. Then we use a standard type equivalence:
\[
P^{T}+Q^{T}\rightarrow T\cong(P^{T}\rightarrow T)\times(Q^{T}\rightarrow T)\quad.
\]
So, the ADTs expressed as typeclasses with signatures $P^{T}\rightarrow T$
have the same inheritance mechanism, based on products of method signatures.
-Keep in mind that this description is only at the level of method
-types. There are other important differences in how the Scala compiler
-works with typeclasses, OOIs, and ADTs:
+\paragraph{Summary}
+
+Object-oriented interfaces and algebraic data types are particular
+cases of typeclasses, if we consider only the type signatures of the
+required methods.
+
+If we look beyond just method types, there are important differences
+in how the Scala compiler works with typeclasses, OOIs, and ADTs:
\begin{itemize}
-\item For OOIs, the compiler provides automatic subtyping for interfaces,
+\item For OOIs, the compiler provides automatic subtyping for interfaces
via the object-oriented inheritance mechanism. If a class (or an interface)
$A$ inherits an interface $B$ then the compiler will automatically
consider $A$ as a subtype of $B$. Subtyping and inheritance are
@@ -6105,48 +6107,62 @@ \subsection{Typeclasses, object-oriented interfaces, and algebraic data types}
$C$ and to be a subtype of $C$. The compiler will construct an inheritance
tree automatically, extending the tree each time a new interface or
class is defined. However, one cannot add or remove inherited interfaces
-once a class definition is given. For example, if it is declared that
-$A$ inherits from $B$ and $C$ (this needs to be declared together
-with the definition of $A$) then the programmer cannot declare in
-another scope that $A$ should inherit additionally from some other
-interface, or that $A$ should no longer inherit from $B$. Typeclasses
-are more flexible in this respect: additional evidence values for
-typeclass membership can be defined in any scope, not necessarily
-together with the declaration of a type. Typeclasses may be implemented
+later in the code. For example, $A$ inherits from $B$ (this must
+be declared together with the definition of $A$) then the programmer
+cannot declare in another scope that $A$ should inherit additionally
+from some other interface $C$; or that $A$ should no longer inherit
+from $B$. Typeclasses are more flexible in this respect: additional
+evidence values for typeclass membership can be defined in any scope,
+not necessarily at the declaration site. Typeclasses may be implemented
via OOIs, which will enable features of inheritance and subtyping.
This will make typeclass inheritance behave like object-oriented interface
-inheritance, with all its benefits and shortcomings. As we have seen,
+inheritance with all its benefits and shortcomings. As we have seen,
typeclasses and their inheritance may be also implemented without
-using object-oriented interfaces or inheritance.
-\item For typeclasses, the compiler provides rich features for automatic
-computation of typeclass evidence values via the mechanism of implicit
-values and implicit functions. These features enable automatic typeclass
-derivation, which works independently of and in parallel with typeclass
-inheritance. The programmer can tell the compiler how to compute (via
-custom code) a typeclass evidence value for, say, any pair type \lstinline!(A, B)!
-from evidence values for \lstinline!A! and \lstinline!B!. The compiler
-will use that custom code to determine automatically whether any given
-pair type \lstinline!(A, B)! belongs to the typeclass. Similarly,
-a typeclass derivation rule for \lstinline!Either[A, B]! could be
-specified. The compiler will compute and use the new typeclass evidence
-values automatically for \emph{all} suitable types \lstinline!A!,
-\lstinline!B!. Certain advanced features of Scala (beyond the scope
-of this book) allow programmers to extend typeclass derivation from
-pairs \lstinline!(A, B)! to all case classes, and from the disjunctive
-type \lstinline!Either[A, B]! to all disjunctive types. In this way,
-typeclass membership can be provided automatically by the compiler
-for a wide range of types, which reduces boilerplate code. But there
-are no comparable facilities for object-oriented \textsf{``}interface derivation\textsf{''}.
-\item The compiler\textsf{'}s treatment of ADTs in Scala (and in other functional
-languages) is significantly different from the treatment of typeclasses
-and interfaces. An ADT is not an arbitrary type $T$ that happens
-to support functions of type $P^{T}\rightarrow T$. Instead, the Scala
-compiler interprets an ADT as the \emph{smallest unique} type generated
-by the given constructors while using no other information or constraints.
-In mathematical terminology, the type $T$ is the least fixpoint\index{least fixpoint}
-of the pattern functor $P$. Rigorous definitions and the necessary
-theory will be developed in Chapter~\ref{chap:Free-type-constructions}.
+OOIs.
+\item For typeclasses, the Scala compiler provides a rich mechanism known
+as \textsf{``}typeclass derivation\textsf{''}: an automatic computation of typeclass
+evidence values, which works independently of typeclass inheritance.
+The programmer can tell the compiler how to compute (via custom code)
+a typeclass evidence value for, say, any pair type \lstinline!(A, B)!
+from evidence values for \lstinline!A! and \lstinline!B!. Similarly,
+a custom derivation rule for \lstinline!Either[A, B]! may be specified.
+The compiler will use that custom code to determine automatically
+whether \lstinline!(A, B)! or \lstinline!Either[A, B]! belongs to
+the typeclass, for \emph{all} suitable types \lstinline!A!, \lstinline!B!.
+Certain advanced features of Scala (beyond the scope of this book)
+allow programmers to extend typeclass derivation from pairs \lstinline!(A, B)!
+to all case classes, and from \lstinline!Either[A, B]! to all disjunctive
+types. In this way, typeclass membership can be provided automatically
+by the compiler (with no boilerplate code) for a wide range of user-defined
+types. But there are no comparable facilities for object-oriented
+\textsf{``}interface derivation\textsf{''}.
+\item The compilers of Scala and other functional languages treat ADTs and
+typeclasses in rather different ways. An ADT is not just an arbitrary
+type $T$ that happens to support functions of type $P^{T}\rightarrow T$.
+In fact, the Scala compiler interprets an ADT as the \emph{smallest
+unique} type generated by the given constructors while using no other
+information or constraints. In mathematical terminology, the type
+$T$ is the least fixpoint\index{least fixpoint} of the pattern functor
+$P$. Rigorous definitions and the necessary theory will be developed
+in Chapter~\ref{chap:Free-type-constructions}.
\end{itemize}
+How to decide whether to use typeclasses, ADTs, or OOIs in practice?
+One approach is to look at the type signatures of functions that one
+needs to use in a given problem domain. If one most often needs to
+construct new domain values, most type signatures will be of the form
+\lstinline!Something => T!, where \lstinline!T! is the type of a
+domain entity. This is of the general form $P^{T}\rightarrow T$ and
+is modeled well by ADTs. If one most often needs to work with existing
+domain entities, type signatures will be of the form \lstinline!T => Something!.
+This is of the general form $T\rightarrow P^{T}$ and is modeled well
+by OOIs.
+
+So, the decision of whether to use ADTs or OOIs depends on the prevalence
+of method signatures of the form $P^{T}\rightarrow T$ or $T\rightarrow P^{T}$
+in the problem domain. Typeclasses support method signatures of either
+form and can be used to implement both ADTs and OOIs, overcoming their
+limitations.
+
\begin{comment}
this tutorial is about typeclasses and type level functions to motivate
why we want to talk about this let\textsf{'}s consider what happens if we would
diff --git a/sofp-src/tex/sofp.tex b/sofp-src/tex/sofp.tex
index 8fcf1eabb..e8c319dc8 100644
--- a/sofp-src/tex/sofp.tex
+++ b/sofp-src/tex/sofp.tex
@@ -329,17 +329,17 @@
\subtitle{A tutorial, with examples in Scala}
\author{by Sergei Winitzki, Ph.D.}
\date{Version of \today}
-\publishers{Published by\textbf{ \href{http://lulu.com}{lulu.com}} in 2024}
-\uppertitleback{{\footnotesize{}Copyright \copyright\ 2018-2024 by Sergei Winitzki}\\
+\publishers{Published by\textbf{ \href{http://lulu.com}{lulu.com}} in 2025}
+\uppertitleback{{\footnotesize{}Copyright \copyright\ 2018-2025 by Sergei Winitzki}\\
{\footnotesize{}~}\\
{\footnotesize{}\href{https://www.lulu.com/en/us/shop/sergei-winitzki/the-science-of-functional-programming-draft-version/paperback/product-1y5zzgje.html}{Print on demand at lulu.com}}\\
{\footnotesize{}~}\\
{\footnotesize{}ISBN (e-book): 978-0-359-76877-6}\\
{\footnotesize{}ISBN: 978-0-359-76877-6}\\
\\
-{\scriptsize{}Source hash (sha256): 78c1bdf371a4a5b26757fc2cbb040109745983d0a5cda174e052a4282b0e33c4}\\
-{\scriptsize{}Git commit: cf9c1ff8f5f6658e5d878b872c200ce75b0655fa}\\
-{\scriptsize{}PDF file built on Fri, 19 Sep 2025 18:48:58 +0200 by pdfTeX 3.141592653-2.6-1.40.22 (TeX Live 2021) on Darwin}\\
+{\scriptsize{}Source hash (sha256): 074268751cedd672514d12d5d68008085291fe321ffd10453d933dc8ede7c0df}\\
+{\scriptsize{}Git commit: 82fa9245aeb24d3691be02c59e3f0fd0ac1f8bd7}\\
+{\scriptsize{}PDF file built on Wed, 11 Mar 2026 20:19:05 +0100 by pdfTeX 3.141592653-2.6-1.40.22 (TeX Live 2021) on Darwin}\\
~\\
{\scriptsize{}Permission is granted to copy, distribute and/or modify
this document under the terms of the GNU Free Documentation License,
@@ -374,10 +374,10 @@
practical applications of parametricity.}\\
{\scriptsize{}}\\
{\scriptsize{}Long and difficult, yet boring explanations are logically
-developed in excruciating detail through 1982 Scala
+developed in excruciating detail through 1995 Scala
code snippets, 233 statements with step-by-step derivations,
-105 diagrams, 237 examples with tested Scala
-code, and 315 exercises. Discussions build upon each
+105 diagrams, 239 examples with tested Scala
+code, and 317 exercises. Discussions build upon each
chapter's material further.}\\
{\scriptsize{}}\\
{\scriptsize{}Beginners in FP will find tutorials about the map/reduce