diff --git a/Catana.cabal b/Catana.cabal
--- a/Catana.cabal
+++ b/Catana.cabal
@@ -7,7 +7,7 @@
 -- The package version. See the Haskell package versioning policy
 -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
 -- standards guiding when and how versions should be incremented.
-Version:             0.1
+Version:             0.2
 
 -- A short (one-line) description of the package.
 Synopsis: A monad for complex manipulation of a stream.          
diff --git a/Control/Monad/Catana.hs b/Control/Monad/Catana.hs
--- a/Control/Monad/Catana.hs
+++ b/Control/Monad/Catana.hs
@@ -1,6 +1,6 @@
 {- |
 Module      : Control.Monad.Catana
-Copyright   : (c) Dustin DeWeese 2011
+Copyright   : (c) Dustin DeWeese 2011-2012
 License     : BSD3
 Maintainer  : dustin.deweese@gmail.com
 Stability   : experimental
@@ -16,7 +16,7 @@
 
 [Example type:] @'Catana' i o b a@
 
-The Catana monad represents computations that are both catamorphisms and anamorphisms; they both consume and produce values.  In addition, the Catana monad represents the computation in continuation-passing style, allowing the continuations to be manipulated as is Control.Monad.Cont
+The Catana monad represents computations that are both catamorphisms and anamorphisms; they both consume and produce values.  In addition, the Catana monad represents the computation in continuation-passing style, and implements callCC.
 -}
 
 module Control.Monad.Catana (
@@ -24,13 +24,14 @@
     Catana(..),
     consume,
     top,
---    consumeOnly, -- too dangerous
     push,
     produce,
     stop,
-    more,
     evalCatana,
-    evalCatana'
+    evalCatana',
+    parallelB,
+    parallelE,
+    serial
     -- * Example 1: Usage of the Catana monad
     -- $catanaExample1
   ) where
@@ -38,6 +39,8 @@
 import Control.Applicative
 import Control.Monad
 import Control.Monad.Cont
+import Data.Either
+import Data.Maybe
 
 {- $catanaExample1
 
@@ -61,82 +64,160 @@
 
 > evalCatana catanaExample1 [1..4]
 > -- result: [3.0,2.0,-1.0,0.5,1.0,7.0,12.0,0.0] 
+
+An example using serial and parallel data flow:
+
+>catanaExample2 = sq `serial` (ev `parallelB` od)
+>  where od = forever $ do
+>               x <- consume
+>               when (odd x) .
+>                 produce $ x * 2
+>        ev = forever $ do
+>               x <- consume
+>               when (even x) .
+>                 produce $ x + 3
+>        sq = forever $ do
+>               x <- consume
+>               produce x
+>               produce $ x ^ 2
+
+> let l = 1 : evalCatana catanaExample2 l
+> take 10 l
+> -- result: [1,2,4,5,25,7,49,10,100,50]
+
 -}
 
-data Catana i o b a = Catana { runCatana :: [i] -> (CatanaIO i o a -> CatanaIO i o b) -> CatanaIO i o b }
-type CatanaIO i o a = (a, [i], [o] -> [o])
+data Catana i o b a = Catana { runCatana :: (a -> Step i o b) -> Step i o b }
 
+data Step i o a = Yield o (Step i o a)
+                | Waiting (i -> Step i o a)
+                | Done a
+
 instance Functor (Catana i o b) where
-  fmap f (Catana l) = Catana $ \i k ->
-                      l i $ \(x, i', o') ->
-                      k (f x, i', o')
+  fmap f (Catana l) = Catana $ l . (. f)
 
 instance Applicative (Catana i o b) where
-  Catana fl <*> x = Catana $ \i k ->
-                    fl i $ \(f, i', o1) ->
-                      let (x', i'', o2) = runCatana (fmap f x) i' k
-                        in (x', i'', o1 . o2)
-  pure x = Catana $ \i k -> k (x, i, id)
 
+  Catana fl <*> x = Catana $ \k ->
+                      fl $ \f ->
+                        runCatana (fmap f x) k
+  pure x = Catana $ \k -> k x
+
 instance Monad (Catana i o b) where
   return = pure
-  Catana l >>= f = Catana $ \i k ->
-                   l i $ \(x, i', o1) ->
-                     let (x', i'', o2) = runCatana (f x) i' k
-                       in (x', i'', o1 . o2)
+  Catana l >>= f = Catana $ \k ->
+                     l $ \x ->
+                       runCatana (f x) k
 
 instance MonadCont (Catana i o b) where
-  callCC f = Catana $ \i k ->
-               let g x = Catana $ \i' _ -> k (x, i', id)
-                 in runCatana (f g) i k
+  callCC f = Catana $ \k -> runCatana (f $ Catana . const . k) k
 
 -- |Consumes an element from the input list, returning it
 -- If there is no more input, the chain of continuations ends
 -- immediately; no more computations will be processed
 consume :: Catana i o a i
-consume = Catana f
-  where f (x : i) k = k (x, i, id)
-        f i k = (undefined, i, id)
+consume = Catana Waiting
 
 -- |Returns the next input without consuming it
 top :: Catana i o a i
-top = Catana f
-  where f i@(x : _) k = k (x, i, id)
-        f i k = (undefined, i, id)
+top = Catana $ \k -> Waiting (\i -> feed i (k i))
 
--- |Consumes only the element satisfying p, leaving the other
--- elements in the input list.  This could cause space leaks if
--- the input is never fully consumed
-consumeOnly :: (i -> Bool) -> Catana i o a i
-consumeOnly p = Catana f
-  where f i k | null b = (undefined, i, id)
-              | otherwise = k (head b, a ++ tail b, id)
-          where (a, b) = span (not . p) i
+-- |Feeds an input into the next Waiting step
+feed :: i -> Step i o a -> Step i o a
+feed i (Yield o s) = Yield o (feed i s)
+feed i (Waiting s) = s i
+feed _ (Done x) = Done x
 
 -- |Stops computation, ending the continuation chain
-stop :: Catana i o () a
-stop = Catana $ \i k -> ((), i, id)
-
--- |Tests for more input
-more :: Catana i o a Bool
-more = Catana f
-  where f [] k = k (False, [], id)
-        f i k = k (True, i, id)
+stop :: b -> Catana i o b a
+stop = Catana . const . Done
 
 -- |Pushes 'x' into the input
 push :: i -> Catana i o a ()
-push x = Catana $ \i k -> k ((), x:i, id)
+push x = Catana $ feed x . ($())
 
 -- |Produces 'x' in the output
 produce :: o -> Catana i o a ()
-produce x = Catana $ \i k -> k ((), i, (x:))
+produce x = Catana $ Yield x . ($())
 
 -- |Converts a Catana monad into a function over lists
 evalCatana :: Catana i o a a -> [i] -> [o]
-evalCatana c i = o []
-  where (_, _, o) = runCatana c i id
+evalCatana c = runSteps (runCatana c Done)
 
+-- |Helper for evalCatana, runs the steps
+runSteps :: Step i o a -> [i] -> [o]
+runSteps (Yield o s) i = o : runSteps s i
+runSteps (Waiting f) (i:is) = runSteps (f i) is
+runSteps (Waiting _) [] = []
+runSteps (Done x) _ = []
+
 -- |Evaluates a Catana monad over a list returning the result and output
-evalCatana' :: Catana i o a a -> [i] -> (a, [o])
-evalCatana' c i = (x, o [])
-  where (x, _, o) = runCatana c i id
+evalCatana' :: Catana i o a a -> [i] -> (Maybe a, [o])
+evalCatana' c i = (listToMaybe x, o)
+  where (x, o) = partitionEithers $ runSteps' (runCatana c Done) i
+
+-- |Helper for evalCatana', runs the steps
+runSteps' :: Step i o a -> [i] -> [Either a o]
+runSteps' (Yield o s) i = Right o : runSteps' s i
+runSteps' (Waiting f) (i:is) = runSteps' (f i) is
+runSteps' (Waiting _) [] = []
+runSteps' (Done x) _ = [Left x]
+
+-- |Helper for parallelB, combine steps to consume the same input at the same time, using k as the continuation
+parStepsB :: Step i o a -> Step i o b -> ((a,b) -> Step i o c) -> Step i o c
+
+-- Yield when possible
+parStepsB (Yield oA sA) (Yield oB sB) k = Yield oA . Yield oB $ parStepsB sA sB k
+parStepsB (Yield oA sA) sB k = Yield oA $ parStepsB sA sB k
+parStepsB sA (Yield oB sB) k = Yield oB $ parStepsB sA sB k
+
+-- Wait for input
+parStepsB (Waiting fA) (Waiting fB) k = Waiting $ \i -> parStepsB (fA i) (fB i) k
+parStepsB (Waiting fA) sB k = Waiting $ \i -> parStepsB (fA i) sB k
+parStepsB sA (Waiting fB) k = Waiting $ \i -> parStepsB sA (fB i) k
+
+-- Apply continuation to results
+parStepsB (Done xA) (Done xB) k = k (xA, xB)
+
+-- |Combine two monads to run in parallel, consuming the same input
+parallelB :: Catana i o a a -> Catana i o b b -> Catana i o c (a, b)
+parallelB a b = Catana $ parStepsB (runCatana a Done) (runCatana b Done)
+
+-- |Helper for parallelB, combine steps to consume the same input at the same time, using k as the continuation
+parStepsE :: Step i o a -> Step i o b -> (Either a b -> Step i o c) -> Step i o c
+
+-- Yield when possible
+parStepsE (Yield oA sA) (Yield oB sB) k = Yield oA . Yield oB $ parStepsE sA sB k
+parStepsE (Yield oA sA) sB k = Yield oA $ parStepsE sA sB k
+parStepsE sA (Yield oB sB) k = Yield oB $ parStepsE sA sB k
+
+-- Apply continuation to result
+parStepsE (Done xA) _ k = k (Left xA)
+parStepsE _ (Done xB) k = k (Right xB)
+
+-- Wait for input
+parStepsE (Waiting fA) (Waiting fB) k = Waiting $ \i -> parStepsE (fA i) (fB i) k
+
+-- |Combine two monads to run in parallel, consuming the same input, stopping when either of them finish.
+parallelE :: Catana i o a a -> Catana i o b b -> Catana i o c (Either a b)
+parallelE a b = Catana $ parStepsE (runCatana a Done) (runCatana b Done)
+
+serSteps :: Step io o a -> Step i io b -> (Either a b -> Step i o c) -> Step i o c
+
+-- Yield when possible
+serSteps (Yield oA sA) sB k = Yield oA $ serSteps sA sB k
+
+-- Apply continuation to results
+serSteps (Done xA) _ k = k (Left xA)
+serSteps _ (Done xB) k = k (Right xB)
+
+-- Pass output from B to A
+serSteps (Waiting fA) (Yield oB sB) k = serSteps (fA oB) sB k
+
+-- Wait for input to B
+serSteps sA (Waiting fB) k = Waiting $ \i -> serSteps sA (fB i) k
+
+-- |Combine two monads to run in serial, the first consuming the output of the second
+serial :: Catana io o a a -> Catana i io b b -> Catana i o c (Either a b)
+serial a b = Catana $ serSteps (runCatana a Done) (runCatana b Done)
+
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c)2011, Dustin DeWeese
+Copyright (c)2011-2012, Dustin DeWeese
 
 All rights reserved.
 
