Groovy Monad Combinators
In the previous post I discussed how to define monads in Groovy and looked a little at how they differ from functors and applicatives.
The payoff for defining monads is not having the methods unit and flatMap defined for the monad, although this is useful. The key benefit is the many methods derived from these methods that come with the abstraction.
Groovy Monads
In the last two posts, I have discussed how to implement functors and applicatives in Groovy. This post discusses the related topic of monads.
Before we start, let’s review the essence of the differences between these three concepts. The primary method for functors, applicatives and monads are map, apply and flatMap respectively.
Class | Primary Method | Argument | Argument | Result | |
---|---|---|---|---|---|
Monad<T<_>> |
flatMap |
T<A> |
F<A, T<B>> |
T<B> |
|
Functor<T<_>> |
map |
T<A> |
F<A, B> |
T<B> |
|
Applicative<T<_>> |
apply |
T<A> |
T<F<A, B>> |
T<B> |
In the table above, I have used invalid syntax to represent the class to indicate that Functor, Applicative and Monad all take a single generic type argument. The type argument itself takes a single type argument. In Groovy, we make do with a lack of higher order types and represent the class without the <_> component, e.g. Functor<T> [3].
We deduce that the differences between the classes in the table are:
-
Functor: apply a function (F<A, B>) to a contextual value using map.
-
Applicative: apply a contextual function (T<F<A, B>>) to a contextual value using apply.
-
Monad: apply a function that returns a contextual value (F<A, T<B>>) to a contextual value using flatMap.
Groovy Applicatives
My last post discussed creating Functors in Groovy [5]. I demonstrated how to create a list functor. Before we start creating the applicative abstraction, let’s create a functor based on the rich FunctionalJava Option type to review functors and to later demonstrate applicatives.
Groovy Functors
Groovy and Java both provide abstractions that allow programmers to transform values within that abstraction. For example, Groovy provides the collect method on Collections and Java 8 provides the map method on the Stream class. This pattern is more widely applicable than these classes, however the simple Java type system prevents this idea from being expressed within Java.
If Java allowed this idea to be expressed it might be expressed as:
public interface Mappable<M<Z>> {
public M<B> map(M<A> m, F<A, B> f);
}
Converting to JBake
This blog is being converted to JBake to allow easier workflow. As a result, some of the links will not be working, such as Disqus, the RSS feed and others.
Please keep this in mind as the conversion takes place. I am expecting this could take a week (around 2014-06-23).
-
Older posts can be found in
- Archive