]> git.rkrishnan.org Git - yorgey.git/blob - misc/applicatives.hs
hw12: exercise 4
[yorgey.git] / misc / applicatives.hs
1 import Control.Applicative
2
3 liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
4 liftA2 h fa fb = (h `fmap` fa) <*> fb
5
6 -- In fact, this pattern is so common that Control.Applicative defines (<$>) as a synonym for fmap,
7
8 (<$>) :: Functor f => (a -> b) -> f a -> f b
9 (<$>) = fmap
10
11 liftA2 h fa fb = h <$> fa <*> fb
12
13 {-|
14
15 h -> (a -> b -> c)
16
17 -- (a -> b -> c) -> f a -> f (b -> c)
18 h <$> fa = hfa
19
20 -- (<*>) :: f (a -> b) -> f a -> f b
21 -- hfa <*> f b
22 -- f (b -> c) -> f b -> f c
23
24 -- Applicative law
25 -- f `fmap` x === pure f <*> x
26
27 -- lhs = (a -> b) `fmap` f a gives a value of type f b
28 -- rhs = pure f.
29 --     f  has the type (a -> b), so pure f has the type f (a -> b)
30 --   pure f <*> x => f (a -> b> <*> f a => f b
31
32 -}
33
34 type Name = String
35
36 data Employee = Employee { name :: Name
37                          , phone :: String }
38                 deriving Show
39
40 newtype ZipList a = ZipList { getZipList :: [a] }
41     deriving (Eq, Show, Functor)
42
43 instance Applicative ZipList where
44   pure = ZipList . repeat
45   ZipList fs <*> ZipList xs = ZipList (zipWith ($) fs xs)
46
47 instance Applicative ((->) e) where
48   -- pure :: a -> ((->) e a)
49   --       = a -> (e -> a)
50     pure = const
51 -- f <*> x
52 -- (e -> (a -> b)) <*> (e -> a) -> (e -> b)
53     f <*> x = \e -> (f e) (x e)