Skip to content

Instantly share code, notes, and snippets.

@rajasharan
Last active October 11, 2017 03:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rajasharan/c85b6d37fea0ae5fc3a12f214405bedb to your computer and use it in GitHub Desktop.
Save rajasharan/c85b6d37fea0ae5fc3a12f214405bedb to your computer and use it in GitHub Desktop.
Intuition for Applicatives (<$>)

Intuition for Applicatives

Consider below program for sequencing commands

sequence : [IO a] -> IO [a]
sequence [] = return []
sequence (c:cs) = do
  x  <- c
  xs <- cs
  return (x:xs)

All we wanted to do was apply a pure function (:) to simple values like x & xs which were trapped under a command/monad.

Introducing ap:

ap: m (a -> b) -> m a -> m b
ap cf cx = do
  f <- cf
  x <- cx
  return f x

Now,

sequence (c: cs) = return (:) `ap` c `ap` (sequence cs)

or replace return with pure and ap with <$>

sequence (c: cs) = pure (:) <$> c <$> (sequence cs)

Furthermore, replace: pure f <$> u1 <$> u2 ... with: | f u1 u2 ... | (syntactic replacement with | ... |)

And so,

sequence (c:cs) = | (:) c (sequence cs) |

See how result follows input form!!!

Another,

add : Expr -> Expr -> Expr
add expr1 expr2 = | (+) expr1 expr2 |

-- where Expr = ... some monadic expression like (Val Int | Add Expr Expr)

again see how result follows input form!!!

All of this being syntactic by replacing:

pure f <$> u1 <$> u2 ...

with:

| f u1 u2 ... |

back to original form:

sequence (c:cs) = pure (:) <$> c <$> (sequence cs)

add expr1 expr1 = pure (+) expr1 <$> expr2

Inspiration

Further Reading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment