Pagini
Workshops
Parteneri
Monads, baby!
Today we look at certain kinds of computations from a truly functional perspective:
But we won't get into math and category theory for this.
We'll see what a monad is from a programming perspective, directly in the Scala language.
You can find today's contents here.
Let's implement some of our own monads.
Option
. Let's call this Maybe
, as in Haskell.Maybe[+A]
(remember the [A]
is equivalent to Java's <A>
syntax for generics and ignore the + for now)Maybe
:map
, flatMap
, filter
zipWith
, which receives a Maybe[B]
and returns a Maybe[(A,B)]
def zipWith[B](other: Maybe[B]): Maybe[(A,B)]
If either this
or other
is empty, the result will be an empty Maybe
.
exists
, which receives a predicate (a function of A to Boolean) and returns true if this instance contains an element which satisfies the predicateorElse
, a special method for Maybe
, which returns this instance if it's not empty, or an alternative otherwise; the signature will bedef orElse[B >: A](alternative: Maybe[B]): Maybe[B]
(ignore the >:
for now)
How can you delay the computation of the alternative until you actually need it? (hint: call by value/call by name)
Maybe
trait:isEmpty
toList
size
Just[A]
and Empty
and implement the methodsEmpty
, actually? a case class? a case object?Try
monad, call this Attempt[A]
.Attempt[A]
and two case subclasses, Success[A]
and Fail
Success
has a member of type A
, Fail has a member of type Throwable
Attempt
and implement them in the subclasses:map
, flatMap
, filter
zipWith
exists
isEmpty
, toList
, size
recoverWith
; the method returns an alternative Attempt
computation if this one fails