Is there any good document out there explaining wh...
# arrow
k
Is there any good document out there explaining why using something like
Kind<F, A>
is so helpful compared to
F<A>
(i.e. and e.g., not hard-coding that your return type is
Option<A>
)? I’m hoping there’s some blog out there showing a real-world reason someone chose to do this and how it benefited them. Is this just so you don’t have to refactor your function’s signatures from an
Either<Throwable, A>
into an
Option<A>
if you change your mind halfway through development, or is there something greater out there? It seems like tutorials are implying a connection to something like an
interface
in OOP (being able to write to a more generic “contract”), but I haven’t been working with FP long enough to grok the real-world benefits. Thanks.
b
The biggest benefit I have observed is compositionality
If you have
fun a(...): Option<A>
and
fun b(Try<A> a): IO<B>
then explicit composition logic is required
If you instead have
fun a(...): Kind<F, A>
and
fun b(Kind<F, A>): Kind<F, B>
then the composition can be accomplished automatically based on the supplied instance that satisfies all constraints on
F
(typically
IO
)
e.g. if
a
requires
Monad
and
b
requires
MonadDefer
then
b(a(...))
can use any instance of
MonadDefer
(since
MonadDefer
extends
Monad
)
🔝 3
a
also, it's a great usecase for libs, where they don't have to impose a specific "runner" such as IO, for example, but just leave it open to
Async
or
Concurrent
for the dev to choose which implementation to use
j
Typeclasses sometimes abstract over the content type: Try writing functor:
interface Functor<A> { fun <B> A.map(f: (??) -> B): ?? }
Not sure you can do that. Some other typeclasses need even more complex types, like Semialign