You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
1.9 KiB
75 lines
1.9 KiB
{-# LANGUAGE InstanceSigs #-} |
|
module ReadingComp where |
|
|
|
import Control.Applicative (liftA2) |
|
|
|
newtype Reader r a = Reader { runReader :: r -> a } |
|
|
|
instance Functor (Reader r) where |
|
fmap f (Reader ra) = Reader $ f . ra |
|
|
|
-- 1 |
|
myLiftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c |
|
myLiftA2 f a b = 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 |
|
|
|
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") |
|
|
|
mario :: Person |
|
mario = Person (HumanName "Mario") |
|
(DogName "Yoshi") |
|
(Address "Mushroom Kingdom") |
|
|
|
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 = do |
|
name <- dogName |
|
addy <- address |
|
return $ Dog name addy |
|
|
|
getDogRM' :: Reader Person Dog |
|
getDogRM' = do |
|
name <- Reader dogName |
|
addy <- Reader address |
|
return $ Dog name addy
|
|
|