Open tiagojdf opened 4 years ago
I got stuck there too. same reason but I think comp1's result is Compose(Identity(Right([true]))) not Compose(Identity([Right(true)])) as you mentioned.
const comp1 = compose(map(map(sequence(Compose.of))), map(sequence(Compose.of)), Compose.of);
const comp2 = (Fof, Gof) => compose(Compose.of, map(sequence(Gof)), sequence(Fof));
would be more rational I think.
This was confusing for me as well. I understand what it's doing step-by-step, but I don't get what this law is trying to say.
Given an initial nested functor, Identity (Maybe ([123]))
,
this functor has three layers:
In comp1, we create a Compose functor using the inner value of Identity:
resulting into Identity (Compose (Maybe ([123])))
.
Then we swap the Identity and Compose functors.
However, since this is a Compose functor, I assume that
the order of functors inside the Compose functor need to be preserved,
therefore, instead of naively swapping Compose with Identity, such as
Compose (Identity (Maybe ([123])))
,
we move Compose to the place of Identity,
then move Identity to the "last" place of the Composed functors,
Compose (Maybe ([Identity (123)]))
.
So now compose has an additional functor from two to three:
In comp2, we swap the outer layer of the given functor, resulting into
Maybe (Identity [123])
.
Then we swap the inner value of Maybe, resulting into
Maybe ([Identity 123])
.
Then we just wrap Compose directly,
Compose (Maybe ([Identity 123]))
#+begin_src js :noweb no-export :results code
<<js curry>>
<<js compose>>
<<js map>>
<<js sequence>>
<<js compose applicative>>
<<js identity traversable>>
<<js maybe traversable>>
<<js list traversable>>
// Compose.of :: x -> Compose F G x
const iofm = Identity.of(Maybe.of([123])) // Identity (Maybe [123])
const x = Compose.of(iofm) // Compose (Identity (Maybe ([123])))
// const comp1 =
// compose(sequence(Compose.of), map(Compose.of))
const y = map(Compose.of)(iofm) // Identity (Compose (Maybe ([123])))
const z = sequence(Compose.of)(y) // Compose (Maybe ([Identity (123)]))
// const comp2 = (Fof, Gof) =>
// compose(Compose.of, map(sequence(Gof)), sequence(Fof))
const a = sequence(Identity.of)(iofm) // Maybe (Identity [123])
const b = map(sequence(Maybe.of))(a) // Maybe ([Identity 123])
const c = Compose.of(b) // Compose (Maybe ([Identity 123]))
return {
x,
y,
z,
a,
b,
c
}
#+end_src
#+RESULTS:
#+begin_src js
{
x: Compose { val: Identity { val: [Maybe] } },
y: Identity { val: Compose { val: [Maybe] } },
z: Compose { val: Maybe { val: [Array] } },
a: Maybe { val: Identity { val: [Array] } },
b: Maybe { val: [ [Identity] ] },
c: Compose { val: Maybe { val: [Array] } }
}
#+end_src
@sevillaarvin is right, because map
is called on Compose
, which reaches two layers deep into the functor, both results are indeed Compose(Right([Identity(true)]))
. So comp1
is correct.
Because traverse(f) === compose(sequence, map(f))
(this wasn't really made obvious in the book), the composition law is equivalent to saying traverse(compose(Compose.of, map(g), f)) === compose(Compose.of, map(traverse(g)), traverse(f))
. (One traversal of the composition is equivalent to traversing twice individually)
@sevillaarvin @lachrymaLF thanks for helping me out!
I am trying to get my head around the section composition in chapter 12, and I don't understand how comp1 is working:
The way I see it:
Could you help me figure out what I am misunderstanding on this example?