Algebras (FP)

Un álgebra nos describe las operaciones permitidas mediante un DSL1, el cual se define dentro de otro lenguaje de programación huésped (en nuestro caso Scala).

Un álgebra puede estar definido por una interfaz en Java, una clase con métodos de instancia o estáticos, un record o un namespace con las operaciones permitidas sobre un diccionario que define nuestro dominio2, etc.

En el caso concreto de Scala vamos a definirlas mediante typeclasses debido a su versatilidad gracias a los constructores de tipos.

Vamos a usar tagless final para definir nuestros álgebras: interfaces que abstraen sobre el efecto usando un constructor de tipos (HKT).

Podemos verlo claramente en el siguiente ejemplo extraído de GVolpe: Practical FP In Scala, A Hands-On Approach

trait Counter[F[_]]:
  def incr: F[Unit]
  def get: F[Int]

Gracias a este constructor de tipos F[_] podemos tener tantas implementaciones como queramos, no solo de una entidad de nuestro docminio. También podemos cambiar el tipo F que nos va a definir cómo vamos a realizar el cálculo/cómputo. De ahí la versatilidad que comentaba antes que obtenemos gracias a los HKT.

Cada una de estas implementaciones será un intérprete. Esta diferenciación entre álgebra (que tienen que ser abstractas) e intérpretes (también llamados programas) es importante: un intérprete define una implementación capaz de ejecutar ciertas acciones, lo que permite/hace necesario definir ciertas restricciones en el tipo del efecto/cálculo como pueden ser Monad, Resource, etc. En cambio un álgebra es un ente puramente abstracto que define simplemente un conjunto de operaciones a realizar pero que ni siquiera tienen definidas el tipo del efecto que vamos a usar.

Notas

1

Domain Specific Language, al final es el lenguaje que limita qué operaciones son válidas en nuestro dominio.

2

En Clojure podemos ver las interfaces que definimos con Polylith como distintos álgebra, por lo que que cada componente, la interfaz en este caso, sería un álgebra distinto.