diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Author name here (c) 2015
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Author name here nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/operational-extra.cabal b/operational-extra.cabal
new file mode 100644
--- /dev/null
+++ b/operational-extra.cabal
@@ -0,0 +1,32 @@
+name:                operational-extra
+version:             0.1.0.0
+synopsis:            Initial project template from stack
+description:         Please see README.md
+homepage:            http://github.com/andrewthad/vinyl-operational#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Andrew Martin
+maintainer:          andrew.thaddeus@gmail.com
+copyright:           2016 Andrew Martin
+category:            Web
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     Control.Monad.Operational.Interpret
+                       Control.Monad.Operational.Wait
+                       Control.Monad.Operational.Exception
+                       Control.Monad.Operational.Now
+  build-depends:       base >= 4.7 && < 5
+                     , operational
+                     , time
+  default-language:    Haskell2010
+  default-extensions:
+    RankNTypes
+    GADTs
+    ScopedTypeVariables
+
+source-repository head
+  type:     git
+  location: https://github.com/andrewthad/vinyl-operational
diff --git a/src/Control/Monad/Operational/Exception.hs b/src/Control/Monad/Operational/Exception.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Operational/Exception.hs
@@ -0,0 +1,30 @@
+module Control.Monad.Operational.Exception where
+
+import           Control.Exception
+import           Control.Monad.Operational
+import           Data.Typeable
+
+data ExceptionI a where
+  ExceptionI :: SomeException -> ExceptionI a
+
+exception :: SomeException -> ProgramT ExceptionI m a
+exception e = singleton (ExceptionI e)
+
+exception' :: Exception e => e -> ProgramT ExceptionI m a
+exception' e = singleton (ExceptionI (toException e))
+
+toExceptionI :: Exception e => e -> ExceptionI a
+toExceptionI = ExceptionI . toException
+
+strExceptionI :: String -> ExceptionI a
+strExceptionI = toExceptionI . DescribedException
+
+interpretExceptionIO :: ExceptionI a -> IO a
+interpretExceptionIO (ExceptionI e) = throwIO e
+
+data DescribedException = DescribedException String
+  deriving (Show,Typeable)
+
+instance Exception DescribedException
+
+
diff --git a/src/Control/Monad/Operational/Interpret.hs b/src/Control/Monad/Operational/Interpret.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Operational/Interpret.hs
@@ -0,0 +1,42 @@
+module Control.Monad.Operational.Interpret where
+
+import           Control.Applicative
+import           Control.Monad
+import           Control.Monad.Operational
+
+data Around m instr = Around (forall a. instr a -> (m (), a -> m ()))
+
+instance Applicative m => Monoid (Around m instr) where
+  mempty = Around (\_ -> (pure (), \_ -> pure ()))
+  mappend (Around f) (Around g) = Around $ \instr -> let
+    (f1,f2) = f instr
+    (g1,g2) = g instr
+    in (f1 *> g1, f2 *> g2)
+
+mapProgramT :: Monad m => (forall b. instr1 b -> instr2 b) -> ProgramT instr1 (ProgramT instr2 m) a -> ProgramT instr2 m a
+mapProgramT f prog = interpretWithMonadT (singleton . f) prog
+
+interpretWithMonadT :: forall instr m b. Monad m
+  => (forall a. instr a -> m a) -> ProgramT instr m b -> m b
+interpretWithMonadT f = eval <=< viewT
+  where
+  eval :: forall a. ProgramViewT instr m a -> m a
+  eval (Return a) = return a
+  eval (m :>>= k) = f m >>= interpretWithMonadT f . k
+
+interpretAroundMonadT :: forall instr m b. Monad m
+  => (Around m instr)
+  -> (forall a. instr a -> m a)
+  -> ProgramT instr m b
+  -> m b
+interpretAroundMonadT around@(Around aroundFunc) f = eval <=< viewT
+  where
+  eval :: forall a. ProgramViewT instr m a -> m a
+  eval (Return a) = return a
+  eval (m :>>= k) = do
+    before
+    a <- f m
+    after a
+    interpretAroundMonadT around f (k a)
+    where (before,after) = aroundFunc m
+
diff --git a/src/Control/Monad/Operational/Now.hs b/src/Control/Monad/Operational/Now.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Operational/Now.hs
@@ -0,0 +1,28 @@
+module Control.Monad.Operational.Now where
+
+import           Control.Monad.Operational
+import           Data.IORef                (IORef, newIORef, readIORef,
+                                            writeIORef)
+import           Data.Time                 (NominalDiffTime, UTCTime,
+                                            addUTCTime, getCurrentTime)
+
+data NowI a where
+  NowI :: NowI UTCTime
+
+interpretNow :: NowI a -> IO a
+interpretNow NowI = getCurrentTime
+
+interpretNowMoving :: UTCTime -> NominalDiffTime -> IO (NowI a -> IO a)
+interpretNowMoving start interval = do
+  timeRef <- newIORef start
+  return (interpretNowMoving' timeRef interval)
+
+interpretNowMoving' :: IORef UTCTime -> NominalDiffTime -> NowI a -> IO a
+interpretNowMoving' timeRef interval NowI = do
+  time <- readIORef timeRef
+  writeIORef timeRef (addUTCTime interval time)
+  return time
+
+interpretNowConstant :: Applicative m => UTCTime -> NowI a -> m a
+interpretNowConstant time NowI = pure time
+
diff --git a/src/Control/Monad/Operational/Wait.hs b/src/Control/Monad/Operational/Wait.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Operational/Wait.hs
@@ -0,0 +1,19 @@
+module Control.Monad.Operational.Wait where
+
+import           Control.Concurrent        (threadDelay)
+import           Control.Monad.Operational
+
+-- Int is the time in microseconds
+data WaitI a where
+  WaitI :: Int -> WaitI ()
+
+wait :: Int -> ProgramT WaitI m ()
+wait i = singleton (WaitI i)
+
+interpretWaitIO :: WaitI a -> IO a
+interpretWaitIO (WaitI i) = threadDelay i
+
+interpretWaitIgnore :: Applicative m => WaitI a -> m a
+interpretWaitIgnore (WaitI _) = pure ()
+
+
