-XFunctorialDo
tl;dr: ApplicativeDo is useful also for functors. However, use laziness when pattern matching. The GHC manual remains a fantastic resource for learning about language extensions. By default, do blocks are associated with Monad constraints. You might know that by enabling the ApplicativeDo language extension, we can write do blocks for unary type constructors that are not monads, but only applicatives. (Recall that Monad is a subclass of Applicative since GHC 7.10.1 .) {-# LANGUAGE ApplicativeDo #-} showAnInt :: Applicative f => f Int -> f String showAnInt action = do n <- action return $ show n But did you know that we can also write do blocks for Functor s? -- Note the 'Functor' constraint rather than 'Applicative'. showAnIntFunctor :: Functor f => f Int -> f String showAnIntFunctor action = do n <- action return $ show n I encountered this accidentally while writing code for Hasura : I wrote a do bloc