{-# LANGUAGE TemplateHaskell, DeriveDataTypeable, MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-} module CounterState where import Control.Monad.State import Control.Monad.Reader import Data.Typeable import Happstack.State {- Define a simple datatype to hold the integer value of our counter. -} data CounterState = CounterState Int deriving (Typeable, Show) {- Our datatype uses the default Version, with no previous version of of our state defined. Versioning is beyond the scope of this example. -} instance Version CounterState {- Our datatype must also be serializable. Template Haskell magic here. -} $(deriveSerialize ''CounterState) {- Defines a simple Update function that increments the value of our counter -} incCount :: Update CounterState () incCount = modify ( \( CounterState n ) -> CounterState ( n + 1 ) ) {- Defines a simple Query function to get teh value of our counter -} getCount :: Query CounterState Int getCount = do CounterState n <- ask return n {- Derive a set of datatypes corresponding to the Query and Update functions we defined on our state. The datatypes will have the same name as our function names, with the initial letter upcased. This is more Tempplate Haskell vodoo. -} $(mkMethods ''CounterState [ 'incCount, 'getCount ] ) {- Build the type level list. Our example uses only primitive data so we use the empty dependency, End. We also define an initial state value. -} instance Component CounterState where type Dependencies CounterState = End initialValue = CounterState 0