**Pagini **

# Workshops

**Parteneri**

**This is an old revision of the document!**

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.

Let's implement some of our own monads.

- 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

- 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