diff --git a/dunai.cabal b/dunai.cabal
--- a/dunai.cabal
+++ b/dunai.cabal
@@ -1,5 +1,5 @@
 name:                dunai
-version:             0.1.1.0
+version:             0.2.0.0
 synopsis:            Generalised reactive framework supporting classic, arrowized and monadic FRP.
 description:
   Dunai is DSL for strongly-typed CPS-based composable transformations.
@@ -60,10 +60,10 @@
                      Control.Monad.Trans.MSF.Writer
                      Data.MonadicStreamFunction
                      Data.MonadicStreamFunction.Core
-                     Data.MonadicStreamFunction.ArrowChoice
-                     Data.MonadicStreamFunction.ArrowLoop
-                     Data.MonadicStreamFunction.ArrowPlus
-                     Data.MonadicStreamFunction.Instances
+                     Data.MonadicStreamFunction.Async
+                     Data.MonadicStreamFunction.Instances.ArrowChoice
+                     Data.MonadicStreamFunction.Instances.ArrowLoop
+                     Data.MonadicStreamFunction.Instances.ArrowPlus
                      Data.MonadicStreamFunction.Instances.Num
                      Data.MonadicStreamFunction.Instances.VectorSpace
                      Data.MonadicStreamFunction.Parallel
@@ -77,7 +77,6 @@
                      Data.VectorSpace.Specific
 
   other-modules:     Control.Arrow.Util
-                     Data.Tuple.Util
 
   build-depends:     base >=4.6 && < 5,
                      transformers,
diff --git a/src/Control/Arrow/Util.hs b/src/Control/Arrow/Util.hs
--- a/src/Control/Arrow/Util.hs
+++ b/src/Control/Arrow/Util.hs
@@ -26,3 +26,10 @@
 
 -- sink :: Arrow a => a b c -> a c () -> a b c
 -- a1 `sink` a2 = a1 >>> (id &&& a2) >>> arr fst
+
+-- Apply functions at the end
+elementwise :: Arrow a => (c -> d) -> a b c -> a b d
+elementwise = (^<<)
+
+elementwise2 :: Arrow a => (c -> d -> e) -> a b c -> a b d -> a b e
+elementwise2 op a1 a2 = (a1 &&& a2) >>^ uncurry op
diff --git a/src/Control/Monad/Trans/MSF.hs b/src/Control/Monad/Trans/MSF.hs
--- a/src/Control/Monad/Trans/MSF.hs
+++ b/src/Control/Monad/Trans/MSF.hs
@@ -1,12 +1,21 @@
-{-# LANGUAGE Rank2Types          #-}
+{-# LANGUAGE Rank2Types #-}
 
-module Control.Monad.Trans.MSF ( module X ) where
--- Caution, RWS is not exported since names collide with Reader, State and Writer
+module Control.Monad.Trans.MSF
+    ( module Control.Monad.Trans.MSF.GenLift
+    , module Control.Monad.Trans.MSF.Except
+    , module Control.Monad.Trans.MSF.Maybe
+    , module Control.Monad.Trans.MSF.Reader
+    , module Control.Monad.Trans.MSF.State
+    , module Control.Monad.Trans.MSF.Writer
+    )
+  where
 
-import Control.Monad.Trans.MSF.GenLift as X
+-- Caution: RWS is not exported since names collide with Reader, State and
+-- Writer
 
-import Control.Monad.Trans.MSF.Except as X
-import Control.Monad.Trans.MSF.Maybe as X
-import Control.Monad.Trans.MSF.Reader as X
-import Control.Monad.Trans.MSF.State as X
-import Control.Monad.Trans.MSF.Writer as X
+import Control.Monad.Trans.MSF.GenLift
+import Control.Monad.Trans.MSF.Except
+import Control.Monad.Trans.MSF.Maybe
+import Control.Monad.Trans.MSF.Reader
+import Control.Monad.Trans.MSF.State
+import Control.Monad.Trans.MSF.Writer
diff --git a/src/Control/Monad/Trans/MSF/Except.hs b/src/Control/Monad/Trans/MSF/Except.hs
--- a/src/Control/Monad/Trans/MSF/Except.hs
+++ b/src/Control/Monad/Trans/MSF/Except.hs
@@ -6,17 +6,17 @@
   ) where
 
 -- External
-import Control.Applicative
-import qualified Control.Category as Category
-import Control.Monad.Trans.Class
-import Control.Monad.Trans.Except
-  hiding (liftCallCC, liftListen, liftPass) -- Avoid conflicting exports
+import           Control.Applicative
+import qualified Control.Category           as Category
+import           Control.Monad              (liftM, ap)
+import           Control.Monad.Trans.Class
+import           Control.Monad.Trans.Except hiding (liftCallCC, liftListen, liftPass) -- Avoid conflicting exports
+import Control.Monad.Trans.Maybe
 
 -- Internal
-import Control.Monad.Trans.MSF.GenLift
+-- import Control.Monad.Trans.MSF.GenLift
 import Data.MonadicStreamFunction
 
-
 -- * Throwing exceptions
 
 throwOnCond :: Monad m => (a -> Bool) -> e -> MSF (ExceptT e m) a a
@@ -28,9 +28,8 @@
 throwOnCondM cond e = proc a -> do
     b <- arrM (lift . cond) -< a
     if b
-    then arrM throwE -< e
-    else returnA -< a
-
+      then arrM throwE -< e
+      else returnA -< a
 
 throwOn :: Monad m => e -> MSF (ExceptT e m) Bool ()
 throwOn e = proc b -> throwOn' -< (b, e)
@@ -52,6 +51,10 @@
 pass :: Monad m => MSF (ExceptT e m) a a
 pass = Category.id
 
+-- | Whenever 'Nothing' is thrown, throw '()' instead.
+maybeToExceptS :: Monad m => MSF (MaybeT m) a b -> MSF (ExceptT () m) a b
+maybeToExceptS = liftMSFPurer (ExceptT . (maybe (Left ()) Right <$>) . runMaybeT)
+
 -- * Catching exceptions
 
 {-
@@ -89,8 +92,6 @@
             Left e          -> return (Left e,  go)
             Right (b, msf') -> return (Right b, exceptS msf')
 
-
-
 inExceptT :: Monad m => MSF (ExceptT e m) (ExceptT e m a) a
 inExceptT = arrM id -- extracts value from monadic action
 
@@ -102,6 +103,7 @@
     Left  e     -> _ return t
     Right bmsf' -> _ return bmsf'
     -}
+
 -- * Monad interface for Exception MSFs
 
 newtype MSFExcept m a b e = MSFExcept { runMSFExcept :: MSF (ExceptT e m) a b }
@@ -109,10 +111,16 @@
 try :: MSF (ExceptT e m) a b -> MSFExcept m a b e
 try = MSFExcept
 
-instance Functor (MSFExcept m a b) where
+-- | Immediately throw the current input as an exception.
+currentInput :: Monad m => MSFExcept m e b e
+currentInput = try throwS
 
+instance Monad m => Functor (MSFExcept m a b) where
+  fmap = liftM
+
 instance Monad m => Applicative (MSFExcept m a b) where
   pure = MSFExcept . throw
+  (<*>) = ap
 
 instance Monad m => Monad (MSFExcept m a b) where
   MSFExcept msf >>= f = MSFExcept $ MSF $ \a -> do
@@ -133,15 +141,24 @@
 safe :: Monad m => MSF m a b -> MSFExcept m a b e
 safe = try . liftMSFTrans
 
-once :: Monad m => (a -> m b) -> MSFExcept m a c ()
-once f = MSFExcept $ arrM (lift . f) >>> throw ()
+once :: Monad m => (a -> m e) -> MSFExcept m a b e
+once f = try $ arrM (lift . f) >>> throwS
 
-once_ :: Monad m => m b -> MSFExcept m c d ()
+once_ :: Monad m => m e -> MSFExcept m a b e
 once_ = once . const
 
+-- | Advances a single tick with the given Kleisli arrow,
+--   and then throws an exception.
+step :: Monad m => (a -> m (b, e)) -> MSFExcept m a b e
+step f = try $ proc a -> do
+  n      <- count           -< ()
+  (b, e) <- arrM (lift . f) -< a
+  _      <- throwOn'        -< (n > (1 :: Int), e)
+  returnA                   -< b
+
 tagged :: Monad m => MSF (ExceptT e1 m) a b -> MSF (ExceptT e2 m) (a, e2) b
 tagged msf = MSF $ \(a, e2) -> ExceptT $ do
   cont <- runExceptT $ unMSF msf a
   case cont of
-    Left e1 -> return $ Left e2
+    Left  _e1       -> return $ Left e2
     Right (b, msf') -> return $ Right (b, tagged msf')
diff --git a/src/Control/Monad/Trans/MSF/Maybe.hs b/src/Control/Monad/Trans/MSF/Maybe.hs
--- a/src/Control/Monad/Trans/MSF/Maybe.hs
+++ b/src/Control/Monad/Trans/MSF/Maybe.hs
@@ -13,7 +13,6 @@
 import Control.Monad.Trans.MSF.GenLift
 import Data.MonadicStreamFunction
 
-
 runMaybeS'' :: Monad m => MSF (MaybeT m) a b -> MSF m a (Maybe b)
 runMaybeS'' = transG transformInput transformOutput
   where
@@ -30,11 +29,10 @@
 exit = MSF $ const $ MaybeT $ return Nothing
 
 exitWhen :: Monad m => (a -> Bool) -> MSF (MaybeT m) a a
-exitWhen condition = go where
-    go = MSF $ \a -> MaybeT $
-        if condition a
-        then return Nothing
-        else return $ Just (a, go)
+exitWhen condition = go
+  where
+    go = MSF $ \a -> MaybeT $ return $
+                       if condition a then Nothing else Just (a, go)
 
 exitIf :: Monad m => MSF (MaybeT m) Bool ()
 exitIf = MSF $ \b -> MaybeT $ return $ if b then Nothing else Just ((), exitIf)
@@ -61,8 +59,13 @@
     Just (b, msf1') -> return (b, msf1' `catchMaybe` msf2)
     Nothing         -> unMSF msf2 a
 
-
+-- * Converting to and from 'MaybeT'
 
+-- | Converts a list to an 'MSF' in 'MaybeT',
+--   which outputs an element of the list at each step,
+--   throwing 'Nothing' when the list ends.
+listToMaybeS :: Monad m => [b] -> MSF (MaybeT m) a b
+listToMaybeS = foldr iPost exit
 
 -- * Running MaybeT
 runMaybeS :: Monad m => MSF (MaybeT m) a b -> MSF m a (Maybe b)
@@ -73,7 +76,6 @@
            case bmsf of
              Just (b, msf') -> return (Just b, runMaybeS msf')
              Nothing        -> return (Nothing, go)
-
 
 -- mapMaybeS msf == runMaybeS (inMaybeT >>> lift mapMaybeS)
 
diff --git a/src/Control/Monad/Trans/MSF/Writer.hs b/src/Control/Monad/Trans/MSF/Writer.hs
--- a/src/Control/Monad/Trans/MSF/Writer.hs
+++ b/src/Control/Monad/Trans/MSF/Writer.hs
@@ -8,7 +8,7 @@
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Writer.Strict
   hiding (liftCallCC, liftCatch, pass) -- Avoid conflicting exports
-import Data.Monoid
+-- import Data.Monoid
 
 -- Internal
 import Control.Monad.Trans.MSF.GenLift
diff --git a/src/Data/MonadicStreamFunction.hs b/src/Data/MonadicStreamFunction.hs
--- a/src/Data/MonadicStreamFunction.hs
+++ b/src/Data/MonadicStreamFunction.hs
@@ -28,10 +28,17 @@
 --   For a very detailed introduction to MSFs, see:
 --   <http://dl.acm.org/citation.cfm?id=2976010>
 --   (mirror: <http://www.cs.nott.ac.uk/~psxip1/#FRPRefactored>).
+--
+--   Apart from the modules exported, this module exports instances from:
+--
+--   - "Data.MonadicStreamFunction.Instances.ArrowChoice"
+--   - "Data.MonadicStreamFunction.Instances.ArrowLoop"
+--   - "Data.MonadicStreamFunction.Instances.ArrowPlus"
 
 module Data.MonadicStreamFunction
   ( module Control.Arrow
-  , module X
+  , module Data.MonadicStreamFunction.Core
+  , module Data.MonadicStreamFunction.Util
   )
  where
 
@@ -41,11 +48,11 @@
 
 -- Internal
 
-import Data.MonadicStreamFunction.Core        as X
-import Data.MonadicStreamFunction.Util        as X
+import Data.MonadicStreamFunction.Core
+import Data.MonadicStreamFunction.Util
 
 -- Internal (Instances)
 
-import Data.MonadicStreamFunction.ArrowChoice ()
-import Data.MonadicStreamFunction.ArrowLoop   ()
-import Data.MonadicStreamFunction.ArrowPlus   ()
+import Data.MonadicStreamFunction.Instances.ArrowChoice ()
+import Data.MonadicStreamFunction.Instances.ArrowLoop   ()
+import Data.MonadicStreamFunction.Instances.ArrowPlus   ()
diff --git a/src/Data/MonadicStreamFunction/ArrowChoice.hs b/src/Data/MonadicStreamFunction/ArrowChoice.hs
deleted file mode 100644
--- a/src/Data/MonadicStreamFunction/ArrowChoice.hs
+++ /dev/null
@@ -1,13 +0,0 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-module Data.MonadicStreamFunction.ArrowChoice where
-
-import Control.Arrow
-
-import Data.MonadicStreamFunction.Core
-
-instance Monad m => ArrowChoice (MSF m) where
-  left sf = MSF f
-    where
-      f (Left a) = do (b, sf') <- unMSF sf a
-                      return (Left b, left sf')
-      f (Right c) = return (Right c, left sf)
diff --git a/src/Data/MonadicStreamFunction/ArrowLoop.hs b/src/Data/MonadicStreamFunction/ArrowLoop.hs
deleted file mode 100644
--- a/src/Data/MonadicStreamFunction/ArrowLoop.hs
+++ /dev/null
@@ -1,15 +0,0 @@
-{-# LANGUAGE RecursiveDo          #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-module Data.MonadicStreamFunction.ArrowLoop where
-
-import Data.MonadicStreamFunction.Core
-
--- External
-import Control.Arrow
-import Control.Monad.Fix
-
-instance (Monad m, MonadFix m) => ArrowLoop (MSF m) where
-  -- loop :: a (b, d) (c, d) -> a b c
-  loop sf = MSF $ \a -> do
-              rec ((b,c), sf') <- unMSF sf (a, c)
-              return (b, loop sf')
diff --git a/src/Data/MonadicStreamFunction/ArrowPlus.hs b/src/Data/MonadicStreamFunction/ArrowPlus.hs
deleted file mode 100644
--- a/src/Data/MonadicStreamFunction/ArrowPlus.hs
+++ /dev/null
@@ -1,13 +0,0 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-module Data.MonadicStreamFunction.ArrowPlus where
-
-import Control.Arrow
-import Control.Monad
-
-import Data.MonadicStreamFunction.Core
-
-instance (Monad m, MonadPlus m) => ArrowZero (MSF m) where
-  zeroArrow = MSF $ const mzero
-
-instance (Monad m, MonadPlus m) => ArrowPlus (MSF m) where
-  sf1 <+> sf2 = MSF $ \a -> unMSF sf1 a `mplus` unMSF sf2 a
diff --git a/src/Data/MonadicStreamFunction/Async.hs b/src/Data/MonadicStreamFunction/Async.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/MonadicStreamFunction/Async.hs
@@ -0,0 +1,62 @@
+-- | This module contains operations on monadic streams that are asynchronous,
+--   i.e. that change the speed at which data enters or leaves the 'MSF'.
+
+module Data.MonadicStreamFunction.Async where
+
+-- Internal
+import Data.MonadicStreamFunction.Core
+import Data.MonadicStreamFunction.Util (MStream)
+
+{- |
+Concatenates a monadic stream of lists to a monadic stream.
+The stream of lists will be called exactly when new data is needed.
+
+Example:
+
+>>> let intstream = concatS $ arrM_ $ putStrLn "Enter a list of Ints:" >> readLn :: MStream IO Int
+>>> reactimate $ concatS intstream >>> arrM print
+Enter a list of Ints:
+[1,2,33]
+1
+2
+33
+Enter a list of Ints:
+[]
+Enter a list of Ints:
+[]
+Enter a list of Ints:
+[1,2]
+1
+2
+Enter a list of Ints:
+...
+
+Beware that @concatS msf@ becomes unproductive when @msf@ starts outputting empty lists forever.
+This is ok:
+
+>>> let boolToList b = if b then ["Yes"] else []
+>>> let everyOddEmpty = count >>> arr (even >>> boolToList)
+>>> reactimate $ concatS everyOddEmpty >>> arrM print
+"Yes"
+"Yes"
+"Yes"
+"Yes"
+"Yes"
+...
+
+But this will be caught in a loop:
+
+>>> let after3Empty = count >>> arr ((<= 3) >>> boolToList)
+reactimate $ concatS after3Empty  >>> arrM print
+"Yes"
+"Yes"
+"Yes"
+^CInterrupted.
+-}
+concatS :: Monad m => MStream m [b] -> MStream m b
+concatS msf = MSF $ \_ -> tick msf []
+  where
+    tick msf' (b:bs) = return (b, MSF $ \_ -> tick msf' bs)
+    tick msf' []     = do
+      (bs, msf'') <- unMSF msf' ()
+      tick msf'' bs
diff --git a/src/Data/MonadicStreamFunction/Core.hs b/src/Data/MonadicStreamFunction/Core.hs
--- a/src/Data/MonadicStreamFunction/Core.hs
+++ b/src/Data/MonadicStreamFunction/Core.hs
@@ -100,24 +100,46 @@
   pure = arr . const
   fs <*> bs = (fs &&& bs) >>> arr (uncurry ($))
 
--- * Lifting
+-- * Monadic computations and MSFs
 
--- | Apply the same monadic transformation to every element of the input stream.
+-- ** Lifting point-wise computations
+
+-- | Apply a monadic transformation to every element of the input stream.
 --
--- Generalisation of arr from Arrow to stream functions with monads.
+-- Generalisation of 'arr' from 'Arrow' to monadic functions.
 arrM :: Monad m => (a -> m b) -> MSF m a b
 arrM f = go
   where go = MSF $ \a -> do
                b <- f a
                return (b, go)
 
--- * Monadic lifting from one monad into another
-
+-- | Monadic lifting from one monad into another
 liftS :: (Monad m2, MonadBase m1 m2) => (a -> m1 b) -> MSF m2 a b
 liftS = arrM . (liftBase .)
 
--- ** Purer monads
+-- ** Lifting MSFs
 
+-- *** Lifting across monad stacks
+
+-- | Lift inner monadic actions in monad stacks.
+
+-- TODO Should be able to express this in terms of MonadBase
+liftMSFTrans :: (MonadTrans t, Monad m, Monad (t m))
+             => MSF m a b
+             -> MSF (t m) a b
+liftMSFTrans sf = MSF $ \a -> do
+  (b, sf') <- lift $ unMSF sf a
+  return (b, liftMSFTrans sf')
+
+-- | Lift innermost monadic actions in a monad stacks (generalisation of
+-- 'liftIO').
+liftMSFBase :: (Monad m2, MonadBase m1 m2) => MSF m1 a b -> MSF m2 a b
+liftMSFBase sf = MSF $ \a -> do
+  (b, sf') <- liftBase $ unMSF sf a
+  b `seq` return (b, liftMSFBase sf')
+
+-- *** Generic MSF Lifting
+
 -- IPerez: There is an alternative signature for liftMStreamPurer that also
 -- works, and makes the code simpler:
 --
@@ -141,26 +163,7 @@
   (b, sf') <- liftPurer $ unMSF sf a
   b `seq` return (b, liftMSFPurer liftPurer sf')
 
--- ** Monad stacks
-
--- | Lift inner monadic actions in monad stacks.
-
--- TODO Should be able to express this in terms of MonadBase
-liftMSFTrans :: (MonadTrans t, Monad m, Monad (t m))
-             => MSF m a b
-             -> MSF (t m) a b
-liftMSFTrans sf = MSF $ \a -> do
-  (b, sf') <- lift $ unMSF sf a
-  return (b, liftMSFTrans sf')
-
--- | Lift innermost monadic actions in a monad stacks (generalisation of
--- 'liftIO').
-liftMSFBase :: (Monad m2, MonadBase m1 m2) => MSF m1 a b -> MSF m2 a b
-liftMSFBase sf = MSF $ \a -> do
-  (b, sf') <- liftBase $ unMSF sf a
-  b `seq` return (b, liftMSFBase sf')
-
--- * MSFs within monadic actions
+-- ** MSFs within monadic actions
 
 -- | Extract MSF from a monadic action.
 --
@@ -172,7 +175,7 @@
   sf <- sfaction
   unMSF sf a
 
--- ** Delays and signal overwriting
+-- * Delays
 
 -- | Delay a signal by one sample.
 iPre :: Monad m
@@ -190,7 +193,7 @@
 delay :: Monad m => a -> MSF m a a
 delay = iPre
 
--- ** Switching
+-- * Switching
 
 -- | Switching applies one MSF until it produces a 'Just' output, and then
 -- "turns on" a continuation and runs it.
@@ -202,7 +205,7 @@
   ((b, c), sf') <- unMSF sf a
   return (b, maybe (switch sf' f) f c)
 
--- ** Feedback loops
+-- * Feedback loops
 
 -- | Well-formed looped connection of an output component as a future input.
 feedback :: Monad m => c -> MSF m (a, c) (b, c) -> MSF m a b
@@ -239,8 +242,9 @@
   reactimate sf'
 
 -- | Run an MSF indefinitely passing a unit-carrying input stream.
--- A more high-level approach to this would be the use of MaybeT
--- in Control.Monad.Trans.MSF.Maybe
+
+-- TODO: A more high-level approach to this would be the use of MaybeT in
+-- Control.Monad.Trans.MSF.Maybe
 reactimateB :: Monad m => MSF m () Bool -> m ()
 reactimateB sf = do
   (b, sf') <- unMSF sf ()
diff --git a/src/Data/MonadicStreamFunction/Instances.hs b/src/Data/MonadicStreamFunction/Instances.hs
deleted file mode 100644
--- a/src/Data/MonadicStreamFunction/Instances.hs
+++ /dev/null
@@ -1,15 +0,0 @@
-{-# LANGUAGE TypeFamilies #-}
-module Data.MonadicStreamFunction.Instances where
-
--- External
-import Control.Arrow
-
--- Internal
-import Data.MonadicStreamFunction.Core
-
--- Numerical operations are defined elementwise on the output
-elementwise :: Monad m => (b -> c) -> MSF m a b -> MSF m a c
-elementwise f msf = msf >>> arr f
-
-elementwise2 :: Monad m => (b -> c -> d) -> MSF m a b -> MSF m a c -> MSF m a d
-elementwise2 op msf1 msf2 = msf1 &&& msf2 >>> arr (uncurry op)
diff --git a/src/Data/MonadicStreamFunction/Instances/ArrowChoice.hs b/src/Data/MonadicStreamFunction/Instances/ArrowChoice.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/MonadicStreamFunction/Instances/ArrowChoice.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE InstanceSigs         #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+-- | Instance of 'ArrowChoice' for Monadic Stream Functions ('MSF').
+--
+--   Import this module to include that (orphan) instance.
+module Data.MonadicStreamFunction.Instances.ArrowChoice where
+
+import Control.Arrow
+
+import Data.MonadicStreamFunction.Core
+
+instance Monad m => ArrowChoice (MSF m) where
+  left :: MSF m a b -> MSF m (Either a c) (Either b c)
+  left sf = MSF f
+    where
+      f (Left a) = do (b, sf') <- unMSF sf a
+                      return (Left b, left sf')
+      f (Right c) = return (Right c, left sf)
diff --git a/src/Data/MonadicStreamFunction/Instances/ArrowLoop.hs b/src/Data/MonadicStreamFunction/Instances/ArrowLoop.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/MonadicStreamFunction/Instances/ArrowLoop.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE InstanceSigs         #-}
+{-# LANGUAGE RecursiveDo          #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+-- | Instance of 'ArrowLoop' for Monadic Stream Functions ('MSF').
+--
+--   Import this module to include that (orphan) instance.
+--
+--   This is only defined for monads that are instances of 'MonadFix'.
+module Data.MonadicStreamFunction.Instances.ArrowLoop where
+
+import Data.MonadicStreamFunction.Core
+
+-- External
+import Control.Arrow
+import Control.Monad.Fix
+
+instance (Monad m, MonadFix m) => ArrowLoop (MSF m) where
+  loop :: MSF m (b, d) (c, d) -> MSF m b c
+  loop sf = MSF $ \a -> do
+              rec ((b,c), sf') <- unMSF sf (a, c)
+              return (b, loop sf')
diff --git a/src/Data/MonadicStreamFunction/Instances/ArrowPlus.hs b/src/Data/MonadicStreamFunction/Instances/ArrowPlus.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/MonadicStreamFunction/Instances/ArrowPlus.hs
@@ -0,0 +1,18 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+-- | Instance of 'ArrowPlus' for Monadic Stream Functions ('MSF').
+--
+--   Import this module to include that (orphan) instance.
+--
+--   This is only defined for monads that are instances of 'MonadPlus'.
+module Data.MonadicStreamFunction.Instances.ArrowPlus where
+
+import Control.Arrow
+import Control.Monad
+
+import Data.MonadicStreamFunction.Core
+
+instance (Monad m, MonadPlus m) => ArrowZero (MSF m) where
+  zeroArrow = MSF $ const mzero
+
+instance (Monad m, MonadPlus m) => ArrowPlus (MSF m) where
+  sf1 <+> sf2 = MSF $ \a -> unMSF sf1 a `mplus` unMSF sf2 a
diff --git a/src/Data/MonadicStreamFunction/Instances/Num.hs b/src/Data/MonadicStreamFunction/Instances/Num.hs
--- a/src/Data/MonadicStreamFunction/Instances/Num.hs
+++ b/src/Data/MonadicStreamFunction/Instances/Num.hs
@@ -4,7 +4,6 @@
 
 import Control.Arrow.Util
 import Data.MonadicStreamFunction.Core
-import Data.MonadicStreamFunction.Instances
 
 instance (Monad m, Num b) => Num (MSF m a b) where
   (+)         = elementwise2 (+)
diff --git a/src/Data/MonadicStreamFunction/Instances/VectorSpace.hs b/src/Data/MonadicStreamFunction/Instances/VectorSpace.hs
--- a/src/Data/MonadicStreamFunction/Instances/VectorSpace.hs
+++ b/src/Data/MonadicStreamFunction/Instances/VectorSpace.hs
@@ -2,19 +2,19 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module Data.MonadicStreamFunction.Instances.VectorSpace where
 
+import Control.Arrow
 import Control.Arrow.Util
 import Data.MonadicStreamFunction.Core
-import Data.MonadicStreamFunction.Instances
 import Data.VectorSpace
 
 -- These conflict with Data.VectorSpace.Instances
 instance (Monad m, RModule v) => RModule (MSF m a v) where
   type Groundring (MSF m a v) = Groundring v
   zeroVector   = constantly zeroVector
-  r *^ msf     = elementwise  (r *^) msf
-  negateVector = elementwise  negateVector
+  r *^ msf     = msf >>^ (r *^)
+  negateVector = (>>^ negateVector)
   (^+^)        = elementwise2 (^+^)
   (^-^)        = elementwise2 (^-^)
 
 instance (Monad m, VectorSpace v) => VectorSpace (MSF m a v) where
-  msf ^/ r = elementwise (^/ r) msf
+  msf ^/ r = msf >>^ (^/ r)
diff --git a/src/Data/MonadicStreamFunction/Parallel.hs b/src/Data/MonadicStreamFunction/Parallel.hs
--- a/src/Data/MonadicStreamFunction/Parallel.hs
+++ b/src/Data/MonadicStreamFunction/Parallel.hs
@@ -2,12 +2,14 @@
 
 -- External
 import Control.Arrow
--- import Control.Parallel
 import GHC.Conc
 
 -- Internal
 import Data.MonadicStreamFunction
 
+-- | Run two MSFs in parallel, taking advantage of parallelism if
+--   possible. This is the parallel version of '(***)'.
+
 -- IPerez: This should be similar to the following:
 -- (msf1 *** msf2) >>> parS
 -- where parS             = arr parTuple
@@ -15,13 +17,13 @@
 -- Manuel: but we added strictness annotations to first
 -- and so (***) might be strict in both arguments and not take
 -- full advantage of parallelism.
---
+
 (*|*) :: Monad m => MSF m a b -> MSF m c d -> MSF m (a, c) (b, d)
 msf1 *|* msf2 = MSF $ \(a, c) -> do
-    (b, msf1') <- unMSF msf1 a
-    (d, msf2') <- unMSF msf2 c
-    b `par` d `pseq` return ((b, d), msf1' *|* msf2')
-
+  (b, msf1') <- unMSF msf1 a
+  (d, msf2') <- unMSF msf2 c
+  b `par` d `pseq` return ((b, d), msf1' *|* msf2')
 
+-- | Parallel version of '(&&&)'.
 (&|&) :: Monad m => MSF m a b -> MSF m a c -> MSF m a (b, c)
 msf1 &|& msf2 = arr (\a -> (a, a)) >>> (msf1 *|* msf2)
diff --git a/src/Data/MonadicStreamFunction/Util.hs b/src/Data/MonadicStreamFunction/Util.hs
--- a/src/Data/MonadicStreamFunction/Util.hs
+++ b/src/Data/MonadicStreamFunction/Util.hs
@@ -56,7 +56,7 @@
  where repeatedly' a = MSF $ \() -> let a' = f a in a' `seq` return (a, repeatedly' a')
 -- repeatedly f x = feedback x (arr (f >>> \x -> (x,x)))
 
--- * Special cases of map
+-- * Analogues of map and fmap
 
 mapMSF :: Monad m => MSF m a b -> MSF m [a] [b]
 mapMSF = MSF . consume
diff --git a/src/Data/Tuple/Util.hs b/src/Data/Tuple/Util.hs
deleted file mode 100644
--- a/src/Data/Tuple/Util.hs
+++ /dev/null
@@ -1,7 +0,0 @@
-module Data.Tuple.Util where
-
-assocR :: ((a, b), c) -> (a, (b, c))
-assocR ((a, b), c) = (a, (b, c))
-
-assocL :: (a, (b, c)) -> ((a, b), c)
-assocL (a, (b, c)) = ((a, b), c)
