Haskell - Functor
Functoren Haskell hay una especie de representación funcional de diferentes tipos que se pueden mapear. Es un concepto de alto nivel de implementación de polimorfismo. Según los desarrolladores de Haskell, todos los tipos, como Lista, Mapa, Árbol, etc., son la instancia del Functor Haskell.
UN Functor es una clase incorporada con una definición de función como -
class Functor f where
fmap :: (a -> b) -> f a -> f b
Por esta definición, podemos concluir que el Functor es una función que toma una función, digamos, fmap()y devuelve otra función. En el ejemplo anterior,fmap() es una representación generalizada de la función map().
En el siguiente ejemplo, veremos cómo funciona Haskell Functor.
main = do
print(map (subtract 1) [2,4,8,16])
print(fmap (subtract 1) [2,4,8,16])
Aquí, hemos usado ambos map() y fmap()sobre una lista para una operación de resta. Puede observar que ambas declaraciones producirán el mismo resultado de una lista que contiene los elementos [1,3,7,15].
Ambas funciones llamadas otra función llamada subtract() para producir el resultado.
[1,3,7,15]
[1,3,7,15]
Entonces, ¿cuál es la diferencia entre map y fmap? La diferencia radica en su uso. Functor nos permite implementar algunos funcionalistas más en diferentes tipos de datos, como "solo" y "Nada".
main = do
print (fmap (+7)(Just 10))
print (fmap (+7) Nothing)
El código anterior producirá el siguiente resultado en el terminal:
Just 17
Nothing
Functor aplicativo
Un Applicative Functor es un Functor normal con algunas características adicionales proporcionadas por la clase de tipo Applicative.
Usando Functor, generalmente mapeamos una función existente con otra función definida dentro de ella. Pero no hay forma de mapear una función que está definida dentro de un Functor con otro Functor. Por eso tenemos otra instalación llamadaApplicative Functor. Esta facilidad de mapeo es implementada por la clase de Tipo Aplicativo definida bajo laControlmódulo. Esta clase nos da solo dos métodos para trabajar: uno espure y el otro es <*>.
A continuación se muestra la definición de clase del Functor Aplicativo.
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Según la implementación, podemos mapear otro Functor usando dos métodos: "Pure" y "<*>". El método "puro" debe tomar un valor de cualquier tipo y siempre devolverá un Functor Aplicativo de ese valor.
El siguiente ejemplo muestra cómo funciona un aplicativo Functor:
import Control.Applicative
f1:: Int -> Int -> Int
f1 x y = 2*x+y
main = do
print(show $ f1 <$> (Just 1) <*> (Just 2) )
Aquí, hemos implementado functores aplicativos en la llamada de función de la función f1. Nuestro programa producirá el siguiente resultado.
"Just 4"
Monoides
Todos sabemos que Haskell define todo en forma de funciones. En funciones, tenemos opciones para obtener nuestra entrada como salida de la función. Esto es lo queMonoid es.
UN Monoides un conjunto de funciones y operadores donde la salida es independiente de su entrada. Tomemos una función (*) y un número entero (1). Ahora, cualquiera que sea la entrada, su salida seguirá siendo el mismo número solamente. Es decir, si multiplicas un número por 1, obtendrás el mismo número.
Aquí hay una definición de clase de tipo de monoide.
class Monoid m where
mempty :: m
mappend :: m -> m -> m
mconcat :: [m] -> m
mconcat = foldr mappend mempty
Eche un vistazo al siguiente ejemplo para comprender el uso de Monoid en Haskell.
multi:: Int->Int
multi x = x * 1
add :: Int->Int
add x = x + 0
main = do
print(multi 9)
print (add 7)
Nuestro código producirá el siguiente resultado:
9
7
Aquí, la función "multi" multiplica la entrada por "1". De manera similar, la función "agregar" agrega la entrada con "0". En ambos casos, la salida será la misma que la entrada. Por tanto, las funciones{(*),1} y {(+),0} son los ejemplos perfectos de monoides.