@@ -5570,10 +5570,9 @@ digraph G {
5570
5570
}
5571
5571
#+END_SRC
5572
5572
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~.
5577
5576
5578
5577
Compelling use-cases for =Cobind= are rare, although when shown in the
5579
5578
=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:
5597
5596
}
5598
5597
#+END_SRC
5599
5598
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.
5605
5603
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=).
5609
5614
5610
5615
#+BEGIN_SRC scala
5611
5616
final case class Hood[A](lefts: IList[A], focus: A, rights: IList[A])
@@ -5622,7 +5627,7 @@ object Hood {
5622
5627
#+END_SRC
5623
5628
5624
5629
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=)
5626
5631
5627
5632
#+BEGIN_SRC scala
5628
5633
...
@@ -5638,9 +5643,8 @@ We can write methods that let us move the focus one to the left
5638
5643
}
5639
5644
#+END_SRC
5640
5645
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
5644
5648
5645
5649
#+BEGIN_SRC scala
5646
5650
...
@@ -5671,7 +5675,7 @@ We can now implement =Comonad[Hood]=
5671
5675
}
5672
5676
#+END_SRC
5673
5677
5674
- =cojoin= gives us a =Hood[Hood[IList]]= containing all the possible
5678
+ =. cojoin= gives us a =Hood[Hood[IList]]= containing all the possible
5675
5679
neighbourhoods in our initial =IList=
5676
5680
5677
5681
#+BEGIN_SRC scala
@@ -5689,7 +5693,7 @@ res = Hood(
5689
5693
Hood([8,7,6,5,4,3,2,1],9,[])])
5690
5694
#+END_SRC
5691
5695
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
5693
5697
direct (and performant) implementation
5694
5698
5695
5699
#+BEGIN_SRC scala
@@ -13732,7 +13736,7 @@ object JsMagnoliaEncoder {
13732
13736
13733
13737
def combine[A](ctx: CaseClass[JsEncoder, A]): JsEncoder[A] = { a =>
13734
13738
val empty = IList.empty[(String, JsValue)]
13735
- val fields = ctx.parameters.foldRight(right ) { (p, acc) =>
13739
+ val fields = ctx.parameters.foldRight(empty ) { (p, acc) =>
13736
13740
p.typeclass.toJson(p.dereference(a)) match {
13737
13741
case JsNull => acc
13738
13742
case value => (p.label -> value) :: acc
0 commit comments