summaryrefslogtreecommitdiff
path: root/Haskell-book/21/instances/src
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-12-11 10:28:11 +0100
committerEugen Wissner <belka@caraus.de>2025-12-11 10:28:11 +0100
commit98329e0a3dd4f78b5d815ac3896272ec70904901 (patch)
tree80f9c56cfe2ac20232358f236d32e84bd683be1b /Haskell-book/21/instances/src
parent3624c712d72d246f21d4e710cec7c11e052e0326 (diff)
downloadbook-exercises-98329e0a3dd4f78b5d815ac3896272ec70904901.tar.gz
Add remaining haskell book exercises
Diffstat (limited to 'Haskell-book/21/instances/src')
-rw-r--r--Haskell-book/21/instances/src/Lib.hs222
-rw-r--r--Haskell-book/21/instances/src/SkiFree.hs32
-rw-r--r--Haskell-book/21/instances/src/Tree.hs44
3 files changed, 298 insertions, 0 deletions
diff --git a/Haskell-book/21/instances/src/Lib.hs b/Haskell-book/21/instances/src/Lib.hs
new file mode 100644
index 0000000..1fbb25b
--- /dev/null
+++ b/Haskell-book/21/instances/src/Lib.hs
@@ -0,0 +1,222 @@
+module Lib where
+
+import Data.Monoid
+import Data.Traversable
+import Test.QuickCheck
+import Test.QuickCheck.Checkers
+
+--
+-- Identity
+--
+newtype Identity a = Identity a
+ deriving (Eq, Ord, Show)
+
+instance Functor Identity where
+ fmap f (Identity x) = Identity $ f x
+
+instance Applicative Identity where
+ pure = Identity
+ (Identity f) <*> x = fmap f x
+
+instance Foldable Identity where
+ foldr f acc (Identity x) = f x acc
+
+instance Arbitrary a => Arbitrary (Identity a) where
+ arbitrary = fmap Identity $ arbitrary
+
+instance Eq a => EqProp (Identity a) where
+ (=-=) = eq
+
+instance Traversable Identity where
+ traverse f (Identity x) = Identity <$> f x
+
+--
+-- Constant
+--
+newtype Constant a b = Constant { getConstant :: a }
+ deriving (Eq, Ord, Show)
+
+instance Functor (Constant a) where
+ fmap _ (Constant x) = Constant x
+
+instance Monoid a => Applicative (Constant a) where
+ pure _ = Constant mempty
+ (Constant x) <*> (Constant y) = Constant $ mappend x y
+
+instance (Arbitrary a, Arbitrary b) => Arbitrary (Constant a b) where
+ arbitrary = do
+ x <- arbitrary
+ return $ Constant x
+
+instance (Eq a, Eq b) => EqProp (Constant a b) where
+ (=-=) = eq
+
+instance Foldable (Constant a) where
+ foldMap _ (Constant _) = mempty
+
+instance Traversable (Constant a) where
+ traverse f (Constant x) = pure $ Constant x
+
+--
+-- Maybe
+--
+data Optional a = Nada | Yep a deriving (Show, Eq, Ord)
+
+instance Monoid a => Monoid (Optional a) where
+ mempty = Nada
+ mappend Nada _ = Nada
+ mappend _ Nada = Nada
+ mappend (Yep x) (Yep y) = Yep $ mappend x y
+
+instance Applicative Optional where
+ pure = Yep
+ (Yep f) <*> (Yep x) = Yep $ f x
+ Nada <*> (Yep x) = Nada
+ _ <*> Nada = Nada
+
+instance Functor Optional where
+ fmap _ Nada = Nada
+ fmap f (Yep x) = Yep $ f x
+
+instance Foldable Optional where
+ foldr f acc Nada = acc
+ foldr f acc (Yep x) = f x acc
+
+instance Traversable Optional where
+ traverse f Nada = pure Nada
+ traverse f (Yep x) = Yep <$> f x
+
+instance (CoArbitrary a, Arbitrary a) => Arbitrary (Optional a) where
+ arbitrary = do
+ x <- arbitrary
+ frequency [ (1, return Nada)
+ , (2, return $ Yep x)
+ ]
+
+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 x xs) = Cons (f x) (fmap f xs)
+
+instance Foldable List where
+ foldr _ acc Nil = acc
+ foldr f acc (Cons x xs) = f x (foldr f acc xs)
+
+instance Traversable List where
+ sequenceA Nil = pure Nil
+ sequenceA (Cons x xs) = Cons <$> x <*> (sequenceA xs)
+
+instance Arbitrary a => Arbitrary (List a) where
+ arbitrary = sized go
+ where go 0 = pure Nil
+ go n = do
+ xs <- go (n - 1)
+ x <- arbitrary
+ return $ Cons x xs
+
+instance (Eq a) => EqProp (List a) where
+ (=-=) = eq
+
+--
+-- Three
+--
+data Three a b c = Three a b c deriving (Show, Eq)
+
+instance Functor (Three a b) where
+ fmap f (Three x y z) = Three x y (f z)
+
+instance Foldable (Three a b) where
+ foldr f acc (Three x y z) = (f z acc)
+
+instance Traversable (Three a b) where
+ traverse f (Three x y z) = fmap (Three x y) (f z)
+
+instance (Arbitrary a, Arbitrary b, Arbitrary c) => Arbitrary (Three a b c) where
+ arbitrary = do
+ x <- arbitrary
+ y <- arbitrary
+ z <- arbitrary
+ return $ Three x y z
+
+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 x y) = Pair x (f y)
+
+instance Foldable (Pair a) where
+ foldr f acc (Pair x y) = (f y acc)
+
+instance Traversable (Pair a) where
+ traverse f (Pair x y) = fmap (Pair x) (f y)
+
+instance (Arbitrary a, Arbitrary b) => Arbitrary (Pair a b) where
+ arbitrary = do
+ x <- arbitrary
+ y <- arbitrary
+ return $ Pair x y
+
+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 x y z) = Big x (f y) (f z)
+
+instance Foldable (Big a) where
+ foldr f acc (Big _ y z) = (f y (f z acc))
+
+instance Traversable (Big a) where
+ traverse f (Big x y z) = (Big x) <$> (f y) <*> (f z)
+
+instance (Arbitrary a, Arbitrary b) => Arbitrary (Big a b) where
+ arbitrary = do
+ x <- arbitrary
+ y <- arbitrary
+ z <- arbitrary
+ return $ Big x y z
+
+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 x y z t) = Bigger x (f y) (f z) (f t)
+
+instance Foldable (Bigger a) where
+ foldr f acc (Bigger _ y z t) = f y $ f z $ f t acc
+
+instance Traversable (Bigger a) where
+ traverse f (Bigger x y z t) = (Bigger x) <$> (f y) <*> (f z) <*> (f t)
+
+instance (Arbitrary a, Arbitrary b) => Arbitrary (Bigger a b) where
+ arbitrary = do
+ x <- arbitrary
+ y <- arbitrary
+ z <- arbitrary
+ t <- arbitrary
+ return $ Bigger x y z t
+
+instance (Eq a, Eq b) => EqProp (Bigger a b) where
+ (=-=) = eq
+
diff --git a/Haskell-book/21/instances/src/SkiFree.hs b/Haskell-book/21/instances/src/SkiFree.hs
new file mode 100644
index 0000000..70e87dc
--- /dev/null
+++ b/Haskell-book/21/instances/src/SkiFree.hs
@@ -0,0 +1,32 @@
+{-# LANGUAGE FlexibleContexts #-}
+
+module SkiFree where
+
+import Test.QuickCheck
+import Test.QuickCheck.Checkers
+
+data S n a = S (n a) a deriving (Eq, Show)
+
+instance ( Functor n
+ , Arbitrary (n a)
+ , Arbitrary a)
+ => Arbitrary (S n a) where
+ arbitrary = S <$> arbitrary <*> arbitrary
+
+--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
+
+instance Functor n => Functor (S n) where
+ fmap f (S x y) = S (fmap f x) (f y)
+
+instance Foldable n => Foldable (S n) where
+ foldMap f (S n a) = mappend (foldMap f n) (f a)
+
+instance Traversable n => Traversable (S n) where
+ traverse f (S x y) = S <$> (traverse f x) <*> (f y)
diff --git a/Haskell-book/21/instances/src/Tree.hs b/Haskell-book/21/instances/src/Tree.hs
new file mode 100644
index 0000000..5c0740c
--- /dev/null
+++ b/Haskell-book/21/instances/src/Tree.hs
@@ -0,0 +1,44 @@
+module Tree where
+
+import Data.Monoid
+import Test.QuickCheck
+import Test.QuickCheck.Checkers
+import Test.QuickCheck.Classes
+
+-- Solution:
+-- https://www.reddit.com/r/HaskellBook/comments/7w7bqn/ch_21_is_this_a_sane_instance_of_traversable/
+
+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 x) = Leaf $ f x
+ fmap f (Node x y z) = Node (fmap f x) (f y) (fmap f z)
+
+-- foldMap is a bit easier and looks more natural, but you can do
+-- foldr too for extra credit.
+instance Foldable Tree where
+ foldMap _ Empty = mempty
+ foldMap f (Leaf x) = f x
+ foldMap f (Node x y z) = (foldMap f x) <> (f y) <> (foldMap f z)
+
+instance Traversable Tree where
+ traverse f Empty = pure Empty
+ traverse f (Leaf x) = Leaf <$> f x
+ traverse f (Node x y z) = Node <$> (traverse f x) <*> (f y) <*> (traverse f z)
+
+instance Arbitrary a => Arbitrary (Tree a) where
+ arbitrary = do
+ x <- arbitrary
+ y <- arbitrary
+ z <- arbitrary
+ frequency [ (1, return Empty)
+ , (2, return $ Leaf y)
+ , (3, return $ Node x y z)
+ ]
+
+instance Eq a => EqProp (Tree a) where
+ (=-=) = eq