diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,11 +3,11 @@
 [![Build Status](https://travis-ci.org/schell/varying.svg)](https://travis-ci.org/schell/varying)
 
 This library provides automaton based value streams useful for both functional
-reactive programming (FRP) and locally stateful programming (LSP). It is 
-influenced by the [netwire](http://hackage.haskell.org/package/netwire) and 
-[auto](http://hackage.haskell.org/package/auto) packages. Unlike netwire the 
-concepts of inhibition and time are explicit (through `Control.Varying.Event` 
-and `Control.Varying.Time`). The library aims at being minimal and well 
+reactive programming (FRP) and locally stateful programming (LSP). It is
+influenced by the [netwire](http://hackage.haskell.org/package/netwire) and
+[auto](http://hackage.haskell.org/package/auto) packages. Unlike netwire the
+concepts of inhibition and time are explicit (through `Control.Varying.Event`
+and `Control.Varying.Time`). The library aims at being minimal and well
 documented with a small API.
 
 ## Getting started
@@ -80,3 +80,55 @@
                           loop vNext
 
 ```
+
+## Caveats
+With tweening, if your input time delta is greater than the duration of the
+first spline, that spline immediately concludes and returns its result value -
+the stream then continues on to the next spline in the sequence, *applying the
+same unmodified input* as the previous spline. This is because splines
+immediately conclude and trigger the next spline, and there is no machinery for
+altering input after the splines conclusion. What's worse is if you have a
+cyclical (infinite) sequence of spline tweens, each with a duration less than
+the given delta - the stream will never produce an output. The input will
+conclude every spline prematurely and the stream will loop infinitely, hanging
+the current thread.
+
+### Here is an example
+
+```haskell
+let dv :: Monad m => SplineT Float (V2 Float) m ()
+    dv = do tween_ easeInExpo 10          (V2 100 10) 0.25
+            tween_ easeInExpo (V2 100 10) 100         0.25
+            tween_ easeInExpo 100         (V2 10 100) 0.25
+            tween_ easeInExpo (V2 10 100) 10          0.25
+            dv
+    v :: Monad m => VarT m Float (V2 Float)
+    v = (deltaTime ~> outputStream dv 0)
+(vec2, v1) <- runVarT v 0.5 -- hangs indefinitely
+```
+
+Surprisingly enough, this is expected behavior (inputs that conclude the
+current spline should be passed downstream immediately), but the behavior isn't
+easily spotted. If you encounter your program hanging check to see that your
+cyclical splines aren't receiving an input that is bigger than they expect.
+
+### A very easy fix
+There is a very simple fix for this scenario - produce exactly one duplicate
+output just before recursing:
+
+```haskell
+let dv :: Monad m => SplineT Float (V2 Float) m ()
+    dv = do tween_ easeInExpo 10          (V2 100 10) 0.25
+            tween_ easeInExpo (V2 100 10) 100         0.25
+            tween_ easeInExpo 100         (V2 10 100) 0.25
+            vec <- tween easeInExpo (V2 10 100) 10 0.25
+            step vec -- <----------------------------\
+            dv                                    -- |
+    v :: Monad m => VarT m Float (V2 Float)       -- |
+    v = (deltaTime ~> outputStream dv 0)          -- |
+(vec, v1) <- runVarT v 0.5  -- will produce 'vec' ---/
+```
+
+The downside is that this is not mathematically accurate - the delta will be
+completely consumed and the stream will output the last position even though
+the delta was not necessarily an amount great enough to warrant that output.
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -2,7 +2,7 @@
 
 import Control.Varying
 import Control.Applicative
-import Text.Printf
+import Control.Concurrent (forkIO, killThread)
 import Data.Functor.Identity
 import Data.Time.Clock
 
@@ -20,7 +20,7 @@
 tweenx :: (Applicative m, Monad m) => SplineT Float Float m Float
 tweenx = do
     -- Tween from 0 to 100 over 1 second
-    x <- tween easeOutExpo 0 100 1
+    x <- tween easeOutExpo 0 50 1
     -- Chain another tween back to the starting position
     _ <- tween easeOutExpo x 0 1
     -- Loop forever
@@ -30,16 +30,16 @@
 -- ends.
 tweeny :: (Applicative m, Monad m) => SplineT Float Float m Float
 tweeny = do
-    y <- tween easeOutQuad 0 100 1
-    _ <- tween easeOutQuad y 0 1
+    y <- tween easeOutExpo 50 0 1
+    _ <- tween easeOutExpo y 50 1
     tweeny
 
 -- Our time signal counts input delta time samples.
-time :: Monad m => VarT m Delta Float
+time :: (Applicative m, Monad m) => VarT m Delta Float
 time = var unDelta
 
 -- | Our Point value that varies over time continuously in x and y.
-backAndForth :: Monad m => VarT m Delta Point
+backAndForth :: (Applicative m, Monad m) => VarT m Delta Point
 backAndForth =
     -- Turn our splines into continuous output streams. We must provide
     -- a starting value since splines are not guaranteed to be defined at
@@ -58,14 +58,30 @@
 main :: IO ()
 main = do
     putStrLn "An example of value streams using the varying library."
-    putStrLn "Enter a newline to continue, quit with ctrl+c"
+    putStrLn "Enter a newline to continue, and then a newline to quit"
     _ <- getLine
-    utc0 <- getCurrentTime
 
-    loop backAndForth utc0
-        where loop v utc1 = do utc2 <- getCurrentTime
-                               let dt = realToFrac $ diffUTCTime utc2 utc1
-                               (point, vNext) <- runVarT v $ Delta dt
-                               printf "\nPoint %03.1f %03.1f" (px point) (py point)
-                               loop vNext utc2
+    t   <- getCurrentTime
+    tId <- forkIO $ loop backAndForth t
+
+    _ <- getLine
+    killThread tId
+
+loop :: Var Delta Point -> UTCTime -> IO ()
+loop v t = do
+  t1 <- getCurrentTime
+  -- Here we'll run in the Identity monad using a fixed time step.
+  let dt = realToFrac $ diffUTCTime t1 t
+      Identity (Point x y, vNext) = runVarT v $ Delta dt
+      xStr = replicate (round x) ' ' ++ "x" ++ replicate (50 - round x) ' '
+      yStr = replicate (round y) ' ' ++ "y" ++ replicate (50 - round y) ' '
+      str  = zipWith f xStr yStr
+      f 'x' 'y' = '|'
+      f 'y' 'x' = '|'
+      f a ' ' = a
+      f ' ' b = b
+      f _ _ = ' '
+  putStrLn str
+  --threadDelay 10
+  loop vNext t1
 
diff --git a/bench/Main.hs b/bench/Main.hs
--- a/bench/Main.hs
+++ b/bench/Main.hs
@@ -1,12 +1,10 @@
 import Control.Varying
+import Control.Monad
 import Criterion.Main
-import Debug.Trace
 
 main :: IO ()
 main = do
-    let v :: Var Int Int
-        v = var (+1)
-        run v a = fst <$> runVarT v a
+    let run v a = fst <$> runVarT v a
     defaultMain $ [ bgroup "runVarT" [ bench "1" $ nf (run $ chain 1) 0
                                      , bench "2" $ nf (run $ chain 2) 0
                                      , bench "4" $ nf (run $ chain 4) 0
@@ -16,9 +14,19 @@
                                      , bench "64" $ nf (run $ chain 64) 0
                                      , bench "128" $ nf (run $ chain 128) 0
                                      ]
+                  , bgroup "SplineT"
+                      [ bench "runSplineT" $
+                          nf (run $ outputStream spline 0) 0
+                      ]
                   ]
     return ()
 
 chain :: Int -> Var Int Int
 chain n = seq x x
   where x = foldl (~>) (var (+1)) $ take (n - 1) $ cycle [var (+1)]
+
+spline :: Spline Float Float ()
+spline = do
+  void $ tween easeInExpo 0 100 1
+  void $ tween easeOutExpo 100 0 1
+  spline
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -13,5 +13,10 @@
 0.4.0.0 - Var and Spline are now parameterized with Identity, removed mix, changed
           the behavior of race, added untilEvent variants, added tests
 
-0.5.0.0 - changed stepMany to remove Monoid requirement, added raceMany, added 
+0.5.0.0 - changed stepMany to remove Monoid requirement, added raceMany, added
           anyE, more tests and SplineT obeys Applicative and Monad laws
+
+0.5.0.1 - removed time as dependency
+
+0.5.0.2 - separated tweening time and value, added runSplineE, builds on all GHC
+          since 7.6
diff --git a/src/Control/Varying/Core.hs b/src/Control/Varying/Core.hs
--- a/src/Control/Varying/Core.hs
+++ b/src/Control/Varying/Core.hs
@@ -124,10 +124,10 @@
 
 -- | Run the stream over the input values, gathering the output values in a
 -- list.
-scanVar :: (Applicative m, Monad m) => VarT m a b -> [a] -> m [b]
-scanVar v = liftM snd . foldM f (v,[])
-    where f (v', outs) a = do (b, v'') <- runVarT v' a
-                              return (v'', outs ++ [b])
+scanVar :: (Applicative m, Monad m) => VarT m a b -> [a] -> m ([b], VarT m a b)
+scanVar v = foldM f ([], v)
+    where f (outs, v') a = do (b, v'') <- runVarT v' a
+                              return (outs ++ [b], v'')
 --------------------------------------------------------------------------------
 -- Testing and debugging
 --------------------------------------------------------------------------------
@@ -150,7 +150,7 @@
 --------------------------------------------------------------------------------
 -- | Accumulates input values using a folding function and yields
 -- that accumulated value each sample.
-accumulate :: Monad m => (c -> b -> c) -> c -> VarT m b c
+accumulate :: (Monad m, Applicative m) => (c -> b -> c) -> c -> VarT m b c
 accumulate f b = VarT $ \a -> do
     let b' = f b a
     return (b', accumulate f b')
@@ -160,7 +160,7 @@
 -- themselves for values. For example:
 --
 -- > let v = 1 + delay 0 v in testVar_ v
-delay :: Monad m => b -> VarT m a b -> VarT m a b
+delay :: (Monad m, Applicative m) => b -> VarT m a b -> VarT m a b
 delay b v = VarT $ \a -> return (b, go a v)
     where go a v' = VarT $ \a' -> do (b', v'') <- runVarT v' a
                                      return (b', go a' v'')
@@ -173,10 +173,10 @@
 -- The "left plug" does the same thing in the opposite direction. This allows
 -- you to write value streams that read naturally.
 --------------------------------------------------------------------------------
-(~>) :: Monad m => VarT m a b -> VarT m b c -> VarT m a c
+(~>) :: (Monad m, Applicative m) => VarT m a b -> VarT m b c -> VarT m a c
 (~>) = (>>>)
 
-(<~) :: Monad m => VarT m b c -> VarT m a b -> VarT m a c
+(<~) :: (Monad m, Applicative m) => VarT m b c -> VarT m a b -> VarT m a c
 (<~) = (<<<)
 --------------------------------------------------------------------------------
 -- Typeclass instances
@@ -282,11 +282,10 @@
 -- input. It's a kind of Mealy machine (an automaton) with effects. Using
 -- 'runVarT' with an input value of type 'a' yields a "step", which is a value
 -- of type 'b' and a new 'VarT' for yielding the next value.
-data VarT m a b where
-  Done :: b -> VarT m a b
-          -- ^ Given a value, return a computation that yields a constant value
-          -- forever. You can also do this with the function 'done'.
-  VarT :: (a -> m (b, VarT m a b)) -> VarT m a b
-          -- ^ Given an input value, return a computation that effectfully
-          -- produces an output value and a new stream for producing the next
-          -- sample.
+data VarT m a b = Done b
+                  -- ^ Given a value, return a computation that yields a constant value
+                  -- forever. You can also do this with the function 'done'.
+                | VarT (a -> m (b, VarT m a b))
+                  -- ^ Given an input value, return a computation that effectfully
+                  -- produces an output value and a new stream for producing the next
+                  -- sample.
diff --git a/src/Control/Varying/Event.hs b/src/Control/Varying/Event.hs
--- a/src/Control/Varying/Event.hs
+++ b/src/Control/Varying/Event.hs
@@ -174,7 +174,7 @@
 -- | Combine two event streams and produce an event any time either stream
 -- produces. In the case that both streams produce, this produces the event of
 -- the left stream.
-anyE :: Monad m => [VarT m a (Event b)] -> VarT m a (Event b)
+anyE :: (Applicative m, Monad m) => [VarT m a (Event b)] -> VarT m a (Event b)
 anyE [] = never
 anyE vs = VarT $ \a -> do
   outs <- mapM (`runVarT` a) vs
diff --git a/src/Control/Varying/Spline.hs b/src/Control/Varying/Spline.hs
--- a/src/Control/Varying/Spline.hs
+++ b/src/Control/Varying/Spline.hs
@@ -19,12 +19,17 @@
 {-# LANGUAGE GADTs #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE TupleSections #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE CPP #-}
 module Control.Varying.Spline (
     -- * Spline
     Spline,
     -- * Spline Transformer
     SplineT(..),
+    -- * Running and streaming
     runSplineT,
+    runSplineE,
     scanSpline,
     outputStream,
     resultStream,
@@ -60,23 +65,35 @@
 -- Much like the State monad it has an "internal state" and an eventual
 -- result value, where the internal state is the output value. The result
 -- value is used only in determining the next spline to sequence.
-data SplineT a b m c where
-  Pass :: c -> SplineT a b m c
-  SplineT :: VarT m a (b, Event c) -> SplineT a b m c
+data SplineT a b m c = Pass c
+                     | SplineT (VarT m a (b, Event c))
 
 -- | Convert a spline into a stream of output value and eventual result value
 -- tuples. Requires a default output value in case none are produced.
-runSplineT :: Monad m => SplineT a b m c -> b -> VarT m a (b, Event c)
+runSplineT :: (Applicative m, Monad m) => SplineT a b m c -> b -> VarT m a (b, Event c)
+--runSplineT (SplineT v) _ = VarT $ runVarT v >=> \case
+--  ((b,NoEvent), v1) -> return ((b,NoEvent), runSplineT (SplineT v1) b)
+--  ((b,Event c), _)  -> return ((b, Event c), runSplineT (Pass c) b)
 runSplineT (Pass c) b = pure (b, Event c)
 runSplineT (SplineT v) _ = VarT $ \a -> do
   (o@(b,ec), v1) <- runVarT v a
-  let s = case ec of
-              NoEvent -> SplineT v1
-              Event c -> Pass c
+  let !s = case ec of
+             NoEvent -> SplineT v1
+             Event c -> Pass c
   return (o, runSplineT s b)
 
+-- | Run a spline without converting it into a stream. Produces either an output
+-- value on the left or the result value on the right.
+runSplineE :: Monad m => SplineT a b m c -> a -> m (Either b c, SplineT a b m c)
+runSplineE (Pass c) _ = return (Right c, Pass c)
+runSplineE (SplineT v) a = do
+  ((b, ev), v1) <- runVarT v a
+  return $ case ev of
+    NoEvent -> (Left b, SplineT v1)
+    Event c -> (Right c, Pass c)
+
 -- | A spline is a functor by applying the function to the result.
-instance Monad m => Functor (SplineT a b m) where
+instance (Applicative m, Monad m) => Functor (SplineT a b m) where
   fmap f (Pass c) = Pass $ f c
   fmap f (SplineT v) = SplineT (((f <$>) <$>) <$> v)
 
@@ -84,7 +101,7 @@
 -- output value and immediately returns the argument. It responds to '<*>' by
 -- applying the left arguments result value (the function) to the right
 -- arguments result value (the argument), sequencing them both in serial.
-instance Monad m => Applicative (SplineT a b m) where
+instance (Applicative m, Monad m) => Applicative (SplineT a b m) where
   pure = Pass
   (Pass f) <*> (Pass x) = Pass $ f x
   (Pass f) <*> (SplineT v) = f <$> SplineT v
@@ -96,7 +113,7 @@
 
 -- | A spline responds to bind by running until it produces an eventual value,
 -- then uses that value to run the next spline.
-instance Monad m => Monad (SplineT a b m) where
+instance (Applicative m, Monad m) => Monad (SplineT a b m) where
   return = Pass
   (Pass x) >>= f = f x
   (SplineT v) >>= f = SplineT $ VarT $ \a -> do
@@ -105,20 +122,22 @@
       NoEvent -> return ((b, NoEvent), runSplineT (SplineT v1 >>= f) b)
       Event c -> runVarT (runSplineT (f c) b) a
 
+#if MIN_VERSION_base(4,8,0)
 -- | A spline is a transformer if its output type is a Monoid.
 instance Monoid b => MonadTrans (SplineT a b) where
   lift = effect mempty
 
 -- | A spline can do IO if its underlying monad has a MonadIO instance. It
 -- takes the result of the IO action as its immediate return value.
-instance (Monoid b, Monad m, MonadIO m) => MonadIO (SplineT a b m) where
+instance (Monoid b, Applicative m, Monad m, MonadIO m) => MonadIO (SplineT a b m) where
   liftIO = lift . liftIO
+#endif
 
 -- | Run the spline over the input values, gathering the output and result
 -- values in a list.
 scanSpline :: (Applicative m, Monad m)
            => SplineT a b m c -> b -> [a] -> m [b]
-scanSpline s b = scanVar (outputStream s b)
+scanSpline s b = fmap fst <$> scanVar (outputStream s b)
 
 -- | A SplineT monad parameterized with Identity that takes input of type @a@,
 -- output of type @b@ and a result value of type @c@.
@@ -134,7 +153,7 @@
 resultStream s b = snd <$> runSplineT s b
 
 -- | Create a spline from an event stream.
-fromEvent :: Monad m => VarT m a (Event b) -> SplineT a (Event b) m b
+fromEvent :: (Applicative m, Monad m) => VarT m a (Event b) -> SplineT a (Event b) m b
 fromEvent ve = SplineT $ f <$> ve
   where f e = (e,e)
 
@@ -257,7 +276,7 @@
 mapOutput _ (Pass c) = Pass c
 
 -- | Map the input value of a spline.
-adjustInput :: (Monad m)
+adjustInput :: (Applicative m, Monad m)
             => VarT m a (a -> r) -> SplineT r b m c -> SplineT a b m c
 adjustInput vf (SplineT vx) = SplineT $ VarT $ \a -> do
     (f, vf1) <- runVarT vf a
diff --git a/src/Control/Varying/Tween.hs b/src/Control/Varying/Tween.hs
--- a/src/Control/Varying/Tween.hs
+++ b/src/Control/Varying/Tween.hs
@@ -20,6 +20,7 @@
     -- * Creating tweens
     -- $creation
     tween,
+    tween_,
     constant,
     timeAsPercentageOf,
     -- * Interpolation functions
@@ -60,68 +61,68 @@
 --------------------------------------------------------------------------------
 
 -- | Ease in quadratic.
-easeInQuad :: Num t => Easing t
-easeInQuad c t b =  c * t*t + b
+easeInQuad :: (Num t, Fractional t, Real f) => Easing t f
+easeInQuad c t b =  c * (realToFrac $ t*t) + b
 
 -- | Ease out quadratic.
-easeOutQuad :: Num t => Easing t
-easeOutQuad c t b =  (-c) * (t * (t - 2)) + b
+easeOutQuad :: (Num t, Fractional t, Real f) => Easing t f
+easeOutQuad c t b =  (-c) * (realToFrac $ t * (t - 2)) + b
 
 -- | Ease in cubic.
-easeInCubic :: Num t => Easing t
-easeInCubic c t b =  c * t*t*t + b
+easeInCubic :: (Num t, Fractional t, Real f) => Easing t f
+easeInCubic c t b =  c * (realToFrac $ t*t*t) + b
 
 -- | Ease out cubic.
-easeOutCubic :: Num t => Easing t
-easeOutCubic c t b =  let t' = t - 1 in c * (t'*t'*t' + 1) + b
+easeOutCubic :: (Num t, Fractional t, Real f) => Easing t f
+easeOutCubic c t b =  let t' = realToFrac t - 1 in c * (t'*t'*t' + 1) + b
 
 -- | Ease in by some power.
-easeInPow :: Num t => Int -> Easing t
-easeInPow power c t b =  c * (t^power) + b
+easeInPow :: (Num t, Fractional t, Real f) => Int -> Easing t f
+easeInPow power c t b =  c * (realToFrac t^power) + b
 
 -- | Ease out by some power.
-easeOutPow :: Num t => Int -> Easing t
+easeOutPow :: (Num t, Fractional t, Real f) => Int -> Easing t f
 easeOutPow power c t b =
-    let t' = t - 1
+    let t' = realToFrac t - 1
         c' = if power `mod` 2 == 1 then c else -c
         i  = if power `mod` 2 == 1 then 1 else -1
     in c' * ((t'^power) + i) + b
 
 -- | Ease in sinusoidal.
-easeInSine :: Floating t => Easing t
-easeInSine c t b =  let cos' = cos (t * (pi / 2))
+easeInSine :: (Floating t, Real f) => Easing t f
+easeInSine c t b =  let cos' = cos (realToFrac t * (pi / 2))
                                in -c * cos' + c + b
 
 -- | Ease out sinusoidal.
-easeOutSine :: Floating t => Easing t
-easeOutSine c t b =  let cos' = cos (t * (pi / 2)) in c * cos' + b
+easeOutSine :: (Floating t, Real f) => Easing t f
+easeOutSine c t b =  let cos' = cos (realToFrac t * (pi / 2)) in c * cos' + b
 
 -- | Ease in and out sinusoidal.
-easeInOutSine :: Floating t => Easing t
-easeInOutSine c t b =  let cos' = cos (pi * t)
+easeInOutSine :: (Floating t, Real f) => Easing t f
+easeInOutSine c t b =  let cos' = cos (pi * realToFrac t)
                                   in (-c / 2) * (cos' - 1) + b
 
 -- | Ease in exponential.
-easeInExpo :: Floating t => Easing t
-easeInExpo c t b =  let e = 10 * (t - 1) in c * (2**e) + b
+easeInExpo :: (Floating t, Real f) => Easing t f
+easeInExpo c t b =  let e = 10 * (realToFrac t - 1) in c * (2**e) + b
 
 -- | Ease out exponential.
-easeOutExpo :: Floating t => Easing t
-easeOutExpo c t b =  let e = -10 * t in c * (-(2**e) + 1) + b
+easeOutExpo :: (Floating t, Real f) => Easing t f
+easeOutExpo c t b =  let e = -10 * realToFrac t in c * (-(2**e) + 1) + b
 
 -- | Ease in circular.
-easeInCirc :: Floating t => Easing t
-easeInCirc c t b = let s = sqrt (1 - t*t) in -c * (s - 1) + b
+easeInCirc :: (Floating t, Real f, Floating f) => Easing t f
+easeInCirc c t b = let s = realToFrac $ sqrt (1 - t*t) in -c * (s - 1) + b
 
 -- | Ease out circular.
-easeOutCirc :: Floating t => Easing t
-easeOutCirc c t b = let t' = (t - 1)
+easeOutCirc :: (Floating t, Real f) => Easing t f
+easeOutCirc c t b = let t' = (realToFrac t - 1)
                         s  = sqrt (1 - t'*t')
                     in c * s + b
 
 -- | Ease linear.
-linear :: Num t => Easing t
-linear c t b = c * t + b
+linear :: (Floating t, Real f) => Easing t f
+linear c t b = c * (realToFrac t) + b
 
 --------------------------------------------------------------------------------
 -- $creation
@@ -145,8 +146,8 @@
 -- Keep in mind `tween` must be fed time deltas, not absolute time or
 -- duration. This is mentioned because the author has made that mistake
 -- more than once ;)
-tween :: (Applicative m, Monad m, Fractional t, Ord t)
-      => Easing t -> t -> t -> t -> SplineT t t m t
+tween :: (Applicative m, Monad m, Num t, Fractional f, Ord f)
+      => Easing t f -> t -> t -> f -> SplineT f t m t
 tween f start end dur =
   let c = end - start
       b = start
@@ -156,6 +157,15 @@
             else (f c t b, NoEvent)
   in SplineT vt
 
+-- | A version of 'tween' that discards the result. It is simply
+--
+-- @
+-- tween f a b c >> return ()
+-- @
+--
+tween_ :: (Applicative m, Monad m, Num t, Fractional f, Ord f)
+       => Easing t f -> t -> t -> f -> SplineT f t m ()
+tween_ f a b c = tween f a b c >> return ()
 
 -- | Creates a tween that performs no interpolation over the duration.
 constant :: (Applicative m, Monad m, Num t, Ord t)
@@ -186,9 +196,9 @@
 -- To make things simple only numerical values can be tweened and the type
 -- of time deltas much match the tween's value type. This may change in the
 -- future :)
-type Easing t = t -> t -> t -> t
+type Easing t f = t -> f -> t -> t
 
 -- | A linear interpolation between two values over some duration.
 -- A `Tween` takes three values - a start value, an end value and
 -- a duration.
-type Tween m t = t -> t -> t -> VarT m t (Event t)
+type Tween m t f = t -> t -> f -> VarT m f (Event t)
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -2,6 +2,7 @@
 
 import Test.Hspec hiding (after, before)
 import Test.QuickCheck
+import Control.Applicative
 import Control.Varying
 import Data.Functor.Identity
 import Data.Time.Clock
@@ -11,29 +12,34 @@
 main = hspec $ do
   describe "before" $ do
     it "should produce events before a given step" $ do
-      let Identity scans = scanVar (1 ~> before 3) $ replicate 4 ()
+      let varEv :: Var () (Event Int)
+          varEv = 1 ~> before 3
+          scans = fst $ runIdentity $ scanVar varEv $ replicate 4 ()
       scans `shouldBe` [Event 1, Event 2, NoEvent, NoEvent]
 
   describe "after" $ do
     it "should produce events after a given step" $ do
-      let Identity scans = scanVar (1 ~> after 3) $ replicate 4 ()
+      let varEv :: Var () (Event Int)
+          varEv = 1 ~> after 3
+          scans = fst $ runIdentity $ scanVar varEv $ replicate 4 ()
       scans `shouldBe` [NoEvent, NoEvent, Event 3, Event 4]
   describe "anyE" $ do
     it "should produce on any event" $ do
-      let v1 = use 1 (1 ~> before 2)
+      let v1,v2,v3 :: Var () (Event Int)
+          v1 = use 1 (1 ~> before 2)
           v2 = use 2 (1 ~> after 3)
           v3 = always 3
           v = anyE [v1,v2,v3]
-          Identity scans = scanVar v $ replicate 4 ()
+          scans = fst $ runIdentity $ scanVar v $ replicate 4 ()
       scans `shouldBe` [Event 1, Event 3, Event 2, Event 2]
   describe "timeAsPercentageOf" $ do
       it "should run past 1.0" $ do
-          let Identity scans = scanVar (timeAsPercentageOf 4)
-                                       [1,1,1,1,1 :: Float]
+          let scans = fst $ runIdentity $ scanVar (timeAsPercentageOf 4)
+                                                  [1,1,1,1,1 :: Float]
           last scans `shouldSatisfy` (> 1)
       it "should progress by increments of the total" $ do
-          let Identity scans = scanVar (timeAsPercentageOf 4)
-                                       [1,1,1,1,1 :: Float]
+          let scans = fst $ runIdentity $ scanVar (timeAsPercentageOf 4)
+                                                  [1,1,1,1,1 :: Float]
           scans `shouldBe` [0.25,0.5,0.75,1.0,1.25 :: Float]
 
   describe "tween" $
@@ -119,9 +125,9 @@
                  case x of
                    (Just "b", 2) -> step "True"
                    _ -> step "False"
-          scans = scanSpline r "" $ replicate 3 ()
+          Identity scans = scanSpline r "" $ replicate 3 ()
       it "should end with the last value captured" $
-          unwords (concat scans) `shouldBe` "a b True"
+          unwords scans `shouldBe` "a b True"
 
   describe "mapOutput" $ do
       let s :: Spline a Char ()
@@ -150,7 +156,7 @@
   let inc = 1 ~> accumulate (+) 0
       sinc :: Spline a Int (Int, Int)
       sinc = inc `untilEvent` (1 ~> after 3)
-      go a = scanSpline a 0 [0..9]
+      go a = runIdentity (scanSpline a 0 [0..9])
       equal a b = go a `shouldBe` go b
 
   describe "spline's functor instance" $ do
@@ -171,13 +177,13 @@
         pfx = pure (1+1)
     it "(homomorphism) pure f <*> pure x = pure (f x)" $ equal pfpx pfx
     let u :: Spline a Int (Int -> Int)
-        u = pure 66 `_untilEvent` (use (+1) $ 1 ~> after 3)
+        u = pure 66 `_untilEvent` (use (+1) $ 1 ~> after (3 :: Int))
         upy = u <*> pure 1
         pyu = pure ($ 1) <*> u
     it "(interchange) u <*> pure y = pure ($ y) <*> u" $ equal upy pyu
     let v :: Spline a Int (Int -> Int)
-        v = pure 66 `_untilEvent` (use (1-) $ 1 ~> after 4)
-        w = pure 72 `_untilEvent` (use 3 $ 1 ~> after 1)
+        v = pure 66 `_untilEvent` (use (1-) $ 1 ~> after (4 :: Float))
+        w = pure 72 `_untilEvent` (use 3 $ 1 ~> after (1 :: Float))
         pduvw = pure (.) <*> u <*> v <*> w
         uvw = u <*> (v <*> w)
     it "(compisition) pure (.) <*> u <*> v <*> w = u <*> (v <*> w)" $
@@ -192,14 +198,14 @@
     it "(right identity w/ const) m >>= return == m" $ equal (p >>= return) p
     it "(right identity) m >>= return == m" $ equal h hr
     it "(right identity w/ monadic results) m >>= return == m" $
-      (scanVar (runSplineT h 0) [0..9])
-        `shouldBe` scanVar (runSplineT hr 0) [0..9]
+      runIdentity (scanSpline h 0 [0..9 :: Int])
+        `shouldBe` runIdentity (scanSpline hr 0 [0..9 :: Int])
     let f :: Int -> Spline a String Bool
         f x = do mapM_ (step . show) [0..x]
                  return True
     it "(left identity) return a >>= f == f a" $
-      (scanVar (runSplineT (return 3 >>= f) "") [0..9])
-        `shouldBe` scanVar (runSplineT (f 3) "") [0..9]
+      runIdentity (scanSpline (return 3 >>= f) "" [0..9 :: Int])
+        `shouldBe` runIdentity (scanSpline (f 3) "" [0..9 :: Int])
     let m :: Spline a String Int
         m = do step "hey"
                step "dude"
@@ -210,5 +216,5 @@
         g False = do step "dang"
                      step "missed it"
     it "(associativity) (m >>= f) >>= g == m >>= (\\x -> f x >>= g)" $
-      (scanVar (runSplineT ((m >>= f) >>= g) "") [0..9])
-        `shouldBe` scanVar (runSplineT (m >>= (\x -> f x >>= g)) "") [0..9]
+      runIdentity (scanSpline ((m >>= f) >>= g) "" [0..9 :: Int])
+        `shouldBe` runIdentity (scanSpline (m >>= (\x -> f x >>= g)) "" [0..9 :: Int])
diff --git a/varying.cabal b/varying.cabal
--- a/varying.cabal
+++ b/varying.cabal
@@ -10,7 +10,7 @@
 -- PVP summary:      +-+------- breaking API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:             0.5.0.0
+version:             0.5.0.2
 
 -- A short (one-line) description of the package.
 synopsis:            FRP through value streams and monadic splines.
@@ -75,9 +75,8 @@
   -- other-extensions:
 
   -- Other library packages from which modules are imported.
-  build-depends:       base >=4.7 && <4.9,
-                       time >=1.5 && <1.6,
-                       transformers >= 0.4 && <0.5
+  build-depends:       base >=4.6 && <5.0
+                     , transformers >=0.3
 
   -- Directories containing source files.
   hs-source-dirs:      src
@@ -89,10 +88,10 @@
   ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N
 
   -- Other library packages from which modules are imported.
-  build-depends:       base >=4.7 && <4.9,
-                       time >=1.5 && <1.6,
-                       transformers >= 0.4 && <0.5,
-                       varying
+  build-depends:       base >=4.6 && <5.0
+                     , transformers >=0.3
+                     , time >=1.4
+                     , varying
 
 
   -- Directories containing source files.
@@ -108,8 +107,8 @@
   ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N
 
   -- Other library packages from which modules are imported.
-  build-depends:       base >=4.7 && <4.9
-                     , time >=1.5 && <1.6
+  build-depends:       base >=4.6 && <5.0
+                     , time >=1.4
                      , transformers
                      , varying
                      , hspec
@@ -129,8 +128,8 @@
   ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N
 
   -- Other library packages from which modules are imported.
-  build-depends:       base >=4.7 && <4.9
-                     , time >=1.5 && <1.6
+  build-depends:       base >=4.6
+                     , time >=1.4
                      , transformers
                      , varying
                      , criterion
