yourself you monad learn data haskell functor applicative

data - monads learn you a haskell



¿Para qué sirve el funtor aplicativo ''Const''? (4)

Acabo de encontrar a Const en la documentación de Control.Applicative , pero me resulta difícil calcular dónde es útil, simplemente usando Monoid directamente.

¿Qué me estoy perdiendo?


Como menciona dave4420, la implementación de accesores y actualizadores para lentes Van Laarhoven involucra el functor Const . Elaborar:

{-# LANGUAGE Rank2Types #-} import Control.Applicative import Control.Monad.Identity -- The definition of Van Laarhoven lenses: type Lens a b = forall f . Functor f => (b -> f b) -> (a -> f a) -- Getter passes the Const functor to the lens: get :: Lens a b -> a -> b get l = getConst . (l Const) -- Updater passes the Identity functor to the lens: modify :: Lens a b -> (b -> b) -> (a -> a) modify l f = runIdentity . l (Identity . f) set :: Lens a b -> b -> (a -> a) set l r = modify l (const r) -- Example: ------------------------------------------- data Person = Person { _name :: String, _age :: Int } deriving Show name :: Lens Person String name f (Person n a) = fmap (/x -> Person x a) (f n) age :: Lens Person Int age f (Person n a) = fmap (/x -> Person n x) (f a) main :: IO () main = do let john = Person "John" 34 print $ get age john print $ set name "Pete" john



Es útil cuando tiene una función o estructura de datos que funciona para todos los Functor ( Applicative ) y desea reutilizarla en un sentido degenerado. Es análogo a pasar const o id a funciones que funcionan dadas funciones arbitrarias.

Las lentes Van Laarhoven se definen en términos de Functors arbitrarios, y usan Const para derivar un elemento de acceso a campo (y la Identity igualmente trivial para derivar un actualizador de campo).

Traversable tipos transitables, como lo menciona el trabajador porcino, son otro ejemplo de esto.


Es bastante útil cuando se combina con Traversable .

getConst . traverse Const :: (Monoid a, Traversable f) => f a -> a

Esa es la receta general para juntar un montón de cosas juntas. Fue uno de los casos de uso que me convenció de que valía la pena separar Applicative de Monad . Necesitaba cosas como elem generalizado

elem :: Eq x => x -> Term x -> Bool

para realizar la comprobación de ocurrencia de un Traversable Term parametrizado por la representación de variables libres. Seguí cambiando la representación de Term y estaba harto de modificar un millón de funciones transversales, algunas de las cuales estaban haciendo acumulaciones, en lugar de mapas efectivos. Me alegré de encontrar una abstracción que cubría ambos.