{-# LANGUAGE ApplicativeDo #-} f x y = undefined data A a = A { runA :: a } instance Functor A where fmap f (A a) = A (f a) instance Applicative A where pure = A A f <*> A x = A (f x) main = do x <- undefined y <- (runA $ do { z <- undefined; w <- undefined; return (f z w) }) return y