Mónada Either en TypeScript
⏱ Dedicación recomendada: 0 minutos
Esto considera el contenido visible y relevante, e ignora texto colapsado o marcado como opcional.
En TypeScript, aunque no existe un tipo Either
nativo como en Haskell, podemos modelar un comportamiento similar utilizando Unión de Tipos y objetos discriminados. TypeScript permite definir tipos que pueden ser uno de varios valores, lo que nos permite imitar la semántica de Either
.
Implementación de Either
en TypeScript
Podemos crear una implementación de Either
en TypeScript utilizando una unión de tipos para representar Left
y Right
.
type Either<L, R> =
| { type: 'Left'; value: L }
| { type: 'Right'; value: R };
Mónada Either
Para que Either
sea una mónada, necesitamos implementar las funciones flatMap
y unit
:
const unit = <L, R>(value: R): Either<L, R> => right(value);
class Left<L> {
readonly type = 'Left';
constructor(public value: L) {}
flatMap<T>(_fn: (value: R) => Either<L, T>): Either<L, T> {
return this as Either<L, T>;
}
}
class Right<R> {
readonly type = 'Right';
constructor(public value: R) {}
flatMap<T>(fn: (value: R) => Either<L, T>): Either<L, T> {
return fn(this.value);
}
}
Ejemplo de Validación de Contraseña
Supongamos que queremos validar una contraseña en TypeScript utilizando Either
:
const validateLength = (password: string): Either<string, string> =>
password.length >= 8
? unit(password)
: new Left("Password is too short");
const validateContainsNumber = (password: string): Either<string, string> =>
/\d/.test(password)
? unit(password)
: new Left("Password must contain a number");
const validatePassword = (password: string): Either<string, string> =>
unit(password)
.flatMap(validateLength)
.flatMap(validateContainsNumber);
Comparación Final
Característica | Kotlin | TypeScript |
---|---|---|
Implementación | Usa clases selladas para modelar Either , con una distinción clara entre Left y Right . | Se modela utilizando unión de tipos y objetos discriminados, aprovechando las capacidades de TypeScript. |
Exhaustividad | El compilador garantiza que todos los casos de Either sean manejados, proporcionando seguridad de tipos. | En TypeScript, el uso de type guards ayuda a manejar todos los casos, pero no es tan estricto como Kotlin. |
Compatibilidad con FlatMap | Kotlin permite fácilmente extender Either con métodos como flatMap directamente en la clase sellada. | En TypeScript, se necesita definir flatMap en las clases Left y Right manualmente para lograr el mismo comportamiento. |
Uso de funciones de extensión | Kotlin permite definir funciones de extensión directamente sobre Either para mejorar su funcionalidad. | TypeScript no soporta funciones de extensión directamente, pero se puede simular usando prototipos. |
Seguridad en tiempo de compilación | Kotlin ofrece seguridad en tiempo de compilación con verificación exhaustiva de tipos y casos. | TypeScript proporciona cierta seguridad en tiempo de compilación, pero es menos estricta que en Kotlin debido a su naturaleza de tipado estructural. |
Ventajas y Desventajas de Either
en TypeScript
Beneficios
- Flexibilidad de Tipado: La implementación de
Either
en TypeScript permite aprovechar la flexibilidad del sistema de tipos y de los type guards, lo que proporciona versatilidad en el manejo de valores. - Compatibilidad con el Ecosistema: TypeScript, al estar integrado con JavaScript, permite que
Either
se combine fácilmente con otras herramientas y bibliotecas del ecosistema, lo que facilita su uso en aplicaciones web. - Uso de Objetos Discriminados: Los objetos discriminados de TypeScript facilitan la verificación de tipos en tiempo de ejecución y la implementación de patrones similares a los de lenguajes funcionales.
Limitaciones
- Menos Seguridad que Kotlin: Aunque TypeScript proporciona verificación en tiempo de compilación, no es tan estricto como Kotlin, lo que puede resultar en errores no detectados si no se manejan todos los casos explícitamente.
- Sintaxis Verbosa: La implementación de
Either
en TypeScript puede ser más detallada y menos intuitiva que en Kotlin, especialmente cuando se extienden las funcionalidades con métodos comoflatMap
. - Limitaciones de Extensión: TypeScript no soporta funciones de extensión de manera nativa, lo que obliga a utilizar prototipos o clases, lo que puede ser menos intuitivo y menos seguro en términos de tipado.
¿Qué Aprendimos?
En esta lección, hemos explorado cómo implementar y utilizar la mónada Either
en TypeScript, comparando sus características y funcionalidades con la implementación en Kotlin. Aquí están los puntos clave que hemos aprendido:
- Modelado de Tipos Algebraicos: Tanto en Kotlin como en TypeScript, el tipo
Either
permite modelar operaciones que pueden resultar en un éxito (Right
) o en un fallo (Left
). Mientras que Kotlin ofrece una implementación nativa más estructurada utilizando clases selladas, TypeScript utiliza unión de tipos y objetos discriminados para lograr un comportamiento similar. - Extensibilidad y Composición:
- En Kotlin, se puede extender
Either
de forma intuitiva mediante métodos y funciones de extensión, lo que facilita su uso y composición. - En TypeScript, aunque se pueden simular estas extensiones utilizando prototipos o definiendo métodos en clases, el enfoque es menos directo y puede ser más complejo.
- En Kotlin, se puede extender
- Seguridad en Tiempo de Compilación:
- Kotlin proporciona un control exhaustivo en tiempo de compilación, asegurando que todos los casos sean manejados y que los tipos sean verificados con precisión, reduciendo el riesgo de errores en tiempo de ejecución.
- TypeScript ofrece cierta verificación en tiempo de compilación, pero debido a su naturaleza de tipado dinámico y estructural, no alcanza el mismo nivel de exhaustividad que Kotlin. Esto significa que, si bien se pueden manejar errores de forma segura, hay más posibilidades de que se ignoren casos o se produzcan errores no detectados.
- Patrones Funcionales en TypeScript:
- A pesar de las diferencias, TypeScript sigue permitiendo el uso de patrones funcionales como el encadenamiento de operaciones usando
flatMap
, lo que resulta útil para componer funciones que manejan errores de forma explícita. - La flexibilidad del sistema de tipos de TypeScript, combinada con type guards, facilita la creación de estructuras funcionales que son fáciles de integrar en el ecosistema JavaScript.
- A pesar de las diferencias, TypeScript sigue permitiendo el uso de patrones funcionales como el encadenamiento de operaciones usando
Reflexión Final
La implementación de Either
en TypeScript muestra cómo un lenguaje orientado a objetos y tipado estructural puede adoptar conceptos de lenguajes funcionales para manejar errores de forma más explícita y segura. Aunque hay limitaciones en comparación con Kotlin, TypeScript sigue siendo una opción potente para desarrollar aplicaciones que se benefician de enfoques funcionales, especialmente en el contexto de desarrollo web.
Con este conocimiento, ahora puedes aplicar Either en proyectos TypeScript para manejar errores de forma clara, reduciendo el uso de excepciones y promoviendo un enfoque más seguro y funcional en tu código.