learning Scalaz: day 7

On day 6 we reviewed for syntax and checked out the Writer monad and the reader monad, which is basically using functions as monads.

Applicative Builder

One thing I snuck in while covering the reader monad is the Applicative builder |@|. On day 2 we introduced ^(f1, f2) {...} style that was introduced in 7.0.0-M3, but that does not seem to work for functions or any type constructor with two parameters.

The discussion on the Scalaz mailing list seems to suggest that |@| will be undeprecated, so that's the style we will be using, which looks like this:

Using State[List[Int], Int] {...} we were able to abstract out the "extract state, and return value with a state" portion of the code. The powerful part is the fact that we can monadically chain each operations using for syntax without manually passing around the Stack values as demonstrated in stackManip above.

Getting and setting state

LYAHFGG:

The Control.Monad.State module provides a type class that's called MonadState and it features two pretty useful functions, namely get and put.

The State object extends StateFunctions trait, which defines a few helper functions:

These are confusing at first. But remember State monad encapsulates functions that takes a state and returns a pair of a value and a state. So get in the context of state simply means to retreive the state into the value:

As you can see a monad on its own doesn't do much (encapsulate a function that returns a tuple), but by chaining them we can remove some boilerplates.

Error error on the wall

LYAHFGG:

The Either e a type on the other hand, allows us to incorporate a context of possible failure to our values while also being able to attach values to the failure, so that they can describe what went wrong or provide some other useful info regarding the failure.

\/

We know Either[A, B] from the standard library, but Scalaz 7 implements its own Either equivalent named \/:

It's a bit difficult to see, but the final result is Failure(event 2 failed!event 3 failed!). Unlike \/ monad which cut the calculation short, Validation keeps going and reports back all failures. This probably would be useful for validating user's input on an online bacon shop.

The problem, however, is that the error messages are mushed together into one string. Shouldn't it be something like a list?