|
| 1 | +module ComposingTypes.IntermissionExercises.Bifunctor where |
| 2 | + |
| 3 | +-- It’s a functor that can map over two type arguments instead of just one. |
| 4 | +class Bifunctor p where |
| 5 | + {-# MINIMAL bimap | first, second #-} |
| 6 | + bimap :: (a -> b) -> (c -> d) -> p a c -> p b d |
| 7 | + bimap f g = first f . second g |
| 8 | + |
| 9 | + first :: (a -> b) -> p a c -> p b c |
| 10 | + first f = bimap f id |
| 11 | + |
| 12 | + second :: (b -> c) -> p a b -> p a c |
| 13 | + second = bimap id |
| 14 | + |
| 15 | + |
| 16 | +-- Question 1 |
| 17 | +data Deux a b = Deux a b |
| 18 | + |
| 19 | +instance Bifunctor Deux where |
| 20 | + bimap f g (Deux a b) = Deux (f a) (g b) |
| 21 | + |
| 22 | +-- Question 2 |
| 23 | +data Const a b = Const a |
| 24 | + |
| 25 | +instance Bifunctor Const where |
| 26 | + bimap f _ (Const a) = Const (f a) |
| 27 | + |
| 28 | +-- Question 3 |
| 29 | +data Drei a b c = Drei a b c |
| 30 | + |
| 31 | +instance Bifunctor (Drei a) where |
| 32 | + bimap f g (Drei a b c) = Drei a (f b) (g c) |
| 33 | + |
| 34 | +-- Question 4 |
| 35 | +data SuperDrei a b c = SuperDrei a b |
| 36 | + |
| 37 | +instance Bifunctor (SuperDrei a) where |
| 38 | + bimap f _ (SuperDrei a b) = SuperDrei a (f b) |
| 39 | + |
| 40 | +-- Question 5 |
| 41 | +data SemiDrei a b c = SemiDrei a |
| 42 | + |
| 43 | +instance Bifunctor (SemiDrei a) where |
| 44 | + bimap _ _ (SemiDrei a) = SemiDrei a |
| 45 | + |
| 46 | +-- Question 6 |
| 47 | +data Quadriceps a b c d = Quadzzz a b c d |
| 48 | + |
| 49 | +instance Bifunctor (Quadriceps a b) where |
| 50 | + bimap f g (Quadzzz a b c d) = Quadzzz a b (f c) (g d) |
| 51 | + |
| 52 | +-- Question 7 |
| 53 | +data Either' a b = Left' a | Right' b |
| 54 | + |
| 55 | +instance Bifunctor Either' where |
| 56 | + bimap f _ (Left' a) = Left' $ f a |
| 57 | + bimap _ g (Right' b) = Right' $ g b |
0 commit comments