Entschuldigung für lakonische und mechanische Antwort. Ich mag es nicht, Dinge wie Applicative oder Monad auszusuchen, aber ich weiß nicht, wo du bist. Dies ist not my usual approach to teaching Haskell.
Erstens, ap
ist wirklich (<*>)
unter der Haube.
Prelude> import Control.Monad
Prelude> import Data.Maybe
Prelude> import Control.Applicative
Prelude> :t ap
ap :: Monad m => m (a -> b) -> m a -> m b
Prelude> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Was bedeutet das? Es bedeutet, dass wir nicht etwas so "Starkes" wie Monad brauchen, um zu beschreiben, was wir tun. Anwendung reicht aus. Functor tut das aber nicht.
Prelude> :info Applicative
class Functor f => Applicative (f :: * -> *) where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Prelude> :info Functor
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
Hier ap
/(<*>)
mit dem Vielleicht Monad/Applicative:
Prelude> ap (Just (+1)) (Just 1)
Just 2
Prelude> (<*>) (Just (+1)) (Just 1)
Just 2
Das erste, was, um herauszufinden, welcher Instanz der Applicative typeclass reden wir?
Prelude> :t fromMaybe
fromMaybe :: a -> Maybe a -> a
Entzuckern fromMaybe der Typ etwas gibt uns:
(->) a (Maybe a -> a)
So ist der Typkonstruktor wir hier sind besorgt (->)
ist. Was sagt uns GHCi über (->)
, auch bekannt als Funktionstypen?
Prelude> :info (->)
data (->) a b -- Defined in ‘GHC.Prim’
instance Monad ((->) r) -- Defined in ‘GHC.Base’
instance Functor ((->) r) -- Defined in ‘GHC.Base’
instance Applicative ((->) a) -- Defined in ‘GHC.Base’
Hrm. Was ist mit Vielleicht?
Prelude> :info Maybe
data Maybe a = Nothing | Just a -- Defined in ‘GHC.Base’
instance Monad Maybe -- Defined in ‘GHC.Base’
instance Functor Maybe -- Defined in ‘GHC.Base’
instance Applicative Maybe -- Defined in ‘GHC.Base’
Was mit dem Einsatz von (<*>)
geschah Vielleicht war:
Prelude> (+1) 1
2
Prelude> (+1) `fmap` Just 1
Just 2
Prelude> Just (+1) <*> Just 1
Just 2
Prelude> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
Prelude> let mFmap = fmap :: (a -> b) -> Maybe a -> Maybe b
Prelude> (+1) `mFmap` Just 1
Just 2
Prelude> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Prelude> let mAp = (<*>) :: Maybe (a -> b) -> Maybe a -> Maybe b
Prelude> :t (+1)
(+1) :: Num a => a -> a
Prelude> :t Just (+1)
Just (+1) :: Num a => Maybe (a -> a)
Prelude> Just (+1) `mAp` Just 1
Just 2
Okay, was ist mit dem Functor und Applicative des Funktionstypen? Einer der kniffligen Teile hier ist, dass (->)
teilweise im Typ als ein Functor/Applicative/Monad angewendet werden muss. Ihr f
wird also (->) a
des gesamten (->) a b
, wobei a
ein Argumenttyp ist und b
das Ergebnis ist.
Prelude> (fmap (+1) (+2)) 0
3
Prelude> (fmap (+1) (+2)) 0
3
Prelude> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
Prelude> let funcMap = fmap :: (a -> b) -> (c -> a) -> c -> b
Prelude> -- f ~ (->) c
Prelude> (funcMap (+1) (+2)) 0
3
Prelude> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Prelude> let funcAp = (<*>) :: (c -> a -> b) -> (c -> a) -> (c -> b)
Prelude> :t fromMaybe
fromMaybe :: a -> Maybe a -> a
Prelude> :t funcAp fromMaybe
funcAp fromMaybe :: (b -> Maybe b) -> b -> b
Prelude> :t const
const :: a -> b -> a
Prelude> :t funcAp const
funcAp const :: (b -> b1) -> b -> b
Nicht garantiert, um nützlich zu sein. Sie können sagen, funcAp const
ist nicht nur von der Art interessant und wissen, wie parametrisch funktioniert.
Edit: Sprechen von komponieren, der Functor für (->) a
ist nur (.)
. Anwendbar ist das, aber mit einem zusätzlichen Argument. Monad ist der Applicative, aber mit Argumenten gewendet.
Weitere whattery: Applicative <*>
für (->) a
) ist S und pure
ist K der SKI Kombinator Kalkül. (Sie kann ich von K und S. ableiten Eigentlich können Sie jedes Programm aus K und S. ableiten)
Prelude> :t pure
pure :: Applicative f => a -> f a
Prelude> :t const
const :: a -> b -> a
Prelude> :t const
const :: a -> b -> a
Prelude> let k = pure :: a -> b -> a
Prelude> k 1 2
1
Prelude> const 1 2
1
Ich bin froh, dass Sie gefragt, weil dies mich auch verrückt machte x.x – dcastro
Übrigens ist "ap von Maybe" Code verschleiert, dass hoffentlich niemand jemals in einem echten Programm schreiben würde. –