From a1c0b90438c336716f44e53472ee0c185514a215 Mon Sep 17 00:00:00 2001
From: Ramakrishnan Muthukrishnan <ram@rkrishnan.org>
Date: Sun, 28 Dec 2014 11:01:01 +0530
Subject: [PATCH] more notes from week11 lecture notes

---
 misc/applicatives.hs  | 25 ++++++++++++++++++++++-
 misc/applicatives2.hs | 46 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 1 deletion(-)
 create mode 100644 misc/applicatives2.hs

diff --git a/misc/applicatives.hs b/misc/applicatives.hs
index abf9231..bdada3b 100644
--- a/misc/applicatives.hs
+++ b/misc/applicatives.hs
@@ -1,3 +1,5 @@
+import Control.Applicative
+
 liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
 liftA2 h fa fb = (h `fmap` fa) <*> fb
 
@@ -27,4 +29,25 @@ h <$> fa = hfa
 --     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
+-}
+
+type Name = String
+
+data Employee = Employee { name :: Name
+                         , phone :: String }
+                deriving Show
+
+newtype ZipList a = ZipList { getZipList :: [a] }
+    deriving (Eq, Show, Functor)
+
+instance Applicative ZipList where
+  pure = ZipList . repeat
+  ZipList fs <*> ZipList xs = ZipList (zipWith ($) fs xs)
+
+instance Applicative ((->) e) where
+  -- pure :: a -> ((->) e a)
+  --       = a -> (e -> a)
+    pure = const
+-- f <*> x
+-- (e -> (a -> b)) <*> (e -> a) -> (e -> b)
+    f <*> x = \e -> (f e) (x e)
diff --git a/misc/applicatives2.hs b/misc/applicatives2.hs
new file mode 100644
index 0000000..3cbfad3
--- /dev/null
+++ b/misc/applicatives2.hs
@@ -0,0 +1,46 @@
+module Apexamples where
+
+import Control.Applicative
+
+pair :: Applicative f => f a -> f b -> f (a,b)
+-- pair fa fb = (\x y -> (x,y)) <$> fa <*> fb
+-- pair fa fb = (,) <$> fa <*> fb
+-- pair fa fb = liftA2 (,) fa fb
+pair = liftA2 (,)
+
+
+{-| Can you implement the following functions?
+
+Consider what each function does when f is replaced with each of the types:
+
+
+f = Maybe: the result is Nothing if either of the arguments is; if both are
+           Just the result is Just their pairing.
+f = []: pair computes the Cartesian product of two lists.
+f = ZipList: pair is the same as the standard zip function.
+f = IO: pair runs two IO actions in sequence, returning a pair of their results.
+f = Parser: pair runs two parsers in sequence (the parsers consume consecutive
+    sections of the input), returning their results as a pair. If either parser fails, the whole thing fails.
+
+
+(*>)       :: Applicative f => f a -> f b -> f b
+mapA       :: Applicative f => (a -> f b) -> ([a] -> f [b])
+sequenceA  :: Applicative f => [f a] -> f [a]
+replicateA :: Applicative f => Int -> f a -> f [a]
+
+-}
+
+(*>)       :: Applicative f => f a -> f b -> f b
+fa *> fb = (flip const) <$> fa <*> fb
+
+mapA       :: Applicative f => (a -> f b) -> ([a] -> f [b])
+mapA _ [] = pure []
+mapA f' (x:xs) = liftA2 (:) (f' x) $ mapA f' xs
+
+sequenceA  :: Applicative f => [f a] -> f [a]
+sequenceA [] = pure []
+sequenceA (x:xs) = (:) <$> x <*> sequenceA xs
+-- sequenceA (x:xs) = liftA2 (:) x (sequenceA xs)
+
+replicateA :: Applicative f => Int -> f a -> f [a]
+replicateA n x = sequenceA (replicate n x)
-- 
2.45.2