{-# 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





