Funtores, funtores aplicativos y mónadas explicados con TypeScript
(evan-moon.github.io)Texto principal
- Explica con código TypeScript el proceso que va desde los dos problemas que no pueden resolverse solo con
mapde los funtores (el problema de que una función quede atrapada dentro de un contenedor y el problema del anidamiento de contexto al componer) hasta llegar a los funtores aplicativos y las mónadas - Parte del trasfondo de 1988, cuando Eugenio Moggi modeló los programas no como
A → B, sino comoA → T(B) - Aborda la estructura
flatMap = map + joiny las tres leyes para usarla de forma segura (asociatividad, identidad izquierda e identidad derecha) - Explica por qué una mónada es un "objeto monoide en la categoría de endofuntores" comparándolo con el monoide de la suma de enteros
- También menciona por qué
Promisefunciona de manera monádica, pero no es una mónada matemática en sentido estricto
Las limitaciones de los funtores: lo que no se puede hacer con map
- Si se aplica una función currificada con
map, el resultado deja la función atrapada dentro del contenedor, comoMaybe<(b: number) => number>mapsolo puede recibir funciones que están fuera del contenedor, así que no hay forma de aplicar esa función atrapada a otro valor
- Si se componen dos funciones que devuelven un funtor, el contexto queda anidado como
Maybe<Maybe>- A medida que aumentan los pasos, se anida indefinidamente como
Maybe<Maybe<Maybe<...>>>
- A medida que aumentan los pasos, se anida indefinidamente como
Funtores aplicativos: aplicar una función dentro del contenedor
- Con la operación
apply, es posible aplicar una función atrapada dentro de un contenedor al valor de otro contenedorapply: T<(A → B)> → T<A> → T<B>
- Con la operación
pure, se inserta un valor puro en el contenedor - Límite: hay que tener definido de antemano qué contenedores se van a componer
- No puede expresar dependencias secuenciales dinámicas en las que el siguiente cálculo se decide según el resultado del cálculo anterior
Mónadas: la invención de una operación para aplanar anidamientos
- La operación
joinaplana un contenedor dobleT<T<A>> → T<A>en uno soloArray.prototype.flatde JavaScript cumple el mismo papel
- En la práctica se usa
flatMap, que combinamap + joinflatMap: T<A> → (A → T<B>) → T<B>maprecibeA → B, peroflatMaprecibeA → T<B>, de modo que el resultado se mantiene en una sola capa
Las tres leyes de flatMap
- Ley de asociatividad: al aplanar un triple anidamiento
T(T(T(A))), el resultado debe ser el mismo ya sea que se aplane desde adentro
hacia afuera o desde afuera hacia adentrom.flatMap(f).flatMap(g) === m.flatMap(x => f(x).flatMap(g))
- Ley de identidad izquierda: si se mete un valor con
purey luego se aplicaflatMapde inmediato, debe dar lo mismo que aplicar la función directamentepure(a).flatMap(f) === f(a)
- Ley de identidad derecha: si se pasa
pureaflatMap, se obtiene el contenedor originalm.flatMap(pure) === m
Desglosando "objeto monoide en la categoría de endofuntores"
- Los funtores en programación van del mundo de los tipos al mundo de los tipos, así que son endofuntores
- Se puede construir una categoría de endofuntores donde los propios endofuntores sean los objetos
- Si se sustituyen los requisitos de un monoide (operación binaria + ley de asociatividad + elemento identidad), queda así:
- operación binaria =
join - elemento identidad =
pure - La estructura corresponde exactamente al monoide de la suma de enteros
- operación binaria =
Por qué Promise no es una mónada
thenmezcla el comportamiento demapyflatMapsegún el valor de retorno- Un estado
Promise<Promise>no está permitido en tiempo de ejecución y se fusiona inmediatamente en una sola capa - Aunque en la práctica es conveniente, no satisface las leyes de una mónada matemática
2 comentarios
¡Por favor, también aborden la comónada!
Uaa... lo voy a pensar jajajaja