Scalaz Apply

Jul 19, 2015

Apply is Functor that also has apply method.
Scalaz defines Apply[F[_]] trait with ap abstract method.

defap[A,B](fa:⇒F[A])(f:⇒F[A⇒B]):F[B]

Having a higher kind A and hight kind of A to B mapping we can get higher
kind B. And since Apply is also a functor we also have

defmap[A, B](fa:F[A])(f:A⇒B):F[B]

We can do interesting things with those two. We can define ap2 for example,
which will take, F[A], F[B], F[(A, B) ⇒ C] and return F[C]

defap2[A,B,C](fa:⇒F[A],fb:⇒F[B])(f:F[(A,B)⇒C]):F[C]=ap(fb)(ap(fa)(map(f)(_.curried)// This will give us F[A ⇒ B ⇒ C])// Here we'll have F[B ⇒ C])// And now we'll get F[C]

And we can extends this to apN to go as many levels deep as we want.
We can also define apply2 which will take F[A], F[B] and (A, B) ⇒ C mapping
and retrun F[C]. Note that unlike ap2, it takes (A, B) ⇒ C instead of
F[(A, B) ⇒ C].

defapply2[A, B, C](fa:⇒F[A],fb:⇒F[B])(f:(A,B)⇒C):F[C]=ap(fb)(map(fa)(f.curried)// This will give as F[B ⇒ C])// And now we'll get F[C]

This one also we can extends to applyN. Since apply2 takes (A, B) ⇒ C
mapping we can just not map it to another type and return (A, B) tuple.

deftuple2[A,B](fa:⇒F[A],fb:⇒F[B]):F[(A,B)]=apply2(fa,fb)((_,_))

And of course we can define tupleN using applyN.
Having apply2 we can define lift2 which will take (A, B) ⇒ C mapping and
lift it to (F[A], F[B]) ⇒ F[C] mapping.

deflift2[A, B, C](f:(A,B)⇒C):(F[A],F[B])⇒F[C]=apply2(_,_)(f)

We can also define liftN based on applyN.

Of course we don’t have to derive all those factions ourself since scalaz is
so awesome it provides those for us. It also defines following syntax functions: