Applicative Functors

Como mencioné en el escrito anterior de esta serie, los Applicative Functors son extensiones naturales de los Functors. ¿Cuál es la diferencia entonces?

Cuando hablamos de Functors, especificamos que estos saben cómo aplicar una función a los elementos que contienen, y el resultado queda “envuelto” en otro Functor del mismo tipo (lo que se conoce como endomorfismo). Pero ¿qué pasa si la función que queremos aplicar está contenida dentro de un Functor?

Recordemos que un para mapear una función en un Functor (levantarla a su contexto), la definición es:

map (f: A => B): F[A] => F[B]

Se puede apreciar que f es simplemente una función que toma valores de tipo A y regresa valores de tipo B; la función no está contenida en ningún contexto. Entonces, si tenemos algo como:

(f: F[A => B]): F[A] => F[B]

no concuerda con lo que map espera, puesto que la función ya está dentro del Functor, y map espera que no lo esté.

Los applicative entran en escena aquí. Definidos en una typeclass, definen 2 operaciones básicas:

Continue reading “Applicative Functors”

Functors – Más detalles

Ya he mencionado un poco acerca de Functors cuando hablé de Monads. Aquí ampliaré un poco al respecto.

Matemáticamente hablando, un functor es un tipo de “mapeo” entre categorías… sí, esa definición no ayuda mucho. Supongamos que tenemos dos conjuntos C y D, y objetos X que pertenecen a C.  Un functor F asocia a esas X con un objeto F(X) que pertenece a D (tomado tal cual de la definción en Wikipedia). Si hablamos de morfismos, asocia X -> Y que pertenecen a C con F(X) -> F(Y) que pertenecen a D.

functor

Muchas matemáticas de por medio…

En lo que concierne a programación funcional, un functor es una typeclass cuyos miembros deben saber mapear un morfismo que toma un valor y lo transforma en otro, sin tener que “sacarlo” para aplicarlo. Esos “morfismos” son simplemente funciones que toman un argumento del tipo de datos que envuelve el Functor y regresan otro tipo de datos (que puede ser que sea el mismo).

Demasiada confusión…

Continue reading “Functors – Más detalles”

Semigrupos y monoids

Una vez que hemos entendido lo que son las typeclasses y cómo implementarlas en Scala, lo que sigue es hablar de abstracciones,

Muchos programadores se asustan cuando leen algo que tiene que ver con teoría de categorías o matemáticas abstractas; después de todo, se puede programar bien sin meterse en tantos líos. No obstante, hay un principio que todo programador conoce: DRY (Don’t Repeat Yourself), que básicamente se refiere a no repetir el mismo código en diferentes partes; de hecho, es de lo más importante que se aprende cuando se aprende programación estructurada: si vas a usar una serie de instrucciones en más de un lugar, mejor júntalas, ponlas en un método por separado y mándalo llamar cada vez que lo necesites con los datos que necesites procesar. Simple.

Las abstracciones matemáticas son exactamente lo mismo, solamente llevado a más alto nivel: si existe un patrón que se repite constantemente en diferentes programas, ¿por qué no abstraerlo en código separado y llamarlas con los datos necesarios?

Continue reading “Semigrupos y monoids”

Typeclasses

Cuando se lee el término “typeclasses” por primera vez, causa confusión debido a que pensamos o en tipos o en clases, pero no en un término compuesto por ambas palabras. No obstante, el concepto es simple y muy poderoso, y seguramente quienes tienen experiencia con Java o lenguajes similares habrán usando algo similar sin saberlo.

Continue reading “Typeclasses”

Monads – Yo también tenía que escribir al respecto

Seguí la tradición: cuentan las leyendas que cuando una persona comienza a ver la luz al usar Monads, invariablemente escribe un tutorial. Pero en mi caso, no es un tutorial, sino más bien una breve explicación de lo que son, junto con algunos ejemplos. Esto es con el fin de que yo mismo compruebe si entiendo el concepto general, y al mismo tiempo de que salgan gurús en programación funcional y me corrijan y me digan en qué estoy mal.

Ésta no es una guía exhaustiva, y omitiré muchos conceptos, pero pondré referencias por aquello de que haya interesados en el tema.

Como nota, sé que en español los términos son Funtor mónadas, pero nada más no me entran en la cabeza, por lo que los usaré en inglés. Además, aunque no está dirigido a un lenguaje en particular, la mayoría de los ejemplos mostrados están en Scala.

Continue reading “Monads – Yo también tenía que escribir al respecto”

Encuentra la diferencia – versión Kanji – en Scala

Y ya con este código dejo el tema por la paz. Lo pongo para que quede en el registro:

object Uniques {
  def main(a: Array[String]) {
    if (a.length != 1) {
      println("Need an argument to analyze")
      sys.exit(1)
    }
    else {
      findUniques(a(0)) match {
        case l if (l.isEmpty) => println("All characters are the same")
        case l => l foreach println
      }
    }
  }

  def findUniques(seq: String) =  seq filter {c => seq.count(_ == c) == 1} map {c => "Unique instance found: " + c + " in position " + (seq.indexOf(c) + 1)}
}

Y probando el caso en cuestión:

mmedina@yggdrasil-m:~/Programming/Scala/Tests$ scala Uniques "麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈塵麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈 麈麈麈麈麈麈麈麈麈"
Unique instance found: 塵 in position 66

Hacerlo para que funcione con otros tipos de datos sin cambiar nada de código no es muy complicado.