Complete Chapter 21

master
Gaël Depreeuw 7 years ago
parent ef86ec4a73
commit 44e1748264
  1. 2
      21-traversable/21.12-chapter-exercises.md
  2. 196
      21-traversable/src/chapter.hs

@ -0,0 +1,2 @@
# Chapter Exercises
see src/chapter.hs

@ -0,0 +1,196 @@
{-# LANGUAGE FlexibleContexts #-}
module Chapter where
import Data.Monoid ((<>))
import Test.QuickCheck
import Test.QuickCheck.Checkers
import Test.QuickCheck.Classes
-- fmap :: Functor f => (a -> b) -> f a -> f b
-- foldMap :: (Monoid m, Foldable t) => (a -> m) -> t a -> m
-- traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
-- Identity
newtype Identity a = Identity a deriving (Eq, Ord, Show)
instance Functor Identity where
fmap f (Identity a) = Identity $ f a
instance Foldable Identity where
foldMap f (Identity a) = f a
instance Traversable Identity where
traverse f (Identity a) = Identity <$> f a
instance Arbitrary a => Arbitrary (Identity a) where
arbitrary = Identity <$> arbitrary
instance (Eq a) => EqProp (Identity a) where (=-=) = eq
-- Constant
newtype Constant a b = Constant { getConstant :: a } deriving (Eq, Show)
instance Functor (Constant a) where
fmap _ (Constant a) = Constant a
instance Foldable (Constant a) where
foldMap _ _ = mempty
instance Traversable (Constant a) where
traverse _ (Constant a) = Constant <$> pure a
instance Arbitrary a => Arbitrary (Constant a b) where
arbitrary = Constant <$> arbitrary
instance Eq a => EqProp (Constant a b) where (=-=) = eq
-- Maybe
data Optional a = Nada | Yep a deriving (Eq, Show)
instance Functor Optional where
fmap _ Nada = Nada
fmap f (Yep a) = Yep $ f a
instance Foldable Optional where
foldMap _ Nada = mempty
foldMap f (Yep a) = f a
instance Traversable Optional where
traverse _ Nada = pure Nada
traverse f (Yep a) = Yep <$> f a
instance Arbitrary a => Arbitrary (Optional a) where
arbitrary = do
a <- arbitrary
frequency [(1, return Nada),(3, return $ Yep a)]
instance Eq a => EqProp (Optional a) where (=-=) = eq
-- List
data List a = Nil | Cons a (List a) deriving (Eq, Show)
instance Functor List where
fmap _ Nil = Nil
fmap f (Cons a l) = Cons (f a) (fmap f l)
instance Foldable List where
foldMap _ Nil = mempty
foldMap f (Cons a l) = f a <> foldMap f l
instance Traversable List where
traverse _ Nil = pure Nil
traverse f (Cons a l) = Cons <$> f a <*> traverse f l
toList :: [a] -> List a
toList [] = Nil
toList (a:l) = Cons a (toList l)
instance Arbitrary a => Arbitrary (List a) where
arbitrary = toList <$> listOf arbitrary
instance Eq a => EqProp (List a) where (=-=) = eq
-- Three
data Three a b c = Three a b c deriving (Eq, Show)
instance Functor (Three a b) where
fmap f (Three a b c) = Three a b $ f c
instance Foldable (Three a b) where
foldMap f (Three _ _ c) = f c
instance Traversable (Three a b) where
traverse f (Three a b c) = Three a b <$> f c
instance (Arbitrary a, Arbitrary b, Arbitrary c) =>
Arbitrary (Three a b c) where
arbitrary = Three <$> arbitrary <*> arbitrary <*> arbitrary
instance (Eq a, Eq b, Eq c) => EqProp (Three a b c) where (=-=) = eq
-- Pair
data Pair a b = Pair a b deriving (Eq, Show)
instance Functor (Pair a) where
fmap f (Pair a b) = Pair a $ f b
instance Foldable (Pair a) where
foldMap f (Pair _ b) = f b
instance Traversable (Pair a) where
traverse f (Pair a b) = Pair a <$> f b
instance (Arbitrary a, Arbitrary b) => Arbitrary (Pair a b) where
arbitrary = Pair <$> arbitrary <*> arbitrary
instance (Eq a, Eq b) => EqProp (Pair a b) where (=-=) = eq
-- Big
data Big a b = Big a b b deriving (Eq, Show)
instance Functor (Big a) where
fmap f (Big a b b') = Big a (f b) (f b')
instance Foldable (Big a) where
foldMap f (Big _ b b') = f b <> f b'
instance Traversable (Big a) where
traverse f (Big a b b') = Big a <$> f b <*> f b'
instance (Arbitrary a, Arbitrary b) => Arbitrary (Big a b) where
arbitrary = Big <$> arbitrary <*> arbitrary <*> arbitrary
instance (Eq a, Eq b) => EqProp (Big a b) where (=-=) = eq
-- Bigger
data Bigger a b = Bigger a b b b deriving (Eq, Show)
instance Functor (Bigger a) where
fmap f (Bigger a b b' b'') = Bigger a (f b) (f b') (f b'')
instance Foldable (Bigger a) where
foldMap f (Bigger _ b b' b'') = f b <> f b' <> f b''
instance Traversable (Bigger a) where
traverse f (Bigger a b b' b'') = Bigger a <$> f b <*> f b' <*> f b''
instance (Arbitrary a, Arbitrary b) => Arbitrary (Bigger a b) where
arbitrary = Bigger <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
instance (Eq a, Eq b) => EqProp (Bigger a b) where (=-=) = eq
-- S
data S n a = S (n a) a deriving (Eq, Show)
instance Functor n => Functor (S n) where
fmap f (S n a) = S (fmap f n) (f a)
instance Foldable n => Foldable (S n) where
foldMap f (S n a) = foldMap f n <> f a
instance Traversable n => Traversable (S n) where
traverse f (S n a) = S <$> traverse f n <*> f a
instance (Functor n, Arbitrary (n a), Arbitrary a) => Arbitrary (S n a) where
arbitrary = S <$> arbitrary <*> arbitrary
-- The EqProp instance from the book fails. No idea why, the logic seems
-- sound?
-- instance (Applicative n, Testable (n Property), EqProp a) =>
-- EqProp (S n a) where
-- (S x y) =-= (S p q) = (property $ (=-=) <$> x <*> p) .&. (y =-= q)
instance (Eq (n a), Eq a) => EqProp (S n a) where (=-=) = eq
-- Tree
data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a) deriving (Eq, Show)
instance Functor Tree where
fmap _ Empty = Empty
fmap f (Leaf a) = Leaf $ f a
fmap f (Node t a t') = Node (fmap f t) (f a) (fmap f t')
instance Foldable Tree where
foldMap _ Empty = mempty
foldMap f (Leaf a) = f a
foldMap f (Node t a t') = foldMap f t <> f a <> foldMap f t'
-- foldr for extra credits!
foldr _ z Empty = z
foldr f z (Leaf a) = f a z
foldr f z (Node t a t') = f a (foldr f (foldr f z t') t)
instance Traversable Tree where
traverse _ Empty = pure Empty
traverse f (Leaf a) = Leaf <$> f a
traverse f (Node t a t') =
Node <$> (traverse f t) <*> f a <*> traverse f t'
-- probably not the best distribution for a tree.
-- Should probably have it have a certain depth similar to []
instance Arbitrary a => Arbitrary (Tree a) where
arbitrary = do
a <- arbitrary
t <- arbitrary
t' <- arbitrary
frequency [(1, return Empty),
(3, return $ Leaf a),
(3, return $ Node t a t')]
instance (Eq a) => EqProp (Tree a) where (=-=) = eq
-- fmap :: Functor f => (a -> b) -> f a -> f b
-- foldMap :: (Monoid m, Foldable t) => (a -> m) -> t a -> m
-- foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
-- traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
main :: IO ()
main = do
quickBatch (functor (undefined :: Identity (Int,Int,Int)))
quickBatch (traversable (undefined :: Identity (Int,Int,[Int])))
quickBatch (functor (undefined :: Constant String (Int,Int,Int)))
quickBatch (traversable (undefined :: Constant String (Int,Int,[Int])))
quickBatch (functor (undefined :: Optional (Int,Int,Int)))
quickBatch (traversable (undefined :: Optional (Int,Int,[Int])))
quickBatch (functor (undefined :: List (Int,Int,Int)))
quickBatch (traversable (undefined :: List (Int,Int,[Int])))
quickBatch (functor (undefined :: Three String Int (Int,Int,Int)))
quickBatch (traversable (undefined :: Three String Int (Int,Int,[Int])))
quickBatch (functor (undefined :: Pair String (Int,Int,Int)))
quickBatch (traversable (undefined :: Pair String (Int,Int,[Int])))
quickBatch (functor (undefined :: Big String (Int,Int,Int)))
quickBatch (traversable (undefined :: Big String (Int,Int,[Int])))
quickBatch (functor (undefined :: Bigger String (Int,Int,Int)))
quickBatch (traversable (undefined :: Bigger String (Int,Int,[Int])))
quickBatch (functor (undefined :: S [] (Int,Int,Int)))
quickBatch (traversable (undefined :: S [] (Int,Int,[Int])))
quickBatch (functor (undefined :: Tree (Int,Int,Int)))
quickBatch (traversable (undefined :: Tree (Int,Int,[Int])))
Loading…
Cancel
Save