newtype Reader e s = Reader { runReader :: e -> s }
instance Functor (Reader e) where
-- fmap :: (a -> b) -> f a -> f b
fmap f r = Reader { runReader = \e -> f $ (runReader r) e }
instance Applicative (Reader e) where
-- (<*>) :: f (a -> b) -> f a -> f b
f <*> r = Reader { runReader = \e -> (runReader f e) (runReader r e) }
pure r = Reader { runReader = const r }
instance Monad (Reader e) where
-- (>>=) :: m a -> (a -> m b) -> m b
r >>= f = Reader { runReader = \e -> runReader (f (runReader r e)) e }
ask :: Reader e e
ask = Reader id
comp :: Reader String String
comp = do
x <- ask
x' <- ask
return $ x ++ x'
comp2 :: String -> Reader String String
comp2 list = do
x <- ask
return $ x ++ " " ++ show (length list)
main = do
print $ runReader (comp >>= comp2) "hello"