--- /dev/null
+liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
+liftA2 h fa fb = (h `fmap` fa) <*> fb
+
+-- In fact, this pattern is so common that Control.Applicative defines (<$>) as a synonym for fmap,
+
+(<$>) :: Functor f => (a -> b) -> f a -> f b
+(<$>) = fmap
+
+liftA2 h fa fb = h <$> fa <*> fb
+
+{-|
+
+h -> (a -> b -> c)
+
+-- (a -> b -> c) -> f a -> f (b -> c)
+h <$> fa = hfa
+
+-- (<*>) :: f (a -> b) -> f a -> f b
+-- hfa <*> f b
+-- f (b -> c) -> f b -> f c
+
+-- Applicative law
+-- f `fmap` x === pure f <*> x
+
+-- lhs = (a -> b) `fmap` f a gives a value of type f b
+-- rhs = pure f.
+-- f has the type (a -> b), so pure f has the type f (a -> b)
+-- pure f <*> x => f (a -> b> <*> f a => f b
+
+-}
\ No newline at end of file