Skip to content
Haskell

Applicative Functors

Apply functions in a context with less power than Monad.

By EZ4Code Team
applicativevalidation

Code

-- Applicative style: multi-arg functions in a context
-- <$> = fmap, <*> = apply
(+) <$> Just 3 <*> Just 5    -- Just 8
(+) <$> Nothing <*> Just 5   -- Nothing

-- Three arguments
(\x y z -> x * y + z) <$> Just 2 <*> Just 3 <*> Just 4  -- Just 10

-- List (non-deterministic computation)
(+) <$> [1,2] <*> [10,20]    -- [11,21,12,22]

-- Parser combinators (a classic use)
-- A parser is a function: String -> [(a, String)]
type Parser a = String -> [(a, String)]

-- With Applicative:
-- parsePair = (,) <$> parseDigit <*> parseDigit
-- parses "12" => [((1,2), "")]

-- Validation (collect all errors)
data Validation e a = Failure [e] | Success a
instance Applicative (Validation e) where
  pure = Success
  Failure e1 <*> Failure e2 = Failure (e1 ++ e2)  -- accumulates!
  Failure e  <*> _          = Failure e
  _          <*> Failure e  = Failure e
  Success f  <*> Success x  = Success (f x)

Explanation

Applicative sits between Functor and Monad — less powerful but more parallelizable. Use it when computations don't depend on each other's results (unlike Monad). Classic uses: parser combinators, form validation (collect all errors), configuration building. <$> is fmap (apply pure function); <*> applies wrapped function. Validation's (<*>) accumulates errors, unlike Maybe which short-circuits.

More Haskell Snippets