Skip to content

Commit b061a8c

Browse files
author
Zara
authored
corrections from Cats translation (#49)
* improve wording of Comonad section * uncompilable typo * rebuild the book
1 parent aadda79 commit b061a8c

File tree

2 files changed

+46
-38
lines changed

2 files changed

+46
-38
lines changed

manuscript/book.org

+23-19
Original file line numberDiff line numberDiff line change
@@ -5570,10 +5570,9 @@ digraph G {
55705570
}
55715571
#+END_SRC
55725572

5573-
~cobind~ (also known as ~coflatmap~) takes an ~F[A] => B~ that acts on
5574-
an ~F[A]~ rather than its elements. But this is not necessarily the
5575-
full ~fa~, it is usually some substructure as defined by ~cojoin~
5576-
(also known as ~coflatten~) which expands a data structure.
5573+
~cobind~ (also known as ~coflatmap~) takes an ~F[A] => B~ that acts on an ~F[A]~
5574+
rather than its elements. But this is not necessarily the full ~fa~, it can be a
5575+
substructure that has been created by ~.coflatten~.
55775576

55785577
Compelling use-cases for =Cobind= are rare, although when shown in the
55795578
=Functor= permutation table (for =F[_]=, =A= and =B=) it is difficult
@@ -5597,15 +5596,21 @@ to argue why any method should be less important than the others:
55975596
}
55985597
#+END_SRC
55995598

5600-
=.copoint= (also =.copure=) unwraps an element from its context. Effects do not
5601-
typically have an instance of =Comonad= since would break referential
5602-
transparency to interpret an =IO[A]= into an =A=. But for collection-like /data
5603-
structures/, it is a way to construct a view of all elements alongside their
5604-
neighbours.
5599+
=.copoint= (also =.copure=) unwraps an element from its context. The =Id= type
5600+
alias that we encountered in Chapter 1 has an instance of =Comonad=, so we can
5601+
reach into an =Id= and extract the value it contains. Similarly, =Name= has a
5602+
=Comonad= with =.value= effectively being the =Value= strategy.
56055603

5606-
Consider a /neighbourhood/ (=Hood= for short) for a list containing all the
5607-
elements to the left of an element (=lefts=), the element itself (the =focus=),
5608-
and all the elements to its right (=rights=).
5604+
Another example of a =Comonad= is the =NonEmptyList=, where =.copoint= returns
5605+
the =.head= element and =.cobind= operates on all the tails of the list.
5606+
5607+
Effects do not typically have an instance of =Comonad= since it would break
5608+
referential transparency to interpret an =IO[A]= into an =A=.
5609+
5610+
=Comonad= allows navigation over elements of a data structure and eventually
5611+
returning to one view of that data. Consider a /neighbourhood/ (=Hood= for
5612+
short) of a list, containing all the elements to the left (=.lefts=) of an
5613+
element =.focus=, and all the elements to its right (=.rights=).
56095614

56105615
#+BEGIN_SRC scala
56115616
final case class Hood[A](lefts: IList[A], focus: A, rights: IList[A])
@@ -5622,7 +5627,7 @@ object Hood {
56225627
#+END_SRC
56235628

56245629
We can write methods that let us move the focus one to the left
5625-
(=previous=) and one to the right (=next=)
5630+
(=.previous=) and one to the right (=.next=)
56265631

56275632
#+BEGIN_SRC scala
56285633
...
@@ -5638,9 +5643,8 @@ We can write methods that let us move the focus one to the left
56385643
}
56395644
#+END_SRC
56405645

5641-
By introducing =more= to repeatedly apply an optional function to
5642-
=Hood= we can calculate /all/ the =positions= that =Hood= can take in
5643-
the list
5646+
=.more= repeatedly applies an optional function to =Hood= such that we calculate
5647+
/all/ the views that =Hood= can take on the list
56445648

56455649
#+BEGIN_SRC scala
56465650
...
@@ -5671,7 +5675,7 @@ We can now implement =Comonad[Hood]=
56715675
}
56725676
#+END_SRC
56735677

5674-
=cojoin= gives us a =Hood[Hood[IList]]= containing all the possible
5678+
=.cojoin= gives us a =Hood[Hood[IList]]= containing all the possible
56755679
neighbourhoods in our initial =IList=
56765680

56775681
#+BEGIN_SRC scala
@@ -5689,7 +5693,7 @@ res = Hood(
56895693
Hood([8,7,6,5,4,3,2,1],9,[])])
56905694
#+END_SRC
56915695

5692-
Indeed, =cojoin= is just =positions=! We can =override= it with a more
5696+
Indeed, =.cojoin= is just =positions=! We can =override= it with a more
56935697
direct (and performant) implementation
56945698

56955699
#+BEGIN_SRC scala
@@ -13732,7 +13736,7 @@ object JsMagnoliaEncoder {
1373213736

1373313737
def combine[A](ctx: CaseClass[JsEncoder, A]): JsEncoder[A] = { a =>
1373413738
val empty = IList.empty[(String, JsValue)]
13735-
val fields = ctx.parameters.foldRight(right) { (p, acc) =>
13739+
val fields = ctx.parameters.foldRight(empty) { (p, acc) =>
1373613740
p.typeclass.toJson(p.dereference(a)) match {
1373713741
case JsNull => acc
1373813742
case value => (p.label -> value) :: acc

manuscript/complete.md

+23-19
Original file line numberDiff line numberDiff line change
@@ -4634,10 +4634,9 @@ signature of *thing* wherever we can.
46344634
}
46354635
~~~~~~~~
46364636

4637-
`cobind` (also known as `coflatmap`) takes an `F[A] => B` that acts on
4638-
an `F[A]` rather than its elements. But this is not necessarily the
4639-
full `fa`, it is usually some substructure as defined by `cojoin`
4640-
(also known as `coflatten`) which expands a data structure.
4637+
`cobind` (also known as `coflatmap`) takes an `F[A] => B` that acts on an `F[A]`
4638+
rather than its elements. But this is not necessarily the full `fa`, it can be a
4639+
substructure that has been created by `.coflatten`.
46414640

46424641
Compelling use-cases for `Cobind` are rare, although when shown in the
46434642
`Functor` permutation table (for `F[_]`, `A` and `B`) it is difficult
@@ -4663,15 +4662,21 @@ to argue why any method should be less important than the others:
46634662
}
46644663
~~~~~~~~
46654664

4666-
`.copoint` (also `.copure`) unwraps an element from its context. Effects do not
4667-
typically have an instance of `Comonad` since would break referential
4668-
transparency to interpret an `IO[A]` into an `A`. But for collection-like *data
4669-
structures*, it is a way to construct a view of all elements alongside their
4670-
neighbours.
4665+
`.copoint` (also `.copure`) unwraps an element from its context. The `Id` type
4666+
alias that we encountered in Chapter 1 has an instance of `Comonad`, so we can
4667+
reach into an `Id` and extract the value it contains. Similarly, `Name` has a
4668+
`Comonad` with `.value` effectively being the `Value` strategy.
46714669

4672-
Consider a *neighbourhood* (`Hood` for short) for a list containing all the
4673-
elements to the left of an element (`lefts`), the element itself (the `focus`),
4674-
and all the elements to its right (`rights`).
4670+
Another example of a `Comonad` is the `NonEmptyList`, where `.copoint` returns
4671+
the `.head` element and `.cobind` operates on all the tails of the list.
4672+
4673+
Effects do not typically have an instance of `Comonad` since it would break
4674+
referential transparency to interpret an `IO[A]` into an `A`.
4675+
4676+
`Comonad` allows navigation over elements of a data structure and eventually
4677+
returning to one view of that data. Consider a *neighbourhood* (`Hood` for
4678+
short) of a list, containing all the elements to the left (`.lefts`) of an
4679+
element `.focus`, and all the elements to its right (`.rights`).
46754680

46764681
{lang="text"}
46774682
~~~~~~~~
@@ -4690,7 +4695,7 @@ via `.toIList`
46904695
~~~~~~~~
46914696

46924697
We can write methods that let us move the focus one to the left
4693-
(`previous`) and one to the right (`next`)
4698+
(`.previous`) and one to the right (`.next`)
46944699

46954700
{lang="text"}
46964701
~~~~~~~~
@@ -4707,9 +4712,8 @@ We can write methods that let us move the focus one to the left
47074712
}
47084713
~~~~~~~~
47094714

4710-
By introducing `more` to repeatedly apply an optional function to
4711-
`Hood` we can calculate *all* the `positions` that `Hood` can take in
4712-
the list
4715+
`.more` repeatedly applies an optional function to `Hood` such that we calculate
4716+
*all* the views that `Hood` can take on the list
47134717

47144718
{lang="text"}
47154719
~~~~~~~~
@@ -4742,7 +4746,7 @@ We can now implement `Comonad[Hood]`
47424746
}
47434747
~~~~~~~~
47444748

4745-
`cojoin` gives us a `Hood[Hood[IList]]` containing all the possible
4749+
`.cojoin` gives us a `Hood[Hood[IList]]` containing all the possible
47464750
neighbourhoods in our initial `IList`
47474751

47484752
{lang="text"}
@@ -4761,7 +4765,7 @@ neighbourhoods in our initial `IList`
47614765
Hood([8,7,6,5,4,3,2,1],9,[])])
47624766
~~~~~~~~
47634767

4764-
Indeed, `cojoin` is just `positions`! We can `override` it with a more
4768+
Indeed, `.cojoin` is just `positions`! We can `override` it with a more
47654769
direct (and performant) implementation
47664770

47674771
{lang="text"}
@@ -12142,7 +12146,7 @@ Start with a `JsEncoder` that handles only our sensible defaults:
1214212146
1214312147
def combine[A](ctx: CaseClass[JsEncoder, A]): JsEncoder[A] = { a =>
1214412148
val empty = IList.empty[(String, JsValue)]
12145-
val fields = ctx.parameters.foldRight(right) { (p, acc) =>
12149+
val fields = ctx.parameters.foldRight(empty) { (p, acc) =>
1214612150
p.typeclass.toJson(p.dereference(a)) match {
1214712151
case JsNull => acc
1214812152
case value => (p.label -> value) :: acc

0 commit comments

Comments
 (0)