|
| 1 | +module Ch12 where |
| 2 | + |
| 3 | +import System.Directory.Internal.Prelude (Functor) |
| 4 | +import GHC.HsToCore.Monad (Applicative) |
| 5 | + |
| 6 | +-- 1. Define an instance of the Functor class for the following type of binary trees that |
| 7 | +-- have data in their nodes: |
| 8 | +data Tree a = Leaf | Node (Tree a) a (Tree a) |
| 9 | + deriving Show |
| 10 | + |
| 11 | +instance Functor Tree where |
| 12 | + fmap _ Leaf = Leaf |
| 13 | + fmap g (Node l v r) = Node (fmap g l) (g v) (fmap g r) |
| 14 | + |
| 15 | +-- 2. Complete the following instance declaration to make the partially-applied function |
| 16 | +-- type (a ->) into a functor: |
| 17 | +-- instance Functor ((->) a) where |
| 18 | +-- fmap = (.) |
| 19 | + |
| 20 | +-- 3. Define an instance of the Applicative class for the type ((->) a). |
| 21 | +-- instance Applicative ((->) a) where |
| 22 | +-- pure = const |
| 23 | +-- g <*> h = \ x -> g x (h x) |
| 24 | + |
| 25 | +-- 4. There may be more than one way to make a parameterised type into an applicative |
| 26 | +-- functor. For example, the library Control.Applicative provides an alternative |
| 27 | +-- 'zippy' instance for lists, in which the function pure makes an infinite list of |
| 28 | +-- copies of its argument, and the operator <*> applies each argument function to the |
| 29 | +-- corresponding argument value at the same position. Complete the following |
| 30 | +-- declarations that implement this idea: |
| 31 | +newtype ZipList a = Z [a] deriving Show |
| 32 | + |
| 33 | +instance Functor ZipList where |
| 34 | + -- fmap :: (a -> b) -> ZipList a -> ZipList b |
| 35 | + fmap g (Z xs) = Z (fmap g xs) |
| 36 | + |
| 37 | +instance Applicative ZipList where |
| 38 | + -- pure :: a -> ZipList a |
| 39 | + pure x = Z (repeat x) |
| 40 | + -- <*> :: ZipList (a -> b) -> ZipList a -> ZipList b |
| 41 | + (Z gs) <*> (Z xs) = Z [g x | (g,x) <- zip gs xs] |
| 42 | + |
| 43 | +-- 5. Work out the types for the variables in the four applicative laws. |
| 44 | +-- pure id <*> x = x :: Applicative f => f b -> f b |
| 45 | +-- pure (g x) = pure g <*> pure x :: Applicative f => (t -> a) -> t -> f a |
| 46 | +-- x <*> pure y = pure (\g -> g y) <*> x :: Applicative f => f (a -> b) -> a -> f b |
| 47 | +-- x <*> (y <*> z) = (pure (.) <*> x <*> y) <*> z :: Applicative f => f (a1 -> b) -> f (a2 -> a1) -> f a2 -> f b |
| 48 | + |
| 49 | +-- 6. Define an instance of the Monad class for the type (a ->). |
| 50 | +-- instance Monad ((->) a) where |
| 51 | +-- return = const |
| 52 | +-- (>>=) f g r = g (f r) r |
0 commit comments