For awhile now, whenever people mention the performance hit of free monad + interpreter pattern, I've had this vague idea in my head that: "Why not just use Template Haskell to evaluate your interpreter at compile time? Thus negating the performance hit of free monads entirely, essentially turning the free monad + interpreter pattern into a free monad + compiler pattern."
Making this a little more concrete, let's say I have something like the following:
data MyFreeF a = ...
type MyFreeM a = (Free MyFreeF) a
interpret :: MyFreeM a -> IO a
interpret = ...
compileFree :: MyFreeM a -> Q (TExp (IO a))
compileFree m = let x = interpret m in [|| x ||]
So, this seems on the surface like it should work. The issue I run into here is that this requires that Lift
be derived for IO a
. So my question is: Is such a thing possible? If not, does deriving Lift
for IO a
even make sense (i.e. we can't do this today, but if we had X, Y, and Z future GHC extension, we could!)?
So far I have tried using DeriveLift
for IO
and its constituent components (Like State#
) as defined in GHC.IO
, but was not able to get far.