-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCh15.hs
More file actions
104 lines (67 loc) · 2.31 KB
/
Ch15.hs
File metadata and controls
104 lines (67 loc) · 2.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
module Ch15 where
-- import Data.Monoid
import Data.Semigroup
import Test.QuickCheck
-- class Monoid m where
-- mempty :: m
-- mappend :: m -> m -> m
-- mconcat :: [m] -> m
-- mconcat = foldr mappend mempty
-- laws:
-- -- left identity:
-- mappend mempty x = x
-- -- right identity:
-- mappend x mempty = x
-- -- associativity:
-- mappend x (mappend y z) = mappend (mappend x y) z
-- mconcat = foldr mappend mempty
-- instance Monid b => Monoid (a -> b)
-- keep in mind that you don't need the type constraint
-- for phantom types e.g.: data Test a = T | F
data Optional a = Nada | Only a
deriving (Eq, Show)
instance Semigroup a => Semigroup (Optional a) where
(<>) = undefined
-- sconcat = undefined
-- stimes = undefined
instance Monoid a => Monoid (Optional a) where
mempty = Nada
mappend = optionalMap
optionalMap :: Monoid a => Optional a -> Optional a -> Optional a
optionalMap Nada x = x
optionalMap x Nada = x
optionalMap (Only x) (Only y) = Only (mappend x y)
monoidAssoc :: (Eq m, Monoid m) => m -> m -> m -> Bool
monoidAssoc a b c = (a <> (b <> c)) == ((a <> b) <> c)
monoidLeftIdentity :: (Eq m, Monoid m) => m -> Bool
monoidLeftIdentity a = (mempty <> a) == a
monoidRightIdentity :: (Eq m, Monoid m) => m -> Bool
monoidRightIdentity a = (a <> mempty) == a
newtype First' a = First' {getFirst' :: Optional a}
deriving (Eq, Show)
instance Arbitrary a => Arbitrary (First' a) where
arbitrary = frequency [(1, return $ First' Nada),
(1, fmap (First' . Only) arbitrary)]
instance Semigroup (First' a) where
(<>) = firstMappend
instance Monoid (First' a) where
mempty = First' Nada
mappend = firstMappend
firstMappend :: First' a -> First' a -> First' a
firstMappend (First' f@(Only a)) _ = First' f
firstMappend (First' Nada) (First' a) = First' a
-- firstMappend (First' Nada) (First' Nada) = First' Nada
type FirstMappend =
First' String -> First' String -> First' String -> Bool
type FstId = First' String -> Bool
main :: IO ()
main = do
quickCheck (monoidAssoc :: FirstMappend)
quickCheck (monoidLeftIdentity :: FstId)
quickCheck (monoidRightIdentity :: FstId)
-- class Semigroup a where
-- (<>) :: a -> a -> a
-- associativity law:
-- (a <> b) <> c = ((a <> b) <> c)
-- data NonEmpty a = a :| [a]
-- deriving (Eq, Show)