Code
haskell
-- 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)