MostlyAdequate / mostly-adequate-guide

Mostly adequate guide to FP (in javascript)
Other
23.3k stars 1.86k forks source link

ch12: The result of `comp1` is not proper #638

Open dzylikecode opened 1 year ago

dzylikecode commented 1 year ago

original content

const comp1 = compose(sequence(Compose.of), map(Compose.of));
const comp2 = (Fof, Gof) => compose(Compose.of, map(sequence(Gof)), sequence(Fof));

// Test it out with some types we have lying around
comp1(Identity(Right([true])));
// Compose(Right([Identity(true)]))

comp2(Either.of, Array)(Identity(Right([true])));
// Compose(Right([Identity(true)]))

issue

I disagree with the result of comp1(Identity(Right([true]))) will be Compose(Right([Identity(true)])). As it's mentioned in the Identity law:

const identity1 = compose(sequence(Identity.of), map(Identity.of));
const identity2 = Identity.of;

// test it out with Right
identity1(Either.of('stuff'));
// Identity(Right('stuff'))

identity2(Either.of('stuff'));
// Identity(Right('stuff'))

identity1 is equivalent to identity2. And I think comp1 is isomorphic to identity1, which means comp1 is equivalent to Compose.of. So the result of comp1(Identity(Right([true]))) should be Compose(Identity(Right([true]))).

maybe a solution

I'm not sure whether sequence will exchange the containers that are not adjacent, like this:

sequence(A.of, C(B(A(x))));
// A(B(C(x)))

If the law is right, I think the proper comp1 should equal compose(sequence(Compose.of), map(map(map(Compose.of))))