This is an old revision of the document!

Today we look at certain kinds of computations from a truly functional perspective:

• computations that might or might not have a value
• computations that might fail
• computations that will finish at some point

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.

## Practice

Let's implement some of our own monads.

1. Let's write a monad equivalent with Option. Let's call this Maybe, as in Haskell.
• create a trait Maybe[A] (remember the [A] is equivalent to Java's <A> syntax for generics)
• add some functional primitives as methods to Maybe:
• the monad requirements: map, flatMap, filter
• zipWith, which receives a Maybe[B] and returns a Maybe[(A,B)]
The signature is just a tiny bit more complex:
def zipWith[B](other: Maybe[B]): Maybe[(A,B)]

If either this or other is empty, the result will be an empty Option.

• exists, which receives a predicate (a function of T to Boolean) and returns true if this instance contains an element which satisfies the predicate
• orElse, a special method for Maybe, which returns this instance if it's not empty, or an alternative otherwise; the signature will be
def orElse(alternative: Maybe[B]): Option[B]

How can you delay the computation of the alternative until you actually need it? (hint: call by value/call by name)

• add some utility methods to the Maybe trait:
• isEmpty
• toList
• size
• create two case subclasses: Just[A] and None and implement the methods
• what is None, actually? a case class? a case object?
• methods should be quick to write and probably take two lines of code, at most
2. An equivalent to Scala's Try monad, call this Attempt[A].
• as before, create a trait Attempt[A] and two case subclasses, Success[A] and Fail
• Success has a member of type A, Fail has a member of type Throwable
• add some functional primitives to your Attempt and implement them in the subclasses:
• map, flatMap, filter
• zipWith
• exists
• isEmpty, toList, size
• a special method - recoverWith; the method returns an alternative Attempt computation if this one fails
3. Talk about the Future[T] (pun intended) if you finish early!