In my application I store and load objects from a database (currently a local flat file...). These objects are all from a type family Event a
and are also all serialisable to/from ByteString
. But the a
in the type family can vary...
Here is the base class declaration:
class BusinessModel a where
data Event a :: *
apply :: a -> Event a -> a
And an example implementation, along with needed types:
data User = User { userId :: UserId, userName :: Text } deriving (Eq, Show, Read, Generic)
instance ToJSON User
instance FromJSON User
type UsersView = M.Map UserId User
instance BusinessModel UsersView where
data Event UsersView = NoEvent -- ^A no-op event
| UserRegistered User
deriving (Eq, Show, Read, Generic)
apply v (UserRegistered u) = insert (userId u) u v
apply v _ = v
Here is the current interface to my event store:
class (MonadIO store) => EventStore store where
-- store a single event
store :: Serializable s => s -> store ()
-- load all events from the store
load :: Serializable s => store [s]
Then we need to be able to serialise events (here we simply use the Json representation:
instance ToJSON (Event UsersView)
instance FromJSON (Event UsersView)
instance Serializable (Event UsersView) where
read = fromJust . decode
write = encode
I would like to be able to deserialise all stored Event a
objects, for all a
, then apply each Event a
to the correct a
inside a structure that contains different events "target". When I try to naively use load
I run into the trouble of having multiple instances of Serializable
and not being able to chose the right one.
Out of the top of my head, I could think of a simple solution: Tag every event to be read with the proper a
it pertains to, but this does not seem very elegant?
What is the best approach to this kind of problem?