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: d5432eeb692ca789729a8cbc13ee3678552e761c8f8fc1bcdb0eb05befc63ab4
+-- hash: b4d9c5533fc659e6801a98a43183cb91426ce81a603cc0267578d5a1cba664ad
 
 name:           dataflower
-version:        0.1.3.0
+version:        0.1.4.0
 synopsis:       A Pure-Haskell Timely Dataflow System
 description:    See README
 homepage:       https://github.com/doublecrowngaming/dataflower#readme
diff --git a/src/Dataflow.hs b/src/Dataflow.hs
--- a/src/Dataflow.hs
+++ b/src/Dataflow.hs
@@ -31,6 +31,7 @@
 ) where
 
 import           Control.Monad              (void)
+import           Control.Monad.IO.Class     (MonadIO (..))
 import           Control.Monad.State.Strict (execStateT, runStateT)
 import           Data.Traversable           (Traversable)
 import           Dataflow.Primitives
@@ -48,15 +49,15 @@
 -- | Take a 'Dataflow' which takes 'i's as input and compile it into a 'Program'.
 --
 -- @since 0.1.0.0
-compile :: Dataflow (Edge i) -> IO (Program i)
-compile (Dataflow actions) = uncurry Program <$> runStateT actions initDataflowState
+compile :: MonadIO io => Dataflow (Edge i) -> io (Program i)
+compile (Dataflow actions) = liftIO $ uncurry Program <$> runStateT actions initDataflowState
 
 -- | Feed a traversable collection of inputs to a 'Program'. All inputs provided will
 -- have the same 'Timestamp' associated with them.
 --
 -- @since 0.1.0.0
-execute :: Traversable t => t i -> Program i -> IO ()
-execute corpus Program{..} = execDataflow feedInput
+execute :: (MonadIO io, Traversable t) => t i -> Program i -> io ()
+execute corpus Program{..} = liftIO $ execDataflow feedInput
   where
     feedInput           = input corpus programInput
     execDataflow action = void $ execStateT (runDataflow action) programState
