Dyre implements a basic interface for dynamically recompiling Haskell programs with new configurations. The inspiration for all this is, of course, Xmonad's reconfiguration functionality. It is similar in usage to the HConf library which was written for the Yi editor.
The main interface to the Dyre library consists of three items: a datatype for configuration data, a set of default values, and a function which makes that data into an entry-point function.
A complete, working example can be seen here:
-- DyreExample.hs --
module DyreExample ( dyreExample ) where
import qualified Config.Dyre as Dyre
confError cfgMessage error = "Error:" ++ error ++ "\n" ++ cfgMessage
realMain message = do
putStrLn "Entered Main Function"
putStrLn message
dyreExample = Dyre.wrapMain $ newParams "dyreExample" realMain confError
This code defines a simple library which will display a message on stdout. It uses Dyre to provide configuration of what exactly the message is. The default configuration could look something like this:
-- Main.hs --
import DyreExample
main = dyreExample "This is the default configuration"
While a user's custom configuration would be more like this:
-- dyreExample.hs --
import DyreExample
main = dyreExample "This is a custom configuration"
This example can be run without installing. Simply run Main.hs
[^1] with the
argument '--dyre-debug', to tell it to search for a configuration file in the
current directory. If the custom configuration exists, it will be compiled and
executed, or the default message will be displayed if there is no custom
configuration.
The Dyre.wrapMain
function is how Dyre is meant to be invoked. It is passed
a set of parameters which configure how it operates. Most parameters have some
good defaults, but can be overriden on the record produced by newParams
.
The Dyre.projectName
element is used to search for a custom configuration, the
Dyre.showError
element is called with compile errors to store the information
in the program configuration, and Dyre.realMain
is the function which is
ultimately the main program entry point.
For the other parameters Dyre uses, consult the Config.Dyre.Params
module
documentation.
[^1] You can compile it with ghc --make
, or simply use runhaskell Main.hs
.
Restarting is handled by the Config.Dyre.Relaunch
module. To simply restart,
discarding all state information, use the relaunchMaster
function.
If the state needs to be preserved, there are two pairs of functions available.
When your program starts, you will want to use either the restoreTextState
or
the restoreBinaryState
function. Both of these take a default state which is
returned when there is no persisted state to use.
Then to restart and persist the state, use the function relaunchWithTextState
or relaunchWithBinaryState
corresponding to your chosen restore function. The
state will be persisted and your program restarted for you.