More lazy values, the State monad and other stateful stuff

In the previous post, we talked about lazy evaluation in Scala. At the end of that post, we asked an interesting question: Does a Lazy value hold an state?

24195622

In order to answer that question, we’ll try to define a type that could represent the Lazy values:

trait Lazy[T] {

  val evalF : () => T

  val value: Option[T] = None

}
object Lazy{
  def apply[T](f: => T): Lazy[T] =
    new Lazy[T]{ val evalF = () => f }
}

As you can see, our Lazy type is parameterized by some T type that represents the actual value type(Lazy[Int] would be the representation for a lazy integer).
Besides that, we can see that it’s composed of the two main Lazy type features:

  • evalF : Zero-parameter function that, when its ‘apply’ method is invoked, it evaluates the contained T expression.
  • value : The result value of the interpretation of the evalF function. This concrete part denotes the state in the Lazy type, and it only admit two possible values: None (not evaluated) or Some(t) (if it has been already evaluated and the result itself).

We’ve also added a companion object that defines the Lazy instance constructor that receives a by-name parameter that is returned as result of the evalF function.

e9a2295b3db9b45c8f5484a09033c1c71cf88e3375bb7ff60456bc81c29a4e04

Now the question is, how do we join both the evaluation function and the value that it returns so we can make Lazy an stateful type? We define the ‘eval’ function this way:

trait Lazy[T] { lzy =>

  val evalF : () => T

  val value: Option[T] = None

  def eval: (T, Lazy[T]) = {
    val evaluated = evalF.apply()
    evaluated -> new Lazy[T]{ mutated =>
      val evalF = lzy.evalF
      override val value = Some(evaluated)
      override def eval: (T, Lazy[T]) = 
        evaluated -> mutated
    }
  } 

}

The ‘eval’ function returns a two-element tuple:

  • The value result of evaluating the expression that stands for the lazy value.
  • a new Lazy value version that contains the new state: the T evaluation result.

If you take a closer look, what ‘eval’ method does in first place is to invoke the evalF function so it can retrieved the T value that remained until that point not-evaluated.
Once done, we return it as well as the new Lazy value version. This new version (let’s call it mutated version) will have in its ‘value’ attribute the result of having invoked the evalF function. In the same way, we change its eval method, so in future invocations the Lazy instance itself is returned instead of creating new instances (because it actually won’t change its state, like Scala’s lazy definitions work).

The interesting question that comes next is: is this an isolated case? Could anything else be defined as stateful? Let’s perform an abstraction exercise.

Looking for generics: stateful stuff

Let’s think about a simple stack:

sealed trait Stack[+T]
case object Empty extends Stack[Nothing]
case class NonEmpty[T](head: T, tail: Stack[T]) extends Stack

The implementation is really simple. But let’s focus in the Stack trait and in a hypothetical pop method that pops an element from the stack so it is returned as well as the rest of the stack:

sealed trait Stack[+T]{
  def pop(): (Option[T], Stack[T])
}

Does it sound familiar to you? It is mysteriously similar to

trait Lazy[T]{
  def eval: (T, Lazy[T])
}

isn’t it?

If we try to re-factor for getting a common trait between Lazy and Stack, we could define a much more abstract type called State:

trait State[S,T] {
  def apply(s: S): (T, S)
}

Simple but pretty: the State trait is parameterized by two types: S (state type) and T (info or additional element that is returned in the specified state mutation). Though it’s simple, it’s also a ver common pattern when designing Scala systems. There’s always something that holds certain state. And everything that has an state, it mutates. And if something mutates in a fancy and smart way…oh man.

That already exists…

24314442

All this story that seems to be created from a post-modern essay, has already been subject of study for people…that study stuff. Without going into greater detail, in ScalaZ library you can find the State monad that, apart from what was previously pointed, is fully-equipped with composability and everything that being a monad means (semigroup, monoid, …).

If we define our Lazy type with the State monad, we’ll get something similar to:

import scalaz.State

type Lazy[T] = (() => T, Option[T])

def Lazy[T](f: => T) = (() => f, None)

def eval[T] = State[Lazy[T], T]{
  case ((f, None)) => {
    val evaluated = f.apply()
    ((f, Some(evaluated)), evaluated)
  }
  case s@((_, Some(evaluated))) => (s, evaluated) 
}

When decrypting the egyptian hieroglyph, given the State[S,T] monad, we have that our S state will be a tuple composed of what exactly represents a lazy expression (that we also previously described):

type Lazy[T] = (() => T, Option[T])
  • A Function0 that represents the lazy evaluation of T
  • The T value that might have been evaluated or not

For building a Lazy value, we generate a tuple with a function that stands for the expression pointed with the by-name parameter of the Lazy method; and the None value (because the Lazy guy hasn’t been evaluated yet):

def Lazy[T](f: => T) = (() => f, None)

Last, but not least (it’s actually the most important part), we define the only state transition that is possible in this type: the evaluation. This is the key when designing any State type builder: how to model what out S type stands for and the possible state transitions that we might consider.

In the case of the Lazy type, we have two possible situations: the expression hasn’t been evaluated yet (in that case, we’ll evaluate it and we’ll return the same function and the result) or the expression has been already evaluated (in that case we won’t change the state at all and we’ll return the evaluation result):

def eval[T] = State[Lazy[T], T]{
  case ((f, None)) => {
    val evaluated = f.apply()
    ((f, Some(evaluated)), evaluated)
  }
  case s@((_, Some(evaluated))) => (s, evaluated) 
}

iZcUNxH

In order to check that we can still count on the initial features we described for the Lazy type (it can only be evaluated once, only when necessary, …) we check the following assertions:

var sideEffectDetector: Int = 0

val two = Lazy {
  sideEffectDetector += 1
  2
}

require(sideEffectDetector==0)

val (_, (evaluated, evaluated2)) = (for {
  evaluated <- eval[Int]
  evaluated2 <- eval[Int]
} yield (evaluated, evaluated2)).apply(two)

require(sideEffectDetector == 1)
require(evaluated == 2)
require(evaluated2 == 2)

Please, do notice that, as we mentioned before, what is defined inside the for-comprehension are the same transitions or steps that the state we decide will face. That means that we define the mutations that any S state will suffer. Once the recipe is defined, we apply it to the initial state we want.
In this particular case, we define as initial state a lazy integer that will hold the 2 value. For checking the amount of times that our Lazy guy is evaluated, we just add a very dummy var that will be used as a counter. After that, we define inside our recipe that the state must mutate twice by ussing the eval operation. Afterwards we’ll check that the expression of the Lazy block has only been evaluated once and that the returning value is the expected one.

I wish you the best tea for digesting all this crazy story 🙂
Please, feel free to add comments/menaces at the end of this post or even at our gitter channel.

See you on next post.
Peace out!

Más lazy’s, la mónada State y otras cosas con estado

En el anterior post hablábamos sobre la evaluación perezosa en Scala. Al final de dicho post, planteábamos una pregunta: ¿Un Lazy tiene estado?

24195622

Para responder a dicha pregunta, vamos a intentar definir un tipo que represente un valor Lazy como sigue:

trait Lazy[T] {

  val evalF : () => T

  val value: Option[T] = None

}
object Lazy{
  def apply[T](f: => T): Lazy[T] =
    new Lazy[T]{ val evalF = () => f }
}

Como se puede observar, nuestro tipo Lazy está parametrizado por un tipo T que representa el tipo del valor en cuestión(Lazy[Int] sería la representación de un entero perezoso).
Además, podemos ver que se compone de dos elementos principales que caracterizan a un Lazy:

  • evalF : Función de cero argumentos que, al invocar su método apply, evalúa la expresión de T contenida.
  • value : El valor resultante de la interpretación de la función evalF. Esta parte es la que denota el estado en el tipo Lazy, y solo admite dos posibles valores: None (no evaluado) o Some(t) (si ya ha sido evaluado y el resultado obtenido).

También hemos añadido un objeto companion que define el constructor de instancias Lazy que recibe un argumento by-name que se devuelve como resultado de la función evalF.

e9a2295b3db9b45c8f5484a09033c1c71cf88e3375bb7ff60456bc81c29a4e04

La cuestión ahora es: ¿Cómo unimos la función de evaluación con el valor que devuelve para hacer que Lazy mantenga un estado? Definiendo la función eval:

trait Lazy[T] { lzy =>

  val evalF : () => T

  val value: Option[T] = None

  def eval: (T, Lazy[T]) = {
    val evaluated = evalF.apply()
    evaluated -> new Lazy[T]{ mutated =>
      val evalF = lzy.evalF
      override val value = Some(evaluated)
      override def eval: (T, Lazy[T]) = 
        evaluated -> mutated
    }
  } 

}

La función eval devuelve una tupla de dos elementos:

  • el valor resultante de la evaluación de la expresión que representa el valor perezoso.
  • una nueva versión del valor Lazy que contiene el nuevo estado: el resultado de la evaluación.

Si os fijáis, lo que hace el método en primer lugar, es invocar a la función evalF para obtener el valor de tipo T que aún estaba sin evaluar.
Una vez hecho esto, lo devolvemos así como la nueva versión del elemento Lazy. Esta nueva versión (llamémosla mutated) tendrá en su atributo value el resultado de haber invocado a evalF. Del mismo modo, modificamos su método eval, para que en sucesivas invocaciones se devuelva a sí mismo y no genere nueva instancias que en realidad no varían su estado.

La cuestión interesante viene ahora: ¿es este un caso único? ¿Existen más ‘cosas’ que mantienen un estado? Hagamos un ejercicio de abstracción.

Buscando la genericidad: cosas-con-estado

Pensemos en el caso de una pila:

sealed trait Stack[+T]
case object Empty extends Stack[Nothing]
case class NonEmpty[T](head: T, tail: Stack[T]) extends Stack

La implementación sale casi sola. Pero centrémonos en el trait Stack y en un hipotético método pop que desapila un elemento que se devuelve junto al resto de la pila:

sealed trait Stack[+T]{
  def pop(): (Option[T], Stack[T])
}

¿Os suena de algo? ¿No se parece misteriosamente a

trait Lazy[T]{
  def eval: (T, Lazy[T])
}

…?

Si intentamos sacar factor común entre Lazy y Stack podríamos definir un tipo mucho más abstracto llamado State:

trait State[S,T] {
  def apply(s: S): (T, S)
}

Simple pero bello: el trait State está parametrizado por dos tipos: S (tipo de estado) y T (información o elemento adicional que devuelve cada vez que mutamos el estado). Aquí donde lo veis, se trata de un patrón muy recurrente al diseñar sistemas en Scala. Siempre hay algo que mantiene un estado. Y todo lo que tiene estado muta. Y si ese algo muta de manera segura y elegante…oh man.

Esto ya existe …

21495586

Toda esta historia que parece sacada de un ensayo post-moderno, resulta que ya ha sido objeto de estudio de personas que estudian cosas. Sin entrar en mucho detalle, en la librería ScalaZ podéis encontrar la mónada State que, además de lo descrito anteriormente, trae de serie un full-equipped de componibilidad y todo lo que conlleva ser Mónada (semigrupo, monoide, etc).

Si definimos nuestro tipo Lazy con la mónada State tenemos algo como:

import scalaz.State

type Lazy[T] = (() => T, Option[T])

def Lazy[T](f: => T) = (() => f, None)

def eval[T] = State[Lazy[T], T]{
  case ((f, None)) => {
    val evaluated = f.apply()
    ((f, Some(evaluated)), evaluated)
  }
  case s@((_, Some(evaluated))) => (s, evaluated) 
}

Al descomponer el jeroglífico egipcio arriba expuesto, dada la mónada State[S,T], nuestro estado S va a ser una tupla de lo que representa en el fondo a una evaluación perezosa:

type Lazy[T] = (() => T, Option[T])

y que más arriba hemos descrito:

  • Una Function0 que representa la evaluación demorada de T
  • El valor T que puede haberse evaluado o no

Para construir un valor Lazy, generamos una tupla con una función que recoge la expresión indicada por un argumento by-name del método Lazy y el valor None (porque aún no ha sido evaluado el Lazy):

def Lazy[T](f: => T) = (() => f, None)

Por último (y esta es la parte importante) definimos la única transición posible de estado que podemos concebir cuando hablamos de valores perezosos: la evaluación. Esta es la clave cuando diseñamos cualquier constructor de tipos que extiende de State: lo importante es modelar qué es nuestro tipo S y las transiciones de estado posibles.

Para el tipo Lazy, tenemos dos posibles casos: que la expresión aún no haya sido evaluada (en cuyo caso la evaluamos y devolvemos la misma función y el resultado) ó que la expresión ya haya sido evaluada (en cuyo caso dejamos el estado como está y devolvemos además el resultado de la evaluación):

def eval[T] = State[Lazy[T], T]{
  case ((f, None)) => {
    val evaluated = f.apply()
    ((f, Some(evaluated)), evaluated)
  }
  case s@((_, Some(evaluated))) => (s, evaluated) 
}

iZcUNxH

Para comprobar que seguimos contando con las mismas características iniciales para las que definimos el tipo Lazy (solo se evalúa una vez, solo se evalúa cuando es necesario, …) lanzamos las siguiente aserciones:

var sideEffectDetector: Int = 0

val two = Lazy {
  sideEffectDetector += 1
  2
}

require(sideEffectDetector==0)

val (_, (evaluated, evaluated2)) = (for {
  evaluated <- eval[Int]
  evaluated2 <- eval[Int]
} yield (evaluated, evaluated2)).apply(two)

require(sideEffectDetector == 1)
require(evaluated == 2)
require(evaluated2 == 2)

Si os fijáis, como antes comentábamos, lo que se define en la for-comprehension son las transiciones o pasos que va a enfrentar el estado que nosotros queramos. Es decir, definimos las mutaciones que sufrirá un estado S cualquiera. Una vez definida la ‘receta’, la aplicamos al estado inicial que nosotros queramos.
En este caso, definimos como estado inicial un perezoso número entero dos. Para comprobar el número de veces que se evalúa nuestro Lazy, añadimos un var muy dummy que funcionará a modo de contador. Luego definimos en nuestra ‘receta’ que el estado debe mutar dos veces mediante la operación eval. Posteriormente comprobamos que solo se ha ejecutado una vez la expresión del bloque Lazy y que el valor resultante de la expresión es el esperado.

Os deseo la mejor de las sales de frutas para digerir todo esto 🙂
Sentíos libres de añadir comentarios/amenazas en el post o en nuestro canal de gitter.

Hasta el próximo post.
¡Agur de limón!

Abstract alge… what? The Reader monad

By losing our fear of monads, a whole new world of possibilities has opened up. Today we’ll take a look at one specific monad: the Reader monad. This monad will allow us to perform the dependency injection in our application.A few weeks ago we saw how to use Cake Pattern. If you didn’t like that that much, pay attention 🙂

The monad Reader belongs to Scalaz and thus, if we want to use it, we have to import this library in our project.

import scalaz.Reader

The constructor of the Reader monad gets a unary function as input, that is, a function with just one argument. With the monad, we’ll be able to work with the unary function in a direct and transparent way, as if it were an instance of the Function1 type.

import scalaz.Reader

val plus100 = Reader((n: Int) => n + 100)
plus100(1) //101

And that’s all? Well, no. The good thing about using the Reader monad is that once it is instantiated, we can use the map method to transform the result of the function:

import scalaz.Reader

val plus100 = Reader((n: Int) => n + 100)
plus100(1) //101

val doublePlus100 = plus100.map(_ * 2)
doublePlus100(1) //202

And how can this be helpful with dependency injection?

By using this monad, we’ll be able to inject dependencies in a component, same thing that we could do with Cake Pattern. Let’s look at a simple example. Since we’re talking about the Reader monad, let’s use an example based on a library.

6400b4d28d122bfa1876eda6a27d169e

It is required that our library has a repository injected to it. The generic implementation will be the following one:

case class Book(isbn: String, name: String)

trait Repository {
  def get(isbn: String): Book
  def getAll: List[Book]
}

In order to inject the dependency, the repository will be used as input argument to the unary function in a generic way.

trait Library {
  import scalaz.Reader

  def getBook(isbn: String) =
    Reader(
      (repository: Repository) => repository.get(isbn)
    )

  def getAllBooks =
    Reader(
      (repository: Repository) => repository.getAll
    )
}

Further on, we may want to know some information about the books, for instance, the title. For that, map function will be used, which will allow us to modify the result of the query.

object LibraryInfo extends Library {

  def bookName(isbn: String) =
    getBook(isbn) map (_.name)

}

Eventually, we will use that information, for example, in a REST API:

import scalaz.Reader

class UniversityApp(repository: Repository) extends Library {
  
  //GET ~/books/{id}/name
  def getBookName(isbn: String) =
    run(LibraryInfo.bookName(isbn))

  //GET ~/books/
  def getAll = run(getAllBooks)

  private def run[A](reader: Reader[Repository, A]): String = {
    reader(repository).toString
  }
}

object UniversityApp extends UniversityApp(new RepositoryImpl{})

The most important thing here is the private method run. This method is the one in charge of applying the implemented repository to every Reader monad that we have defined in our program.

Besides, we use an argument in our application to define the implementation of the repository we want to inject. This way, we can inject a test repository when tests need to be performed, facilitating to a great extent the construction of them.

That’s all folks!

Teoría de Cate-movidas: Mónada Reader

Después de perder el miedo a las mónadas se abre un mundo de posibilidades. Hoy vamos a ver una mónada en concreto: la mónada Reader. Esta mónada nos permitirá realizar inyección de dependencias en nuestra aplicación. Hace unas semanas vimos como utilizar el Cake Pattern. Si no te gustó demasiado, presta atención 🙂

La mónada Reader está presente en Scalaz, por lo que si queremos utilizarla, debemos importar esta librería en nuestro proyecto.

import scalaz.Reader

El constructor de la mónada Reader recibe una función unitaria, es decir, una función con un solo argumento. Con la mónada podemos trabajar con la función unitaria directamente y de forma transparente, como si fuera una instancia de tipo Function1.

import scalaz.Reader

val plus100 = Reader((n: Int) => n + 100)
plus100(1) //101

¿Y ya está? Pues no. La gracia de usar la mónada reader es que una vez instanciada podemos utilizar el método map para transformar el resultado de la función:

import scalaz.Reader

val plus100 = Reader((n: Int) => n + 100)
plus100(1) //101

val doublePlus100 = plus100.map(_ * 2)
doublePlus100(1) //202

¿Y cómo nos ayuda esto con la inyección de dependencias?

Utilizando esta mónada, podemos inyectar dependencias en un componente, al igual que hacíamos con el Cake Pattern. Vamos a utilizar un ejemplo sencillo. Aprovechando que se trata de la mónada Reader, vamos a utilizar un ejemplo basado en una biblioteca.

6400b4d28d122bfa1876eda6a27d169e

En la biblioteca será necesario inyectar un repositorio. La implementación genérica será la siguiente:

case class Book(isbn: String, name: String)

trait Repository {
  def get(isbn: String): Book
  def getAll: List[Book]
}

Para inyectar la dependencia, se utilizará como parámetro de entrada de la función unitaria el repositorio de forma genérica.

trait Library {
  import scalaz.Reader

  def getBook(isbn: String) =
    Reader(
      (repository: Repository) => repository.get(isbn)
    )

  def getAllBooks =
    Reader(
      (repository: Repository) => repository.getAll
    )
}

Más adelante, vamos a querer conocer determinada información de los libros, por ejemplo, el nombre. Para ello se utilizará la función map, que nos permitirá cambiar el resultado de la consulta.

object LibraryInfo extends Library {

  def bookName(isbn: String) =
    getBook(isbn) map (_.name)

}

Finalmente, vamos a utilizar esta información por ejemplo en una API REST:

import scalaz.Reader

class UniversityApp(repository: Repository) extends Library {
  
  //GET ~/books/{id}/name
  def getBookName(isbn: String) =
    run(LibraryInfo.bookName(isbn))

  //GET ~/books/
  def getAll = run(getAllBooks)

  private def run[A](reader: Reader[Repository, A]): String = {
    reader(repository).toString
  }
}

object UniversityApp extends UniversityApp(new RepositoryImpl{})

Lo más importante es el método privado run. Este método es el encargado de aplicar el repositorio implementado en cada una de las mónadas readers que hemos definido en nuestro programa.

Además, utilizamos un argumento en nuestra aplicación para definir la implementación del repositorio que queremos inyectar. De esta manera, podemos inyectar un repositorio de prueba cuando tengamos que hacer tests, facilitando en gran medida la construcción de los mismos.

¡Esto es todo amigos!

Abstract alge… what? Monads

The day has finally come. Today we’ll take a look at the noteworthy monads.

A monad, just like a monoid, may seem to be a concept taken from the deepest hell. It seems almost impossible to understand. Nothing could be further from the truth. Let’s try to shed light on this concept.

There are many definitions of what a monad is. Some are complicated, others are easier.

44b0bd758f8ee5c81362923f0d5c8e017c9ddf623925e60c29a4c015b89fbb45

As we are really fond of simple definitions, in this first contact with monads we’ll say that they are algebraic structures that have a constructor and a flatMap method which, as we already saw in previous posts, is a concatenation of a map method and a flatten.

What do we need to create a monad?

As we have already said, we need basically two methods: a constructor (commonly called apply) and a flatMap method.

In addition, there are some monadic laws to comply with. Those laws require that certain relations exist between the abovementioned functions. However, for better or worse, we are not going to analyse them in this post in order not to complicate it unnecessarily.

Case: Option type

Option type, as already mentioned in some other posts, is a monad.

Bdu68sACYAAfkkr

Let’s get into the insides of Scala to see how it’s defined:

def apply[A](x: A): Option[A] =
  if (x == null) None else Some(x)

def flatMap[B](f: A => Option[B]): Option[B] =
  if (isEmpty) None else f(this.get)

As can be appreciated, Option type has a constructor (apply) and a flatMap method. Thanks to these two methods (and to the compliance with monadic laws), we can say that Option type is a monad.

However, in Scala’s basic library, the Monad type is not defined. This is where Scalaz comes in. Let’s see how Scalaz defines the Option type as a monad:

def point[A](a: => A) = Some(a)

def bind[A, B](fa: Option[A])(f: A => Option[B]) =
  fa flatMap f

As can be seen, in Scalaz, the flatMap method is called bind. In turn, the point method calls a constructor and therefore, the apply method is called. Henceforth, if we define these two methods for our own types (them complying with monadic laws too), we’ll be able to create our own monads.

And, as they’ll have a flatMap and an apply methods (or same thing, a bind and a point methods), we’ll be able to use the for comprehension structure to make our code more readable, as we learned two weeks ago:

for {
  x <- Some(1)
  y <- Some(2)
} yield x + y //Some(3)

Conclusion

Monads are much more than we have described in this post. It’s a whole new world to explore. Apart from the abovementioned monadic laws, there are some predefined monads, such as the Reader one. Furthermore, the use of monads is geared towards avoiding side effects, which is quite important in pure functional programming. But all in due time 🙂

Teoría de Cate-movidas: Mónadas

Hoy ha llegado el día. Hoy veremos unas pinceladas de las famosas mónadas.
Una mónada, al igual que un monoide, parece un concepto sacado de lo más profundo del infierno. Parece imposible de entender. Pero nada más lejos de la realidad. Vamos a intentar poner un poco de luz sobre este concepto.

Existen numerosas definiciones de lo que es una mónada. Alguna más complicada, alguna más sencilla.

44b0bd758f8ee5c81362923f0d5c8e017c9ddf623925e60c29a4c015b89fbb45

Pero como nos gustan las definiciones sencillas, en este primer contacto con las mónadas vamos a decir que son estructuras algebraicas que tienen un constructor y un método flatMap que, como vimos en anteriores posts, es la concatenación de un método map y un flatten.

¿Qué necesitamos para crear una mónada?

Como acabamos de comentar, básicamente necesitamos dos métodos: un constructor (comúnmente llamado apply) y un método flatMap.

Además, existen unas leyes monádicas que hay que cumplir. Dichas leyes exigen una serie de relaciones entre las funciones anteriormente mencionadas. Pero, para bien o para mal, no vamos a analizarlas en este post para no hacerlo muy denso.

Ejemplo: El tipo Option

El tipo Option, como ya hemos dicho en varios post, es una mónada.

Bdu68sACYAAfkkr

Vamos a introducirnos en las tripas de Scala para ver como está definida:

def apply[A](x: A): Option[A] =
  if (x == null) None else Some(x)

def flatMap[B](f: A => Option[B]): Option[B] =
  if (isEmpty) None else f(this.get)

Como se puede ver, el tipo Option tiene un constructor (apply) y un método flatMap. Gracias a estos dos métodos (y a que se cumplen las leyes monádicas), podemos decir que el tipo Option es una mónada.

Sin embargo, en la librería básica de Scala, no está definido directamente el tipo Monad. Pero para eso está Scalaz. Vamos a ver como define Scalaz el tipo Option como mónada:

def point[A](a: => A) = Some(a)

def bind[A, B](fa: Option[A])(f: A => Option[B]) =
  fa flatMap f

Como se puede ver, en Scalaz, el método flatMap es llamado bind. A su vez, el método point llama a un constructor, por lo que realmente se llama al método apply. Por tanto, si definimos estos dos métodos para nuestros tipos propios (y además cumplen las leyes monádicas), podemos definir nuestras propias mónadas.

Y debido a que tiene definida una función flatMap y un método apply (o lo que es lo mismo, un método bind y un método point), podemos utilizar for comprehension para hacer nuestro código más legible, como vimos hace dos semanas:

for {
  x <- Some(1)
  y <- Some(2)
} yield x + y //Some(3)

Conclusión

Las mónadas son mucho más de lo que hemos contado en este post. Es todo un mundo por explorar. Además de las ya mencionadas leyes monádicas, existen distintos tipos de mónadas ya definidas, como la mónada Reader. Además, el uso de mónadas está orientado a evitar los efectos de lado, un tema bastante importante en el ámbito de la programación funcional pura. Pero todo a su tiempo 🙂

Catching exceptions in Scala: Try type

It’s quite common to call functions that may throw exceptions. For instance, when a call is made to a web service, there could be a connection error which would throw an exception.

At first sight, we can think of using a try-catch block to handle the error in case the function explodes:

try {
  val userInfo = myWebServer.getUserInfo("Royston")
  userInfo.email
} catch {
  case e: ConnectionException =&gt; // do something
  case e: BadRequestException =&gt; // do something
  case _ =&gt; //do something
}

This is quite good because, if any exception is thrown, we will be able to catch and handle it. However, using the try block is not truly a functional approach. It leaves us with very few transformation options and nor are we allowed to decide at a later point in time on the action to perform in case an exception is raised.

Try type to the rescue

Try is a type that, given an action to perform, it can return either a Success with the result of that action or the exception thrown when trying to execute that action, but encapsulated in a Failure.

import scala.util.{ Try, Success, Failure }

Try(myWebServer.getUserInfo("Royston")) match {
  case Success(userInfo) =&gt; 
    userInfo.email
  case Failure(exception: ConnectionException) =&gt; 
    //do something
  case Failure(exception: BadRequestException) =&gt; 
    //do something
  case Failure(exception) =&gt; 
    //do something
}

As can be seen, by using pattern matching, we are able to define what to do depending on the result of executing the action. Now, as an example, we can use this type in the signature of a function:

def getUserInfo(username: String): Try[String] =
  Try(myWebServer.getUserInfo("Royston"))

This way we can leave the decision on what to do with the result of the function to a different part of the code.

Another advantage compared to using a try-catch block is that we can use the methods that the Try type API provides us with. These methods will allow us to evaluate or modify the value contained in a Try. For instance, we could use the map method:

def encrypt(value: String): String =
  value.map(_.toInt).mkString("-")

getUserInfo("Royston").map(_.email).map(_.encrypt)

In the previous piece of code, what we are doing is encrypting the email in case it is successfully obtained. In case an exception is thrown, no transformation will be carried out. The behaviour is identical to the one we already saw applied to Option type.

Besides, as it has a flatmap method, we can use it in for comprehension structures and combine several instances of the Try type.

def getEmail(username: String): Try[String] =
  getUserInfo(username).map(_.email)

def getAge(username: String): Try[Int] =
  getUserInfo(username).map(_.age)

for {
  email &lt;- getEmail("Royston")
  age &lt;- getAge("Royston")
  if age &gt; 18
} yield s"User with $email is not under 18"

In this scenario, if any of the calls fails or if the user is underage, the execution flow will stop and no transformation will be performed. Otherwise, Try will be transformed.

Monads, monads everywhere

It would be quite wrong to conclude this post without our head being properly stimulated. We have seen that, by using the Try type, we can make our program more functional. As it is a monad complies some of the monad laws (what?), we can combine them in order to make our programs more expressive.

56248419

Well, there’s no need to panic. Further on, we’ll go deeper into monads and other functional abstractions and we’ll see they are not as complicated as they may seem.