Skip to content

Week 2 Lecture 1

A monad is a monoid in the category of endofunctors

lec03.hs:

hs
1
import Distribution.Fields.Field (getName)
2
type Name = String
3
4
type Age = Int
5
6
data Country
7
= Denmark
8
| DPRK
9
| Latvia
10
11
personAge :: Name -> Maybe Age
12
personAge "Troels" = Just 38
13
personAge "Toxo" = Just 8
14
personAge "Sebastian" = Just 29
15
personAge _ = Nothing
16
17
mayVote0 :: Name -> Maybe Bool
18
mayVote0 name = fmap (>= 18) (personAge name)
19
20
mayVote1 :: (Functor f) => (Name -> f Age) -> Name -> f Bool
21
mayVote1 getAge name = fmap (>= 18) (getAge name)
22
23
anotherPersonAge :: Name -> Either String Age
24
anotherPersonAge "Troels" = Right 38
25
anotherPersonAge "Doctor Doom" = Left "Dr. Doom is ageless"
26
anotherPersonAge name = Left $ "Unknown person: " ++ name
27
28
votingAge :: Country -> Maybe Age
29
votingAge Denmark = Just 18
30
votingAge DPRK = Just 17
31
votingAge Latvia = Nothing
32
33
mayVote2 :: Applicative f => (Name -> f Age) -> (Country -> f Age) -> Name -> Country -> f Bool
34
mayVote2 getAge getVotingAge name country =
35
-- (>=) <$> (getAge name) <*> (getVotingAge country) -- Name check first
36
(<=) <$> (getVotingAge country) <*> (getAge name) -- Age check first
37
-- pure (>=) <*> (getAge name) <*> (getVotingAge country)
38
39
-- "Talking to the outside world is dangerous and uncomfortable for computer scientists"
40
41
findVoters :: Monad f => (Name -> f Age) -> (Country -> f Age) -> [Name] -> Country -> f [Name]
42
findVoters getAge getMinAge [] country = pure []
43
findVoters getAge getMinAge (name: names) country = canVote name >>= filtering
44
where
45
remaining = findVoters getAge getMinAge names country
46
filtering b = if b then (name:) <$> remaining else remaining
47
canVote name = (>=) <$> getAge name <*> getMinAge country
48
49
myVoters :: Maybe [Name]
50
myVoters = findVoters personAge votingAge ["Troels", "asd"] Latvia
51
52
getAgeFromUser :: Name -> IO Age
53
getAgeFromUser name = do
54
putStrLn $ "How old is " ++ name ++ "?"
55
a <- getLine
56
pure (read a)
57
58