Playing with event-sourcing
Below is my attempt. I wrote generic serialization using Generics and cereal. So all that's needed is to derive Generic and add empty Serialize instances. Function save first writes the type of the value, which is then checked by load. So when loading a list of events, we can check wich ones belong to the given type we want to change and drop all others (deserializeMany).

I dropped Applicable completely. Usually the problem with existential data types is that there is only a limited set of things you can do with them, so you can replace such a data type directly with the action, like a function that acts on a given object ag -&gt; ag. See also my question Why (or why not) are existential types considered bad practice in functional programming?.

I also changed the open class of events for a given type (open in the sense any module can define additional events for an object) to a closed one - every WithEvent instance has exactly one data type that describes its possible events. This makes it somewhat easier to handle, in particular avoids some cumbersome situations where it's necessary to explicitly give types when applying events, and it's also less verbose.

{-# LANGUAGE DeriveDataTypeable, DeriveGeneric, ScopedTypeVariables,
             TypeFamilies, FlexibleContexts #-}
module Test where

import Control.Monad
import qualified Data.ByteString as BS
import Data.Maybe (catMaybes)
import Data.Typeable
import Data.Serialize
import Data.Maybe (catMaybes)
import GHC.Generics

-- * Generic serialization of events

-- ** Generic serialization of classes that know their type

save :: (Serialize a, Typeable a) =&gt; a -&gt; Put
save x = put (show $ typeOf x) &gt;&gt; put x

-- | Returns 'Nothing' if the serialized event is of a different type.
-- Note that that's different from parsing error.
load :: forall a . (Serialize a, Typeable a) =&gt; Get (Maybe a)
load = do
    t &lt;- get
    if t == show (typeRep (Proxy :: Proxy a))
      then Just &lt;$&gt; get
      else return Nothing -- some other type


serialize :: (Serialize a, Typeable a) =&gt; a -&gt; BS.ByteString
serialize = runPut . save

-- | Read given events and returns the ones that apply to @a@.
deserializeMany :: (Serialize a, Typeable a) =&gt; [BS.ByteString] -&gt; Either String [a]
deserializeMany = liftM catMaybes . mapM (runGet load)

-- ** WithEvent

class (Serialize (Event a), Typeable (Event a)) =&gt; WithEvent a where
    type family Event a
    apply :: Event a -&gt; a -&gt; a

fold :: (WithEvent a) =&gt; [Event a] -&gt; a -&gt; a
fold = flip (foldr apply)

-- * Example

-- ** Foo

data Foo = Foo

data SomeOtherEvent = SomeOtherEvent
  deriving (Show, Read, Typeable, Generic)

instance Serialize SomeOtherEvent where

instance WithEvent Foo where
    type Event Foo = SomeOtherEvent
    apply SomeOtherEvent Foo = Foo

-- ** Person

data Person = Person { name :: String, age :: Int }
  deriving Show

data PersonEvent
    = SetName String
    | SetAge Int
  deriving (Show, Read, Typeable, Generic)

instance Serialize PersonEvent where

instance WithEvent Person where
    type Event Person = PersonEvent
    apply (SetName n) p = p { name = n }
    apply (SetAge a) p = p { age = a }

-- ** Tests

nobody :: Person
nobody = Person "" 0

events :: [PersonEvent]
events = [SetName "Mr.Wrong", SetAge 42]

serialized :: [BS.ByteString]
serialized = serialize SomeOtherEvent : map serialize events

person :: Either String Person -- is `Person {name = "Mr.Wrong", age = 42}`
person = flip fold nobody &lt;$&gt; deserializeMany serialized