Applies a wrapped (lifted) function to a wrapped (lifted) value.
Only implementation of
<*> for each particular instance knows how to reach inside a wrapped value.
To be an Applicative is to have a
<*> function implemented.
<* are for convenience.
class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b (<*>) = liftA2 id liftA2 :: (a -> b -> c) -> f a -> f b -> f c liftA2 f x = (<*>) (fmap f x) (*>) :: f a -> f b -> f b a1 *> a2 = (id <$ a1) <*> a2 (<*) :: f a -> f b -> f a (<*) = liftA2 const
liftA :: Applicative f => (a -> b) -> f a -> f b liftA f a = pure f <*> a
which is another name for
fmap :: (a -> b) -> f a -> f b
The whole thing is about generalizing application to Tuples
((,)) or abstracting out Set Multiplication.
instance Monoid a => Applicative ((,) a) where pure x = (mempty, x) (u, f) <*> (v, x) = (u <> v, f x) liftA2 f (u, x) (v, y) = (u <> v, f x y)
instance Monoid a => Monad ((,) a) where (u, a) >>= k = case k a of (v, b) -> (u <> v, b)