¿Es posible extender intérpretes de mónada gratis?

Dada una mónada DSL gratuita como:

data FooF x = Foo String x
            | Bar Int    x
  deriving (Functor)

type Foo = Free FooF

Y un intérprete al azar paraFoo:

printFoo :: Foo -> IO ()
printFoo (Free (Foo s n)) = print s >> printFoo n
printFoo (Free (Bar i n)) = print i >> printFoo n

Me parece que debería ser posible intercalar algo en cada iteración de printFoo sin recurrir a hacerlo manualmente:

printFoo' :: Foo -> IO ()
printFoo' (Free (Foo s n)) = print s >> print "extra info" >> printFoo' n
printFoo' (Free (Bar i n)) = print i >> print "extra info" >> printFoo' n

¿Es esto posible de alguna manera 'envolviendo' el originalprintFoo?

Motivación: Estoy escribiendo un DSL pequeño que se 'compila' en un formato binario. El formato binario contiene información adicional después de cada comando de usuario. Tiene que estar allí, pero es totalmente irrelevante en mi caso de uso.

Respuestas a la pregunta(5)

Su respuesta a la pregunta