Add remaining haskell book exercises
This commit is contained in:
62
Haskell-book/22/Reader.hs
Normal file
62
Haskell-book/22/Reader.hs
Normal file
@@ -0,0 +1,62 @@
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
module Reader where
|
||||
|
||||
import Control.Applicative (liftA2)
|
||||
|
||||
newtype Reader r a =
|
||||
Reader { runReader :: r -> a }
|
||||
|
||||
myLiftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
|
||||
myLiftA2 f x y = f <$> x <*> y
|
||||
|
||||
asks :: (r -> a) -> Reader r a
|
||||
asks f = Reader f
|
||||
|
||||
instance Functor (Reader r) where
|
||||
fmap f (Reader x) = Reader $ f . x
|
||||
|
||||
instance Applicative (Reader r) where
|
||||
pure :: a -> Reader r a
|
||||
pure a = Reader $ \x -> a
|
||||
(<*>) :: Reader r (a -> b) -> Reader r a -> Reader r b
|
||||
(Reader rab) <*> (Reader ra) = Reader $ \r -> rab r (ra r)
|
||||
|
||||
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
|
||||
|
||||
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 "Big Bird")
|
||||
(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
|
||||
|
||||
getDogRM :: Person -> Dog
|
||||
getDogRM = dogName >>= (\x -> address >>= \y -> return $ Dog x y)
|
||||
Reference in New Issue
Block a user