[Haskell-cafe] Design of an extensible system

Marc Busqué marc at lamarciana.com
Sun Jul 22 15:27:09 UTC 2018


Hi there,

I'm currently programming my first non toy project in Haskell. I come from Ruby
background, where everything is possible no matter how much entropy the
universe gains after you finish your work, so I'm still not sure how to do
certain things without this side-effect :)

I'll try to be concise. My idea is that the project would consist of several
different Haskell packages. The central one, call it Core, would define a
certain data type (with info about certain URLs). Other packages would define
each one an strategy to do something with that data type (processing the URL
info). Each strategy would have its own dependencies, and as a user probably
won't need all of the strategies, I would like to keep them in separated
packages so she or he has no need to download the unneeded stuff.

The problem is that Core should act as the central dashboard, whether through a
CLI or even a web frontend. For example, in the CLI case, I would like to be
able to install Core package along with package StrategyA and package StrategyB
and then do something like the following:

``` 
bash> core --action=fetch --strategy=A
bash> core --action=fetch --strategy=B
```

Two generic ideas come to my mind but I don't know how to translate them
to Haskell:

- Infer module name from the `--strategy` argument and call it dynamically.
   However, as far as I know, in Haskell modules are not first class citizens,
   so no way I can dynamically call them. I have read something to achieve this
   through Template Haskell or through outdaded
   [plugins](http://hackage.haskell.org/package/plugins) package, but I'm not
   sure whether the need is the same and anyway it seems quite unnatural to
   Haskell (I would not like to go against it, but to learn to do thing in its
   way).

- Define from Core some kind of global list where strategy packages can
   register a map between CLI argument value and a defined instance of the core
   data type. But, again, how to do global things in Haskell (and I would prefer
   not to need external tools like RDBMS, filesystem or whatever)? And, anyway,
   surely I don't want to do this because concurrency and everything...

Any idea?

Thanks in advance!

Marc Busqué
http://waiting-for-dev.github.io/about/


More information about the Haskell-Cafe mailing list