I do not see why `Interfaces` and `interfaces` and `ModuleInterface` need to be exposed. Isn't it possible to have the following type:

    compile :: String -> IO (Either String String)

There is only one way to create an interface, so this is effectively going in an IO monad no matter what with these changes.