This is an old revision of the document!


6 - Monads

Monads, baby!
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[T] (remember the [T] is equivalent to Java's <T> syntax for generics)
    • add some functional primitives as methods to Maybe:
      • the monad requirements: map, flatMap, filter
      • zipWith, which receives a Maybe[A] and returns a Maybe[(T,A)]
        The signature is just a tiny bit more complex:
        def zipWith[A](other: Maybe[A]): Maybe[(T,A)]

        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: Option[A]): Option[A]

        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[T] 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[T].
    • as before, create a trait Attempt[T] and two case subclasses, Success[T] and Fail
    • Success has a member of type T, 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
sesiuni/scala/lab6.1467638587.txt.gz · Last modified: 2016/07/04 16:23 by dciocirlan