Week 2 Lecture 1
A monad is a monoid in the category of endofunctors
hs
1import Distribution.Fields.Field (getName)2type Name = String34type Age = Int56data Country7 = Denmark8 | DPRK9 | Latvia1011personAge :: Name -> Maybe Age12personAge "Troels" = Just 3813personAge "Toxo" = Just 814personAge "Sebastian" = Just 2915personAge _ = Nothing1617mayVote0 :: Name -> Maybe Bool18mayVote0 name = fmap (>= 18) (personAge name)1920mayVote1 :: (Functor f) => (Name -> f Age) -> Name -> f Bool21mayVote1 getAge name = fmap (>= 18) (getAge name)2223anotherPersonAge :: Name -> Either String Age24anotherPersonAge "Troels" = Right 3825anotherPersonAge "Doctor Doom" = Left "Dr. Doom is ageless"26anotherPersonAge name = Left $ "Unknown person: " ++ name2728votingAge :: Country -> Maybe Age29votingAge Denmark = Just 1830votingAge DPRK = Just 1731votingAge Latvia = Nothing3233mayVote2 :: Applicative f => (Name -> f Age) -> (Country -> f Age) -> Name -> Country -> f Bool34mayVote2 getAge getVotingAge name country = 35 -- (>=) <$> (getAge name) <*> (getVotingAge country) -- Name check first36 (<=) <$> (getVotingAge country) <*> (getAge name) -- Age check first37 -- pure (>=) <*> (getAge name) <*> (getVotingAge country)3839-- "Talking to the outside world is dangerous and uncomfortable for computer scientists"4041findVoters :: Monad f => (Name -> f Age) -> (Country -> f Age) -> [Name] -> Country -> f [Name]42findVoters getAge getMinAge [] country = pure []43findVoters getAge getMinAge (name: names) country = canVote name >>= filtering44 where45 remaining = findVoters getAge getMinAge names country46 filtering b = if b then (name:) <$> remaining else remaining47 canVote name = (>=) <$> getAge name <*> getMinAge country4849myVoters :: Maybe [Name]50myVoters = findVoters personAge votingAge ["Troels", "asd"] Latvia5152getAgeFromUser :: Name -> IO Age53getAgeFromUser name = do54 putStrLn $ "How old is " ++ name ++ "?"55 a <- getLine56 pure (read a)5758