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"