Dynamic’s are essential to support Hot Reload.

A Dynamic is simply defined as:

newtype Dynamic m a
  = Dynamic
      ( -- Initial value
      , -- Set a new value
        (a -> m ()) -> m ()

It is a pair of values: the initial value, and a function that knows how to update that value over time using the user-provided update function (a -> m ()). Dynamic’s are an Applicative, so they compose using liftA* family of functions.

The EmaSite’s siteInput method returns a Dynamic of Model type, which represents all the data required to render a site. If you do not want Hot Reload, you may return a pure value.

The use of a time-varying Dynamic is what enables Hot Reload. See here for an example of making a model time-varying. Checkout unionmount to produce a Dynamic of a model that updates based on the filesystem tree.

Links to this page
  • unionmount

    unionmount is a Haskell library that wraps fsnotify to provide a Dynamic-friendly API to listen on filesystem changes and update an in-memory Model type. The library interface is such that you can “mount” multiple directories (union'ing them in the process), and have it update the model when files on any of those directories change.

  • Upgrading
    Change Ema to EmaSite, and define siteInput (what used to be in argument to runEma) and siteOutput (the render argument to runEma). You will want to use Dynamic instead of LVar.
  • Model type
    In EmaSite typeclass, siteInput can now return this model value (and it can be time-varying if using a Dynamic), as well as siteOutput can take the model value so as to render the site based on it.
  • Live Server

    The “run” command of CLI runs the live-server, as opposed to the “gen” command which generates the static site one off. The live-server is a simple HTTP server that serves the Ema site “on the fly” (without doing O(n) static-site generation). Furthermore, changes to your Model type (via Dynamic) will automatically Hot Reload the browser clients to display the new HTML as rendered using the new model value.

  • Hot Reload

    For anything outside of the Haskell code, your code becomes responsible for monitoring and updating the Model type Dynamic. The unionmount library already provides utilities to facilitate this for monitoring changes to files and directories.

  • Guide
  • EmaSite

    The siteInput method takes a SiteArg value (and other relevant parameters) and returns a Dynamic of the site’s Model type.

  • Dynamic Model

    To do this, we must understand what a Dynamic (which siteInput returns) is.

    siteInput is defined to return a Dynamic m (RouteModel r). In our case, r ~ Route and RouteModel Route ~ Model, thus our siteInput returns a Dynamic m Model in the IO monad. A Dynamic is simply defined as: