-
Notifications
You must be signed in to change notification settings - Fork 1
/
Ch22.hs
160 lines (116 loc) · 3.04 KB
/
Ch22.hs
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
{-# LANGUAGE InstanceSigs #-}
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
-- | Chapter 22, Reader
module Ch22 where
import Control.Applicative
import Control.Monad
import Data.Char
--- 22.2 A new beginning
boop = (*2)
doop = (+10)
-- Functor context: bip and bloop are equivalent
bip :: Integer -> Integer
bip = boop . doop
bloop :: Integer -> Integer
bloop = fmap boop doop
-- Applicative context: bbop and duwop are equivalent
bbop :: Integer -> Integer
bbop = (+) <$> boop <*> doop
duwop :: Integer -> Integer
duwop = liftA2 (+) boop doop
-- Monad context: works like bbop/duwop. no change from Applicative
boopDoop :: Integer -> Integer
boopDoop = do
a <- boop
b <- doop
return (a + b)
--- Short Exercise: Warming Up
cap :: [Char] -> [Char]
cap xs = map toUpper xs
rev :: [Char] -> [Char]
rev xs = reverse xs
composed :: [Char] -> [Char]
composed = cap . rev
fmapped :: [Char] -> [Char]
fmapped = fmap cap rev
tupled :: [Char] -> ([Char], [Char])
tupled = liftA2 (,) cap rev
-- monadic version with do
tupledM :: [Char] -> ([Char], [Char])
tupledM = do
c <- cap
r <- rev
return (c, r)
-- monadic version with bind
tupledMM :: [Char] -> ([Char], [Char])
tupledMM = cap >>= (\c -> rev >>= (\r -> return (,) c r))
--- Exercise: Ask
newtype Reader r a = Reader
{ runReader :: r -> a
}
instance Functor (Reader r) where
fmap f (Reader ra) = Reader $ (f . ra)
ask :: Reader a a
ask = Reader id
--- Demonstrating the function applicative
newtype HumanName =
HumanName String
deriving (Eq, Show)
newtype DogName =
DogName String
deriving (Eq, Show)
newtype Address =
Address String
deriving (Eq, Show)
data Person = Person
{ humanName :: HumanName
, dogName :: DogName
, address :: Address
} deriving (Eq, Show)
data Dog = Dog
{ dogsName :: DogName
, dogsAddress :: Address
} deriving (Eq, Show)
pers :: Person
pers =
Person (HumanName "BigBird") (DogName "Barkley") (Address "Sesame Street")
chris :: Person
chris = Person (HumanName "Chris Allen") (DogName "Papu") (Address "Austin")
getDog :: Person -> Dog
getDog p = Dog (dogName p) (address p)
getDogR :: Person -> Dog
getDogR =
Dog <$> dogName <*> address
getDogR' :: Person -> Dog
getDogR' = liftA2 Dog dogName address
--- Exercise: Reading Comprehension
-- 1. Write liftA2
myLiftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
myLiftA2 f a b = fmap f a <*> b
-- 2.
asks :: (r -> a) -> Reader r a
asks = Reader
-- 3.
instance Applicative (Reader r) where
pure :: a -> Reader r a
pure a = Reader $ const a
(<*>) :: Reader r (a -> b)
-> Reader r a
-> Reader r b
(Reader rab) <*> (Reader ra) =
Reader (\r -> rab r (ra r))
--- Exercise: Reader Monad
-- 1.
instance Monad (Reader r) where
return = pure
(>>=) :: Reader r a
-> (a -> Reader r b)
-> Reader r b
(Reader ra) >>= aRb =
Reader $ \r -> (runReader . aRb) (ra r) r
-- 2.
getDogRM :: Person -> Dog
getDogRM = liftM2 Dog dogName address
getDogRM' :: Person -> Dog
getDogRM' =
dogName >>= (\name -> (address >>= (\addy -> return $ Dog name addy)))