HORIZON HASKELLDocslts/ghc-10.0.x8c2f8e82026-10-19Search names, modules, packages, or :: a typeCtrl K

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8c2f8e8 · 2026-10-19

Moduleacid-state-0.16.1.4Haskell2010

Data.Acid.TemplateHaskell

  • 2 types
  • 20 values
  • Packageacid-state-0.16.1.4
  • Exports22
  • LanguageHaskell2010
  • LicenceLicenseRef-PublicDomain
  • SourceTemplateHaskell.hs
valuemakeAcidic :: Name -> [Name] -> Q [Dec]
#

Create the control structures required for acid states using Template Haskell.

This code:

myUpdate :: Argument -> Update State Result
myUpdate arg = ...

myQuery :: Argument -> Query State Result
myQuery arg = ...

$(makeAcidic ''State ['myUpdate, 'myQuery])

will make State an instance of IsAcidic and provide the following events:

data MyUpdate = MyUpdate Argument
data MyQuery  = MyQuery Argument
datadata SerialiserSpec
#

Specifies how to customise the IsAcidic instance and event data type serialisation instances for a particular serialisation layer.

Constructors

valuemakeEvent :: SerialiserSpec -> Name -> Q [Dec]
#

Given an event name (e.g. 'myUpdate), produce a data type like

data MyUpdate = MyUpdate Argument

along with the Method class instance, Event class instance and the instance of the appropriate serialisation class.

However, if the event data type already exists, this will generate the serialisation instance only. This makes it possible to call makeAcidicWithSerialiser multiple times on the same events but with different SerialiserSpecs, to support multiple serialisation backends.

valueeventCxts
  1. :: Type

    State type

  2. -> [TyVarBndrUnit]

    type variables that will be used for the State type in the IsAcidic instance

  3. -> Name

    Name of the event

  4. -> Type

    Type of the event

  5. -> [Pred]

    extra context to add to IsAcidic instance

#

This function analyses an event function and extracts any additional class contexts which need to be added to the IsAcidic instance.

For example, if we have:

data State a = ...
setState :: (Ord a) => a -> UpdateEvent (State a) ()

Then we need to generate an IsAcidic instance like:

instance (SafeCopy a, Typeable a, Ord a) => IsAcidic (State a)

Note that we can only add constraints for type variables which appear in the State type. If we tried to do this:

setState :: (Ord a, Ord b) => a -> b -> UpdateEvent (State a) ()

We will get an ambigious type variable when trying to create the IsAcidic instance, because there is no way to figure out what type b should be.

The tricky part of this code is that we need to unify the type variables.

Let's say the user writes their code using b instead of a:

setState :: (Ord b) => b -> UpdateEvent (State b) ()

In the IsAcidic instance, we are still going to use a. So we need to rename the variables in the context to match.

The contexts returned by this function will have the variables renamed.

Additionally, if the event uses MonadReader or MonadState it might look like this:

setState :: (MonadState x m, IsFoo x) => m ()

In this case we have to rename x to the actual state we're going to use. This is done by renameState.

valuetoStructName :: Name -> Name
#

Convert the Name of the event function into the name of the corresponding data constructor.