{-# LANGUAGE GeneralizedNewtypeDeriving, GADTs #-}
module Data.Acid.Common where
import Data.Acid.Core
import Control.Monad.State
import Control.Monad.Reader
import Control.Applicative
class IsAcidic st where
acidEvents :: [Event st]
newtype Update st a = Update { unUpdate :: State st a }
deriving (Monad, Functor, MonadState st)
instance Applicative (Update st) where
pure = return
(<*>) = ap
newtype Query st a = Query { unQuery :: Reader st a }
deriving (Monad, Functor, MonadReader st)
instance Applicative (Query st) where
pure = return
(<*>) = ap
liftQuery :: Query st a -> Update st a
liftQuery query
= do st <- get
return (runReader (unQuery query) st)
type EventResult ev = MethodResult ev
type EventState ev = MethodState ev
data Event st where
UpdateEvent :: UpdateEvent ev => (ev -> Update (EventState ev) (EventResult ev)) -> MethodSerialiser ev -> Event (EventState ev)
QueryEvent :: QueryEvent ev => (ev -> Query (EventState ev) (EventResult ev)) -> MethodSerialiser ev -> Event (EventState ev)
class Method ev => UpdateEvent ev
class Method ev => QueryEvent ev
eventsToMethods :: [Event st] -> [MethodContainer st]
eventsToMethods = map worker
where worker :: Event st -> MethodContainer st
worker (UpdateEvent fn ms) = Method (unUpdate . fn) ms
worker (QueryEvent fn ms) = Method (\ev -> do st <- get
return (runReader (unQuery $ fn ev) st)
) ms