content: {-# LANGUAGE TypeFamilies #-}
  {-# LANGUAGE MultiParamTypeClasses #-}
  {-# LANGUAGE FlexibleInstances #-}
  module T11401 where
  
  import Data.Kind (Type)
  
  newtype Value a = Value a
  newtype CodeGen r a = CodeGen a
  
  bind :: CodeGen r a -> (a -> CodeGen r b) -> CodeGen r b
  bind (CodeGen a) k = k a
  
  class
     (f ~ CalledFunction g, r ~ CallerResult g, g ~ CallerFunction f r) =>
         CallArgs f g r where
     type CalledFunction g :: Type
     type CallerResult g :: Type
     type CallerFunction f r :: Type
     call :: f -> g
  
  instance CallArgs (IO a) (CodeGen r (Value a)) r where
     type CalledFunction (CodeGen r (Value a)) = IO a
     type CallerResult (CodeGen r (Value a)) = r
     type CallerFunction (IO a) r = CodeGen r (Value a)
     call = undefined
  
  instance CallArgs b b' r => CallArgs (a -> b) (Value a -> b') r where
     type CalledFunction (Value a -> b') = a -> CalledFunction b'
     type CallerResult (Value a -> b') = CallerResult b'
     type CallerFunction (a -> b) r = Value a -> CallerFunction b r
     call = undefined
  
  test :: IO a -> (a -> IO ()) -> CodeGen () (Value ())
  test start stop  =  bind (call start) (call stop)
  