2012-02-01 11 views

Respuesta

26

Bueno, fmap es solo (a -> b) -> f a -> f b, es decir, queremos transformar el resultado de la acción monádica con una función pura. Eso es fácil de escribir con la notación do:

fmap f m = do 
    a <- m 
    return (f a) 

o, por escrito "en bruto":

fmap f m = m >>= \a -> return (f a) 

Esto está disponible como Control.Monad.liftM.

pure :: a -> f a es por supuesto return. (<*>) :: f (a -> b) -> f a -> f b es un poco más complicado. Tenemos una acción que devuelve una función y una acción que devuelve su argumento, y queremos que una acción devuelva su resultado. En la notación do de nuevo:

mf <*> mx = do 
    f <- mf 
    x <- mx 
    return (f x) 

O Desazucarado:

mf <*> mx = 
    mf >>= \f -> 
    mx >>= \x -> 
    return (f x) 

Tada! Esto está disponible como Control.Monad.ap, por lo que puede dar una instancia completa de Functor y Applicative para cualquier mónada M de la siguiente manera:

instance Functor M where 
    fmap = liftM 

instance Applicative M where 
    pure = return 
    (<*>) = ap 

Idealmente, nos gustaría poder especificar estas implementaciones directamente en Monad, para aliviar la carga de definir instancias separadas para cada mónada, como con this proposal. Si eso sucede, no habrá ningún obstáculo real para hacer que Applicative sea una superclase de Monad, ya que garantizará que no rompa ningún código existente. Por otro lado, esto significa que la repetición implicada en la definición de instancias Functor y Applicative para un Monad dado es mínima, por lo que es fácil ser un "buen ciudadano" (y tales instancias deben definirse para cualquier mónada).

+5

Esta respuesta falta una pieza importante: prueba de que si una 'instancia' Monad 'dada' m' en verdad satisface las leyes Mónadas, entonces las definiciones monádicas que usted proporciona para 'fmap',' pure' y '(<*>)' obedezca el Functor y las leyes Aplicativas. Todo lo que Haskell impone es que los tipos lo comprueben. –

10

fmap = liftM y (<*>) = ap. Aquí hay enlaces al código fuente para liftM y ap. Supongo que sabes cómo desugar hacer notación.

Cuestiones relacionadas