diff --git a/src/Chapter4.hs b/src/Chapter4.hs index 20532222..ea76a0af 100644 --- a/src/Chapter4.hs +++ b/src/Chapter4.hs @@ -115,22 +115,38 @@ the output in here: >>> :k Char +Char :: * + >>> :k Bool +Bool :: * + >>> :k [Int] +[Int] :: * + >>> :k [] +[] :: * -> * + >>> :k (->) +(->) :: * -> * -> * + >>> :k Either +Either :: * -> * -> * + >>> data Trinity a b c = MkTrinity a b c >>> :k Trinity +Trinity :: * -> * -> * -> * + >>> data IntBox f = MkIntBox (f Int) >>> :k IntBox +IntBox :: (* -> *) -> * + -} {- | @@ -293,7 +309,8 @@ values and apply them to the type level? -} instance Functor (Secret e) where fmap :: (a -> b) -> Secret e a -> Secret e b - fmap = error "fmap for Box: not implemented!" + fmap _ (Trap a) = Trap a + fmap f (Reward a) = Reward(f a) {- | =⚔️= Task 3 @@ -307,6 +324,12 @@ data List a = Empty | Cons a (List a) +instance Functor List where + fmap :: (a->b) -> List a -> List b + fmap _ Empty = Empty + fmap f (Cons x xs) = Cons (f x) (fmap f xs) + + {- | =🛡= Applicative @@ -472,10 +495,12 @@ Implement the Applicative instance for our 'Secret' data type from before. -} instance Applicative (Secret e) where pure :: a -> Secret e a - pure = error "pure Secret: Not implemented!" + pure = Reward (<*>) :: Secret e (a -> b) -> Secret e a -> Secret e b - (<*>) = error "(<*>) Secret: Not implemented!" + Reward f <*> a = fmap f a + Trap e <*> _ = Trap e + {- | =⚔️= Task 5 @@ -488,6 +513,18 @@ Implement the 'Applicative' instance for our 'List' type. may also need to implement a few useful helper functions for our List type. -} +join :: List a -> List a -> List a +join Empty l = l +join (Cons x xs) l = Cons x (join xs l) + +instance Applicative List where + pure :: a -> List a + pure x = Cons x Empty + + (<*>) :: List (a->b) -> List a -> List b + Empty <*> _ =Empty + _ <*> Empty = Empty + Cons x xs <*> l = join (fmap x l) (xs <*> l) {- | @@ -600,7 +637,8 @@ Implement the 'Monad' instance for our 'Secret' type. -} instance Monad (Secret e) where (>>=) :: Secret e a -> (a -> Secret e b) -> Secret e b - (>>=) = error "bind Secret: Not implemented!" + Trap e >>= _ = Trap e + Reward x >>= f = f x {- | =⚔️= Task 7 @@ -609,8 +647,21 @@ Implement the 'Monad' instance for our lists. 🕯 HINT: You probably will need to implement a helper function (or maybe a few) to flatten lists of lists to a single list. + + data List a + = Empty + | Cons a (List a) -} +flatten :: List(List a) -> List a +flatten Empty = Empty +flatten (Cons x xs) = join x (flatten xs) + +instance Monad List where + (>>=) :: List a -> (a -> List b) -> List b + l >>= f = flatten (fmap f l) + + {- | =💣= Task 8*: Before the Final Boss @@ -629,7 +680,7 @@ Can you implement a monad version of AND, polymorphic over any monad? 🕯 HINT: Use "(>>=)", "pure" and anonymous function -} andM :: (Monad m) => m Bool -> m Bool -> m Bool -andM = error "andM: Not implemented!" +andM a b = a >>= \f -> if f then b else pure False {- | =🐉= Task 9*: Final Dungeon Boss @@ -673,6 +724,19 @@ Specifically, ❃ Implement the function to convert Tree to list -} +data Tree a = Leaf | Node a (Tree a) (Tree a) +instance Functor Tree where + fmap :: (a -> b) -> Tree a -> Tree b + fmap _ Leaf = Leaf + fmap f (Node a l r) = Node (f a) (fmap f l) (fmap f r) + +revTree :: Tree a -> Tree a +revTree Leaf = Leaf +revTree (Node a l r) = Node a (revTree r) (revTree l) + +listTree :: Tree a -> List a +listTree Leaf= [] +listTree (Node a l r) = a : (listTree l) ++ (listTree r) {- You did it! Now it is time to open pull request with your changes