TypeScript Academy · Lección

Functors y mappers genéricos

Escriba funciones map genéricas para cualquier contenedor.

Lección 4 de 413 pasos

Functors y mappers genéricos es una lección gratuita de TypeScript Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de TypeScript Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de TypeScript Academy incluye 4 lecciones en total.

Un functor genérico

Ahora utilizamos la codificación para lo que fue diseñada: un map genérico que funciona con cualquier contenedor registrado. La interfaz Functor, parametrizada mediante una URI, declara un método.

interface Functor<F extends URIS> {
  readonly URI: F;
  map<A, B>(fa: Kind<F, A>, f: (a: A) => B): Kind<F, B>;
}

La instancia de Array

Una instancia implementa map para una URI. La instancia de Array realiza el mapeo mediante el método incorporado de los arrays. Su Kind<"Array", A> se resuelve en A[].

const arrayFunctor: Functor<"Array"> = {
  URI: "Array",
  map: (fa, f) => fa.map(f)
};

Usar la instancia de Array

Al llamar a map en la instancia de Array, se transforma cada elemento y se conserva el tipo de contenedor array.

const doubled = arrayFunctor.map([1, 2, 3], n => n * 2);
// doubled: number[] -> [2, 4, 6]

El tipo Option

Defina Option como un valor o null y regístrelo. Su map aplica la función únicamente cuando hay un valor; de lo contrario, propaga null.

interface URItoKind<A> { Option: A | null }
type Option<A> = A | null;

La instancia de Option

La instancia de Option conserva el contenedor option: la función se aplica al valor y un null sigue siendo null.

const optionFunctor: Functor<"Option"> = {
  URI: "Option",
  map: (fa, f) => (fa === null ? null : f(fa))
};

Usar la instancia de Option

Ahora la misma estructura de map funciona con un contenedor completamente distinto. Los valores presentes se transforman; los valores ausentes se dejan sin cambios.

const a = optionFunctor.map(5, n => n + 1);    // 6
const b = optionFunctor.map(null, n => n + 1); // null

Una abstracción, muchos contenedores

Este es el beneficio. arrayFunctor y optionFunctor comparten la misma interfaz Functor. El código escrito contra Functor<F> funciona con ambos sin cambios.

function bumpAll<F extends URIS>(
  F: Functor<F>,
  fa: Kind<F, number>
): Kind<F, number> {
  return F.map(fa, n => n + 1);
}

Llamar a la función genérica

bumpAll no sabe ni le importa qué contenedor recibe. Pase la instancia y los datos; el resultado conserva el tipo de contenedor.

const arr = bumpAll(arrayFunctor, [1, 2]); // number[] -> [2, 3]
const opt = bumpAll(optionFunctor, 9);     // number | null -> 10

Leyes de los funtores

Un functor correcto obedece dos leyes: aplicar la función identidad no cambia nada, y aplicar dos funciones en secuencia equivale a aplicar su composición. Tanto las instancias de array como las de option anteriores las cumplen.

// map(fa, x => x) === fa
// map(map(fa, f), g) === map(fa, x => g(f(x)))

Añadir más instancias

Como la abstracción es abierta, los nuevos contenedores se incorporan registrando una URI y proporcionando una instancia. Un Tree, un Result o un Task: cada uno se vuelve compatible con map mediante el mismo código genérico.

// Register URI, implement Functor<"Tree">,
// and bumpAll works on trees too - no edits to bumpAll

Por qué es importante

Los funtores genéricos son el punto de entrada a las abstracciones funcionales en TypeScript: aplicativos, mónadas y recorridos. Cada una es una interfaz sobre Kind<F, A> con instancias para cada contenedor. Ahora comprende la maquinaria que hace posibles fp-ts y Effect.

interface Monad<F extends URIS> extends Functor<F> {
  of<A>(a: A): Kind<F, A>;
  chain<A, B>(fa: Kind<F, A>, f: (a: A) => Kind<F, B>): Kind<F, B>;
}

Comprobación rápida

Compruebe su comprensión de los funtores genéricos.

Repaso

Ha escrito un map genérico para contenedores.

  • Functor<F> declara map sobre Kind<F, A>.
  • Las instancias de Array y Option lo implementan para sus URI.
  • El código genérico, como bumpAll, funciona con cualquier contenedor registrado.
  • Las leyes de los funtores mantienen el buen comportamiento de las instancias; las abstracciones más avanzadas se construyen sobre esta base.

A continuación, el curso 24: construir analizadores sintácticos con seguridad de tipos.

Gratis para empezar

Aprende TypeScript con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
101
Lecciones
352

Preguntas frecuentes

¿La lección «Functors y mappers genéricos» es gratis?

Sí — el texto completo de «Functors y mappers genéricos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de TypeScript Academy, actualiza a CoddyKit PRO. El curso de TypeScript Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Functors y mappers genéricos»?

Escriba funciones map genéricas para cualquier contenedor. Practicas TypeScript Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar TypeScript Academy?

No se requiere experiencia previa. TypeScript Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Functors y mappers genéricos»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de TypeScript Academy?

Sí. Cada lección de TypeScript Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. El problema de HKT en TypeScript
  2. Definición de constructores de tipos
  3. El patrón HKT ligero
  4. Functors y mappers genéricos
← Volver a TypeScript Academy