diff --git a/dataflower.cabal b/dataflower.cabal
--- a/dataflower.cabal
+++ b/dataflower.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: c36b2b11b6e3244c6cf8d82e5ffb803aa706157c2751aa29fdea8d10815cbfc3
+-- hash: 9d147f4f1bd73d431e7656ae023cb460b458b917a64239625a7673a5ec972915
 
 name:           dataflower
-version:        0.2.3.0
+version:        0.3.0.0
 synopsis:       A Pure-Haskell Timely Dataflow System
 description:    See README
 homepage:       https://github.com/doublecrowngaming/dataflower#readme
diff --git a/src/Dataflow/Primitives.hs b/src/Dataflow/Primitives.hs
--- a/src/Dataflow/Primitives.hs
+++ b/src/Dataflow/Primitives.hs
@@ -30,10 +30,10 @@
 import           Control.Monad.State.Strict (StateT, get, gets, modify)
 import           Control.Monad.Trans        (lift)
 import           Data.Hashable              (Hashable (..))
-import           Data.IORef                 (IORef, atomicModifyIORef',
-                                             atomicWriteIORef, newIORef,
-                                             readIORef)
+import           Data.IORef                 (IORef, modifyIORef', newIORef,
+                                             readIORef, writeIORef)
 import           Data.Vector                (Vector, empty, snoc, unsafeIndex)
+import           GHC.Exts                   (Any)
 import           Numeric.Natural            (Natural)
 import           Prelude
 import           Unsafe.Coerce              (unsafeCoerce)
@@ -68,16 +68,9 @@
   inc (Epoch n) = Epoch (n + 1)
 
 
--- | 'ErasedType' erases the type it wraps.
-data ErasedType = forall i. EraseType i
-
-unEraseType :: ErasedType -> a
-unEraseType (EraseType x) = unsafeCoerce x
-
-
 data DataflowState = DataflowState {
-  dfsVertices       :: Vector ErasedType,
-  dfsStates         :: Vector (IORef ErasedType),
+  dfsVertices       :: Vector Any,
+  dfsStates         :: Vector (IORef Any),
   dfsFinalizers     :: [Timestamp -> Dataflow ()],
   dfsLastVertexID   :: VertexID,
   dfsLastStateID    :: StateID,
@@ -135,7 +128,7 @@
   Dataflow $ do
     vertices <- gets dfsVertices
 
-    return $ unEraseType (vertices `unsafeIndex` vindex)
+    return $ unsafeCoerce (vertices `unsafeIndex` vindex)
 
 -- | Store a provided vertex and obtain an 'Edge' that refers to it.
 registerVertex :: Vertex i -> Dataflow (Edge i)
@@ -149,7 +142,7 @@
 
   where
     addVertex vtx vid s = s {
-      dfsVertices     = dfsVertices s `snoc` EraseType vtx,
+      dfsVertices     = dfsVertices s `snoc` unsafeCoerce vtx,
       dfsLastVertexID = vid
     }
 
@@ -170,7 +163,7 @@
 newState a =
   Dataflow $ do
     sid   <- gets (dfsLastStateID >>> inc)
-    ioref <- lift $ newIORef (EraseType a)
+    ioref <- lift $ newIORef (unsafeCoerce a)
 
     modify $ addState ioref sid
 
@@ -182,7 +175,7 @@
       dfsLastStateID = sid
     }
 
-lookupStateRef :: StateRef s -> Dataflow (IORef ErasedType)
+lookupStateRef :: StateRef s -> Dataflow (IORef Any)
 lookupStateRef (StateRef (StateID sindex)) =
   Dataflow $ do
     states <- gets dfsStates
@@ -195,7 +188,7 @@
 readState :: StateRef a -> Dataflow a
 readState sref = do
   ioref <- lookupStateRef sref
-  Dataflow $ lift $ (unEraseType <$> readIORef ioref)
+  Dataflow $ lift (unsafeCoerce <$> readIORef ioref)
 
 -- | Overwrite the value stored in the `StateRef`.
 --
@@ -203,7 +196,7 @@
 writeState :: StateRef a -> a -> Dataflow ()
 writeState sref x = do
   ioref <- lookupStateRef sref
-  Dataflow $ lift $ atomicWriteIORef ioref (EraseType x)
+  Dataflow $ lift $ writeIORef ioref (unsafeCoerce x)
 
 -- | Update the value stored in `StateRef`.
 --
@@ -211,7 +204,7 @@
 modifyState :: StateRef a -> (a -> a) -> Dataflow ()
 modifyState sref op = do
   ioref <- lookupStateRef sref
-  Dataflow $ lift $ atomicModifyIORef' ioref (\x -> (EraseType $ op (unEraseType x), ()))
+  Dataflow $ lift $ modifyIORef' ioref (unsafeCoerce . op . unsafeCoerce)
 
 {-# INLINEABLE input #-}
 input :: Traversable t => t i -> Edge i -> Dataflow ()
