style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Kotlin Magic Box

Un monad es una tecnica que nos permite crear tipos propios, extender funcionalidades de una meanera limpia y hacer tranformaciones entre tipos. Me gusto mucho en kotlin porque elimina el estar escribiendo tantos tipos todo el tiempo que a veces me parecen inecesarios (esto opinion muy personal), en este caso vamos a escribir una clase Caja que nos permite aplicar funciones de una forma continua (encadenada), manteniendo un solo closure (parcialmente, en kotlin no he hecho pruebas de rendimiento para ver cuanta memoria usa, pero en javascript el incremento en memoria es minimo).

En el ejemplo podemos ver como cambiamos de un numero en String para despues limpiarlo y convertirlo a su equivalente en carácter, lo anterior de una manera limpia, sin hacer uso mas que de una sola variable.

En el archivo Main.kt colocamos lo siguiente:

class Box<T>(private val x: T) {

    fun <R> map(f: (x:T) -> R): Box<R> {
        return Box(f(x))
    }

    fun <R> fold(f: (x:T) -> R): R {
        return f(x)
    }

    fun inspect(): String {
        return "Box($x)"
    }

}

fun main(args: Array<String>) {
    val num = Box<String>("  64  ")
            .map({ a: String -> a.trim()})
            .map({ a: String -> a.toInt()})

    println(num.inspect())

    println(num.fold({a: Int -> a.toChar()}))
}

La salida de esto es:

Box(64)
@

Como se puede ver también sirve para hacer cadenas de funciones al mismo valor cuando este es entrada para lo que sigue (acaso se parece a stream processing ?), o en otras palabras ayuda en composición de funciones.

De igual modo, me sigue gustando mas la forma de hacer lo mismo en javascript, se pierde la ventaja de los tipos, pero igual no se necesitan.

const Box = x => ({
  map: f => Box(f(x)),
  fold: f => f(x),
  inspect: () => `Box(${x})`
});

const num = Box("  64  ")
  .map(a => a.trim())
  .map(a => parseInt(a));

console.log(num.inspect())

console.log(num.fold(a => String.fromCharCode(a)));

La salida:

Box(64)
@

La función map es la que hace la magia del encadenamiento de funciones y la función fold saca el valor del closure y aplica una ultima funcion para obtener el valor al que le aplicamos todas la funciones previamente. Un ejemplo practico seria formatear monedas, fechas o traducciones de textos.

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">