En este módulo, exploraremos dos conceptos fundamentales en Haskell: Functor y Foldable. Ambos son clases de tipos que proporcionan abstracciones poderosas para trabajar con estructuras de datos de manera funcional.

Functor

¿Qué es un Functor?

Un Functor es una clase de tipos que representa estructuras de datos que pueden ser mapeadas. En otras palabras, un Functor es algo en lo que puedes aplicar una función a cada elemento dentro de la estructura sin cambiar la estructura en sí.

Definición de la Clase Functor

La clase Functor se define en el módulo Prelude de Haskell de la siguiente manera:

class Functor f where
    fmap :: (a -> b) -> f a -> f b
  • fmap es una función que toma una función (a -> b) y un Functor que contiene elementos de tipo a (f a), y devuelve un Functor que contiene elementos de tipo b (f b).

Ejemplo de Functor: Lista

Las listas en Haskell son instancias de Functor. Aquí hay un ejemplo de cómo usar fmap con listas:

-- Definimos una función que incrementa un número en 1
increment :: Int -> Int
increment x = x + 1

-- Usamos fmap para aplicar 'increment' a cada elemento de la lista
result :: [Int]
result = fmap increment [1, 2, 3, 4]

-- El resultado será [2, 3, 4, 5]

Ejemplo de Functor: Maybe

El tipo Maybe también es una instancia de Functor:

-- Definimos una función que convierte un número a su representación en cadena
toString :: Int -> String
toString x = show x

-- Usamos fmap para aplicar 'toString' a un valor de tipo Maybe
resultMaybe :: Maybe String
resultMaybe = fmap toString (Just 123)

-- El resultado será Just "123"

Ejercicio Práctico

Ejercicio: Define una instancia de Functor para un tipo de datos personalizado Box.

data Box a = Box a deriving (Show)

instance Functor Box where
    fmap f (Box x) = Box (f x)

-- Prueba tu instancia de Functor
main :: IO ()
main = do
    let box = Box 10
    print $ fmap (*2) box  -- Debería imprimir "Box 20"

Foldable

¿Qué es Foldable?

Foldable es una clase de tipos que representa estructuras de datos que pueden ser "plegadas" (folded). Plegar una estructura de datos significa reducirla a un solo valor mediante la aplicación repetida de una función.

Definición de la Clase Foldable

La clase Foldable se define en el módulo Prelude de Haskell de la siguiente manera:

class Foldable t where
    foldr :: (a -> b -> b) -> b -> t a -> b
  • foldr es una función que toma una función binaria (a -> b -> b), un valor inicial de tipo b, y una estructura de datos de tipo t a, y devuelve un valor de tipo b.

Ejemplo de Foldable: Lista

Las listas en Haskell son instancias de Foldable. Aquí hay un ejemplo de cómo usar foldr con listas:

-- Definimos una función que suma dos números
add :: Int -> Int -> Int
add x y = x + y

-- Usamos foldr para sumar todos los elementos de la lista
sumList :: [Int] -> Int
sumList = foldr add 0

-- El resultado de sumList [1, 2, 3, 4] será 10

Ejemplo de Foldable: Maybe

El tipo Maybe también es una instancia de Foldable:

-- Usamos foldr para sumar el valor de un Maybe con un valor inicial
sumMaybe :: Maybe Int -> Int
sumMaybe = foldr (+) 0

-- El resultado de sumMaybe (Just 5) será 5
-- El resultado de sumMaybe Nothing será 0

Ejercicio Práctico

Ejercicio: Define una instancia de Foldable para un tipo de datos personalizado Box.

data Box a = Box a deriving (Show)

instance Foldable Box where
    foldr f z (Box x) = f x z

-- Prueba tu instancia de Foldable
main :: IO ()
main = do
    let box = Box 10
    print $ foldr (+) 5 box  -- Debería imprimir "15"

Resumen

En esta sección, hemos aprendido sobre las clases de tipos Functor y Foldable en Haskell. Los Functor nos permiten aplicar funciones a cada elemento dentro de una estructura de datos, mientras que los Foldable nos permiten reducir una estructura de datos a un solo valor mediante la aplicación repetida de una función. Hemos visto ejemplos prácticos y ejercicios para reforzar estos conceptos.

En el próximo módulo, exploraremos el concepto de Mónadas, que es una extensión poderosa de los Functor y Foldable.

© Copyright 2024. Todos los derechos reservados