63 lines
1.7 KiB
Haskell
63 lines
1.7 KiB
Haskell
{-# 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)
|