The question is how to structure a Haskell project in order to allow the user of a library to provide own plugins without having to mix her own code into the library's source code. Let me elaborate...
Suppose I have a library called foolib
that
- provides plugins via a
Plugin
type class - provides some (many) types that are instances of the
Plugin
class - shall allow the user to create own plugins
Of course the user of foolib
could just add more plugins inside foolib/
. But foolib
is developed independently of the application that uses foolib
, and both are under separate SCM. In this case mixing in the user's plugins under foolib/
violates separation and complicates source control. In short: Mixing in users' plugins in foobar/
is feasible, of course, but can't be maintained.
The obvious alternative is depicted below. The user maintains my-project
, adds foolib/
as a git submodule (let's say we're using git), and keeps his plugins in a separate Plugins/
directory. Now here comes the dilemma: All the plugins, i.e. both the user's plugins and the ones in foolib
, are used deep down in foolib/src/Core/
and re-exposed to the user - not directly, but in disguise. (Suppose the plugins are blocks in a CMS where the plugin renders some HTML and makes some keywords available that the end-user can use in his content, and that are understood by a HTML template engine.)
One issue is how to make Haskell stack
deal with this setup while keeping up with the separation of my-project/
and foolib/
.
To make matters worse, there is some template Haskell ("TH") going on that discovers all plugins in foobar/src/Plugins
at compile-time and uses the class functions of the many plugins in many places in the source code of foolib
. (This isn't perfect either since, to my knowledge, imports cannot be templatized - but that's another issue.)
I think it's clear that the structure I presented here isn't working and I don't see a nice way out. The central problem is that either I sacrifice the separation of foolib
and my-project
, or I end up with convolution of template Haskell, sed
, awk
and other scripts, which is ultimately counter-productive.
Any guidance would be very much appreciated.