title: Making QualifiedDo and ApplicativeDo work together when nesting applicative functors
body: <p>I want to define deeply nested <a href="https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Functor-Compose.html#t:Compose" rel="noreferrer">compositions</a> of applicative functors. For example something like this:</p>
  <pre><code>{-# LANGUAGE TypeOperators #-}
  import Control.Monad.Trans.Cont
  import Control.Arrow (Kleisli (..))
  import Data.Aeson
  import Data.Aeson.Types
  import Data.Functor.Compose
  import Data.Functor
  
  type Configurator = Kleisli Parser Value
  type Allocator = ContT () IO 
  type Validator = Either String
  
  someConfigurator :: Configurator Int
  someConfigurator = undefined
  
  someAllocator :: Allocator Char
  someAllocator = undefined
  
  -- the nested functor composition. left-associated
  type Phases = Configurator `Compose` Allocator `Compose` Validator 
  
  data Foo = Foo Int Char
  
  -- I want to streamline writing this, without spamming the Compose constructor 
  fooPhases :: Phases Foo
  fooPhases = _ 
  </code></pre>
  <p>To streamline the syntax for creating the <code>fooPhases</code> value, I though of (ab)using <a href="https://downloads.haskell.org/ghc/latest/docs/html/users_guide/exts/qualified_do.html?highlight=qualifieddo#extension-QualifiedDo" rel="noreferrer"><code>QualifiedDo</code></a>:</p>
  <pre><code>module Bind where
  import Data.Functor
  import Data.Functor.Compose
  
  (&gt;&gt;=) :: Functor f =&gt; f a -&gt; (a -&gt; g b) -&gt; Compose f g b 
  (&gt;&gt;=) f k = bindPhase f k
  
  (&gt;&gt;) :: Functor f =&gt; f a -&gt; g b -&gt; Compose f g b 
  (&gt;&gt;) f g = Compose $ f &lt;&amp;&gt; \_ -&gt; g
  
  fail :: MonadFail m =&gt; String -&gt; m a
  fail = Prelude.fail
  
  bindPhase :: Functor f =&gt; f a -&gt; (a -&gt; g b) -&gt; Compose f g b 
  bindPhase f k = Compose (f &lt;&amp;&gt; k)
  </code></pre>
  <p>Somewhat to my surprise, it worked:</p>
  <pre><code>{-# LANGUAGE QualifiedDo #-}
  import qualified Bind
  fooPhases :: Phases Foo
  fooPhases = Bind.do 
      i &lt;- someConfigurator 
      c &lt;- someAllocator 
      pure (Foo i c)
  </code></pre>
  <p>Alas, when I add applicative-like functions to the <code>Bind</code> module</p>
  <pre><code>return :: Applicative f =&gt; a -&gt; f a
  return = Prelude.pure
  
  pure :: Applicative f =&gt; a -&gt; f a
  pure = Prelude.pure
  
  fmap :: Functor f =&gt; (a -&gt; b) -&gt; f a -&gt; f b
  fmap = Prelude.fmap
  
  join :: f (g a) -&gt; Compose f g a
  join = Compose
  
  (&lt;*&gt;) :: (Applicative f, Applicative g) =&gt; f (a -&gt; b) -&gt; g a -&gt; Compose f g b
  (&lt;*&gt;) f g = Compose $ f &lt;&amp;&gt; \z -&gt; Prelude.fmap (z $) g
  </code></pre>
  <p>and then enable <a href="https://downloads.haskell.org/ghc/latest/docs/html/users_guide/exts/applicative_do.html?highlight=applicativedo#extension-ApplicativeDo" rel="noreferrer"><code>ApplicativeDo</code></a> in <code>Main</code>, I start to get errors like the following:</p>
  <pre><code>* Couldn't match type: Compose (Kleisli Parser Value) (ContT () IO)
                   with: Kleisli Parser Value
    Expected: Configurator (Compose Allocator Validator Foo)
      Actual: Compose
                (Kleisli Parser Value)
                (ContT () IO)
                (Compose Allocator Validator Foo)
  </code></pre>
  <p>Is there a way to use my <code>Bind.do</code> when <em>both</em> <code>QualifiedDo</code> and <code>ApplicativeDo</code> are enabled in <code>Main</code>?</p>