coldwa.st
Todas las guíasProgramaciónWebDatosHerramientasBases de datosHaskellConceptosCabal y buildsToolchainCompiladorRendimientoEditor y HLS

Programación · conceptos · Haskell

¿Qué es una función de orden superior?

Por ColdwastActualizado el 24 de junio de 20268 min de lectura#functional#concepts#haskell
Un portátil sobre un escritorio con un editor de código abierto que muestra código fuente con resaltado de sintaxis
Un editor de código abierto en un portátil: las funciones de orden superior son una herramienta cotidiana que escribes aquí — funciones que reciben otras funciones como argumento, como map y filter.

En la mayoría de los lenguajes, una función es algo que se llama. En la programación funcional, una función también es un valor: puedes guardarla en una variable, pasarla a otra función y recibir una como resultado. Una función de orden superior es exactamente la que hace una de esas dos últimas cosas. Esta guía explica qué es una función de orden superior, por qué map, filter y fold son los ejemplos clásicos, cómo sustituyen a los bucles y cómo se ven en Haskell.

La definición breve

Una función de orden superior es una función que recibe una o más funciones como argumento, devuelve una función como resultado, o ambas cosas. Una función que no hace ninguna de las dos — que solo recibe y devuelve valores simples como números o cadenas — se llama de primer orden. El término «orden superior» significa simplemente que opera sobre funciones igual que una función ordinaria opera sobre datos.

Esto solo funciona en un lenguaje donde las funciones son valores de primera clase: cosas que puedes nombrar, pasar y devolver, igual que un entero. Haskell, JavaScript, Python, Swift y muchos otros tratan así las funciones, y eso es lo que hace posibles las funciones de orden superior.

Las tres clásicas: map, filter y fold

Casi toda base de código funcional se apoya en tres funciones de orden superior. Cada una recibe una función como argumento y la aplica sobre una colección:

  • map aplica una función a cada elemento de una lista y devuelve una nueva lista con los resultados. map (+1) [1,2,3] da [2,3,4] — la función (+1) es el argumento.
  • filter conserva solo los elementos para los que una función devuelve verdadero. filter even [1,2,3,4] da [2,4] — aquí even es la función que pasas.
  • fold (también llamado reduce) reduce una lista a un único valor combinando los elementos de dos en dos. foldr (+) 0 [1,2,3] los suma hasta 6 — el paso de combinación (+) es la función que se pasa como argumento.

En cada caso, tú aportas la pequeña pieza de lógica — incrementar, «es par», sumar — y la función de orden superior se encarga de recorrer la lista. Describes qué hacer con cada elemento, no la mecánica de cómo recorrerlos.

Cómo sustituyen a los bucles

En un lenguaje imperativo escribirías un bucle con un contador, un acumulador y un índice explícito. La misma intención expresada con una función de orden superior cabe en una sola línea, porque la iteración ya está integrada en map o fold. Por eso el código puramente funcional, que evita los contadores de bucle mutables, se apoya tanto en estas funciones y en la recursión — entre ambas cubren el trabajo que los bucles hacen en otros lenguajes. Las comprensiones de listas suelen ser un atajo legible para la misma combinación de map y filter.

Código fuente Swift en una pantalla oscura donde un bloque closure se pasa como argumento completionHandler a una llamada de apertura de documento
Una función de orden superior en otro lenguaje: aquí un closure (el bloque entre llaves) se pasa como argumento completionHandler a document.open — una función entregada a otra función, exactamente la idea detrás de map y filter.

Devolver una función: donde se vuelve potente

La otra mitad de la definición — funciones que devuelven funciones — es igual de común. Una función puede construir y devolver una nueva función especializada. Un ejemplo clásico es el «fabricante de multiplicadores»: le das un número y devuelve una función que multiplica su entrada por ese número. Llámalo con 3 y obtienes una función «por tres» que puedes usar como cualquier otra. El fabricante es de orden superior porque su resultado es a su vez una función.

En Haskell esto está tejido en el lenguaje mediante el currying: toda función de varios argumentos es en realidad una cadena de funciones de un solo argumento, cada una devolviendo la siguiente. Por eso funciona map (+1)(+1) es la función de suma con un argumento ya proporcionado, que devuelve una función que aún espera el otro. Esta aplicación parcial son las funciones de orden superior en acción, a menudo sin que te des cuenta.

Funciones de orden superior en Haskell

Haskell hace la idea explícita en sus firmas de tipo. El tipo de map se escribe map :: (a -> b) -> [a] -> [b]. Léelo de izquierda a derecha: el primer argumento (a -> b) es a su vez una función — esa es la parte de orden superior — seguido de una lista de a, produciendo una lista de b. Las flechas dejan ver sobre el papel que se está pasando una función. El mismo patrón aparece en filter :: (a -> Bool) -> [a] -> [a] y en toda la biblioteca estándar.

A menudo pasas estas funciones en línea como lambdas, pequeñas funciones anónimas escritas con una barra invertida, como map (\x -> x * x) [1,2,3] para elevar al cuadrado cada elemento. Tanto si pasas una función con nombre, una sección de operador como (*2) o una lambda, es el mismo mecanismo: una función viajando como valor hacia una función de orden superior.

Por qué importan

Las funciones de orden superior permiten extraer la forma común de un cálculo — «hacer algo a cada elemento», «conservar los que coinciden», «combinarlos todos» — y reutilizarla con una lógica distinta conectada. El resultado: menos código repetido, código que se lee más cerca de su intención y piezas de lógica pequeñas, comprobables y componibles. Son el ladrillo sobre el que se expresa buena parte de la programación funcional de Haskell, y combinadas con la evaluación perezosa de Haskell incluso permiten mapear y filtrar listas conceptualmente infinitas.

Las concesiones honestas

Las funciones de orden superior requieren acostumbrarse: leer un foldr o una cadena map . filter es una destreza, y las lambdas muy anidadas pueden volverse difíciles de seguir. Pasar funciones por todas partes también puede hacer menos evidente una traza de pila cuando algo falla. La recompensa — mucho menos código de iteración repetitivo y una lógica recomponible — explica por qué se han extendido mucho más allá de los lenguajes funcionales, hasta el JavaScript, Python y Swift cotidianos. Usadas con mesura, hacen el código más corto y claro; abusadas, pueden oscurecerlo como cualquier otra herramienta.

Preguntas frecuentes

¿Qué es una función de orden superior en términos simples?

Una función de orden superior es una función que recibe otra función como argumento, devuelve una función como resultado, o ambas cosas. En lugar de trabajar solo con datos simples como números y cadenas, trabaja con funciones. Los ejemplos clásicos son map, filter y fold, que reciben cada uno una pequeña función y la aplican sobre una lista.

¿Es map una función de orden superior?

Sí. map recibe una función como primer argumento y la aplica a cada elemento de una lista, devolviendo una nueva lista con los resultados. Como uno de sus argumentos es a su vez una función, map es un ejemplo de manual de función de orden superior — igual que filter y fold por la misma razón.

¿Cuál es la diferencia entre una función de orden superior y una de primer orden?

Una función de primer orden solo recibe y devuelve valores ordinarios, como números o cadenas. Una función de orden superior recibe una o más funciones como argumento, o devuelve una función, o ambas. La diferencia está en si la función opera solo sobre datos o también sobre otras funciones.

¿Solo existen las funciones de orden superior en Haskell?

No. Existen en cualquier lenguaje que trate las funciones como valores de primera clase — valores que puedes guardar, pasar y devolver. Haskell, JavaScript, Python, Swift y muchos otros las admiten. Haskell hace la idea especialmente visible mediante sus firmas de tipo y el currying, pero el concepto está muy extendido.

Guía independiente, mantenida por la comunidad. coldwa.st es un sitio de recursos de programación; este artículo es un texto explicativo original e inédito sobre las funciones de orden superior. Las firmas y ejemplos de Haskell mostrados corresponden al comportamiento de la biblioteca estándar; consulta la documentación oficial para los tipos y casos límite exactos.
Recomendado

Una máquina Linux para compilar y ejecutar tu código Haskell

Probar estas funciones de orden superior de verdad — cargarlas en GHCi, compilar un proyecto con map y fold y luego ejecutarlo — es más cómodo en una máquina Linux real que en un portátil. Un servidor en la nube te da control total para instalar GHC y una cadena de herramientas de Haskell en un entorno limpio, al que llegas por SSH. Infomaniak — un proveedor suizo respetuoso con la privacidad — ofrece servidores en la nube para exactamente eso.

Ver Infomaniak Cloud →

Enlace de afiliado — ayuda a mantener estas guías gratuitas.

Explora más explicaciones claras en nuestro índice de guías.