diff --git a/dunai.cabal b/dunai.cabal
--- a/dunai.cabal
+++ b/dunai.cabal
@@ -1,5 +1,5 @@
 name:                dunai
-version:             0.5.2.1
+version:             0.6.0
 synopsis:            Generalised reactive framework supporting classic, arrowized and monadic FRP.
 homepage:            https://github.com/ivanperez-keera/dunai
 description:
@@ -76,15 +76,14 @@
                      Data.MonadicStreamFunction.ReactHandle
                      Data.MonadicStreamFunction.Util
 
-                     -- Auxiliary definitions
-                     Data.VectorSpace
-
   other-modules:     Control.Arrow.Util
 
   build-depends:     base >=4.6 && < 5,
                      transformers,
                      transformers-base,
-                     MonadRandom
+                     MonadRandom,
+                     simple-affine-space
+
   hs-source-dirs:    src
   default-language:  Haskell2010
   ghc-options:       -Wall -fno-warn-unused-do-bind
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
@@ -1,5 +1,8 @@
-{-# LANGUAGE TypeFamilies         #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE UndecidableInstances  #-}
+{-# OPTIONS_GHC -fno-warn-orphans  #-}
 -- | 'VectorSpace' instances for 'MSF's that produce vector spaces. This allows
 -- you to use vector operators with 'MSF's that output vectors, for example, you
 -- can write:
@@ -19,6 +22,12 @@
 --
 --
 -- Instances are provided for the type classes 'RModule' and 'VectorSpace'.
+
+-- Note: This module uses undecidable instances, because GHC does not know
+-- enough to assert that it will be able to determine the type of 's' from the
+-- type of 'v', because 'v' only appears under 'MSF' in the instance head and
+-- it cannot determine what 'MSF' will do to 'v' and whether the type can be
+-- resolved.
 module Data.MonadicStreamFunction.Instances.VectorSpace where
 
 import Control.Arrow
@@ -26,17 +35,11 @@
 import Data.MonadicStreamFunction.Core
 import Data.VectorSpace
 
--- These conflict with Data.VectorSpace.Instances
-
--- | R-module instance for 'MSF's.
-instance (Monad m, RModule v) => RModule (MSF m a v) where
-  type Groundring (MSF m a v) = Groundring v
+-- | Vector-space instance for 'MSF's.
+instance (Monad m, VectorSpace v s) => VectorSpace (MSF m a v) s where
   zeroVector   = constantly zeroVector
-  r *^ msf     = msf >>^ (r *^)
-  negateVector = (>>^ negateVector)
+  r   *^ msf   = msf >>^ (r *^)
+  msf ^/ r     = msf >>^ (^/ r)
   (^+^)        = elementwise2 (^+^)
   (^-^)        = elementwise2 (^-^)
-
--- | Vector-space instance for 'MSF's.
-instance (Monad m, VectorSpace v) => VectorSpace (MSF m a v) where
-  msf ^/ r = msf >>^ (^/ r)
+  negateVector = (>>^ negateVector)
diff --git a/src/Data/MonadicStreamFunction/InternalCore.hs b/src/Data/MonadicStreamFunction/InternalCore.hs
--- a/src/Data/MonadicStreamFunction/InternalCore.hs
+++ b/src/Data/MonadicStreamFunction/InternalCore.hs
@@ -116,7 +116,7 @@
 -- if the 'MSF' produces 'Nothing' at any point, so the output stream cannot
 -- consumed progressively.
 --
--- To explore the output progressively, use 'liftMSF' and '(>>>)'', together
+-- To explore the output progressively, use 'arrM' and '(>>>)'', together
 -- with some action that consumes/actuates on the output.
 --
 -- This is called 'runSF' in Liu, Cheng, Hudak, "Causal Commutative Arrows and
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
@@ -96,11 +96,11 @@
 count = arr (const 1) >>> accumulateWith (+) 0
 
 -- | Sums the inputs, starting from zero.
-sumS :: (RModule v, Monad m) => MSF m v v
+sumS :: (VectorSpace v s, Monad m) => MSF m v v
 sumS = sumFrom zeroVector
 
 -- | Sums the inputs, starting from an initial vector.
-sumFrom :: (RModule v, Monad m) => v -> MSF m v v
+sumFrom :: (VectorSpace v s, Monad m) => v -> MSF m v v
 sumFrom = accumulateWith (^+^)
 
 -- ** Folding for monoids
diff --git a/src/Data/VectorSpace.hs b/src/Data/VectorSpace.hs
deleted file mode 100644
--- a/src/Data/VectorSpace.hs
+++ /dev/null
@@ -1,323 +0,0 @@
-{-# LANGUAGE TypeFamilies               #-}
-{-# LANGUAGE FlexibleInstances          #-}
-{-# LANGUAGE FlexibleContexts           #-}
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
--- |
--- Module      :  Data.VectorSpace
--- Copyright   :  (c) Ivan Perez and Manuel Bärenz
--- License     :  See the LICENSE file in the distribution.
---
--- Maintainer  :  ivan.perez@keera.co.uk
--- Stability   :  provisional
--- Portability :  non-portable (GHC extensions)
---
--- Vector space type relation and basic instances.
--- Heavily inspired by Yampa's @FRP.Yampa.VectorSpace@ module.
-
-module Data.VectorSpace where
-
-------------------------------------------------------------------------------
--- * Vector space classes
-------------------------------------------------------------------------------
-
-infixr 6 *^
-infixl 6 ^/
-infix 6 `dot`
-infixl 5 ^+^, ^-^
-
--- | R-modules.
---   A module @v@ over a ring @Groundring v@
---   is an abelian group with a linear multiplication.
---   The hat @^@ denotes the side of an operation
---   on which the vector stands,
---   i.e. @a *^ v@ for @v@ a vector.
---
--- A minimal definition should include the type 'Groundring' and the
--- implementations of 'zeroVector', '^+^', and one of '*^' or '^*'.
---
---   The following laws must be satisfied:
---
---   * @v1 ^+^ v2 == v2 ^+^ v1@
---   * @a *^ zeroVector == zeroVector@
---   * @a *^ (v1 ^+^ v2) == a *^ v1 ^+^ a*^ v2
---   * @a *^ v == v ^* a@
---   * @negateVector v == (-1) *^ v@
---   * @v1 ^-^ v2 == v1 ^+^ negateVector v2@
-class Num (Groundring v) => RModule v where
-    type Groundring v
-    zeroVector   :: v
-
-    (*^)         :: Groundring v -> v -> v
-    (*^)         = flip (^*)
-
-    (^*)         :: v -> Groundring v -> v
-    (^*)         = flip (*^)
-
-    negateVector :: v -> v
-    negateVector v = (-1) *^ v
-
-    (^+^)        :: v -> v -> v
-
-    (^-^)        :: v -> v -> v
-    v1 ^-^ v2     = v1 ^+^ negateVector v2
-
--- Maybe norm and normalize should not be class methods, in which case
--- the constraint on the coefficient space (a) should (or, at least, could)
--- be Fractional (roughly a Field) rather than Floating.
-
--- Minimal instance: zeroVector, (*^), (^+^), dot
--- class Fractional (Groundfield v) => VectorSpace v where
-
--- | A vector space is a module over a field,
---   i.e. a commutative ring with inverses.
---
---   It needs to satisfy the axiom
---   @v ^/ a == (1/a) *^ v@,
---   which is the default implementation.
-class (Fractional (Groundring v), RModule v) => VectorSpace v where
-    (^/) :: v -> Groundfield v -> v
-    v ^/ a = (1/a) *^ v
-
--- | The ground ring of a vector space is required to be commutative
---   and to possess inverses.
---   It is then called the "ground field".
---   Commutativity amounts to the law @a * b = b * a@,
---   and the existence of inverses is given
---   by the requirement of the 'Fractional' type class.
-type Groundfield v = Groundring v
-
--- | An inner product space is a module with an inner product,
---   i.e. a map @dot@ satisfying
---
---   * @v1 `dot` v2 == v2 `dot` v1@
---   * @(v1 ^+^ v2) `dot` v3 == v1 `dot` v3 ^+^ v2 `dot` v3@
---   * @(a *^ v1) `dot` v2 == a *^ v1 `dot` v2@
-class RModule v => InnerProductSpace v where
-  dot :: v -> v -> Groundfield v
-
--- | A normed space is a module with a norm,
---   i.e. a function @norm@ satisfying
---
---   * @norm (a ^* v) = a ^* norm v@
---   * @norm (v1 ^+^ v2) <= norm v1 ^+^ norm v2@
---     (the "triangle inequality")
---
---   A typical example is @sqrt (v `dot` v)@,
---   for an inner product space.
-class (Floating (Groundfield v), InnerProductSpace v, VectorSpace v) => NormedSpace v  where
-  norm :: v -> Groundfield v
-  norm v = sqrt $ v `dot` v
-
--- | Divides a vector by its norm, resulting in a vector of norm 1.
---   Throws an error on vectors with norm 0.
-normalize :: (Eq (Groundfield v), NormedSpace v) => v -> v
-normalize v = if nv /= 0 then v ^/ nv else error "normalize: zero vector"
-  where nv = norm v
-
-
------------------------------
--- Instances for scalar types
------------------------------
-
-
-instance RModule Int where
-    type Groundring Int = Int
-    (^+^) = (+)
-    (^*) = (*)
-    zeroVector = 0
-
-instance RModule Integer where
-    type Groundring Integer = Integer
-    (^+^) = (+)
-    (^*) = (*)
-    zeroVector = 0
-
-instance RModule Double where
-    type Groundring Double = Double
-    (^+^) = (+)
-    (^*) = (*)
-    zeroVector = 0
-
-instance RModule Float where
-    type Groundring Float = Float
-    (^+^) = (+)
-    (^*) = (*)
-    zeroVector = 0
-
-instance VectorSpace Double where
-
-instance VectorSpace Float where
-
------------------------
--- Instances for tuples
------------------------
-
-
-instance
-  ( Groundring a ~ Groundring b
-  , RModule a, RModule b
-  ) => RModule (a, b) where
-    type Groundring (a, b) = Groundring a
-    zeroVector = (zeroVector, zeroVector)
-    (a, b) ^* x = (a ^* x, b ^* x)
-    (a1, b1) ^+^ (a2, b2) = (a1 ^+^ a2, b1 ^+^ b2)
-
-instance
-  (Groundfield a ~ Groundfield b
-  , VectorSpace a, VectorSpace b
-  ) => VectorSpace (a, b) where
-    (a, b) ^/ x = (a ^/ x, b ^/ x)
-
-instance (Groundfield a ~ Groundfield b, InnerProductSpace a, InnerProductSpace b) => InnerProductSpace (a, b) where
-    (a1, b1) `dot` (a2, b2) = (a1 `dot` a2) + (b1 `dot` b2)
-
-instance (Groundfield a ~ Groundfield b, NormedSpace a, NormedSpace b) => NormedSpace (a, b) where
-
--- ** Utilities to work with n-tuples for n = 3, 4, 5
-
-break3Tuple :: (a, b, c) -> ((a, b), c)
-break3Tuple    (a, b, c) =  ((a, b), c)
-
-join3Tuple  :: ((a, b), c) -> (a, b, c)
-join3Tuple     ((a, b), c) =  (a, b, c)
-
-break4Tuple :: (a, b, c, d) -> ((a, b), (c, d))
-break4Tuple    (a, b, c, d) =  ((a, b), (c, d))
-
-join4Tuple  :: ((a, b), (c, d)) -> (a, b, c, d)
-join4Tuple     ((a, b), (c, d)) =  (a, b, c, d)
-
-break5Tuple :: (a, b, c, d, e) -> ((a, b), (c, d, e))
-break5Tuple    (a, b, c, d, e) =  ((a, b), (c, d, e))
-
-join5Tuple  :: ((a, b), (c, d, e)) -> (a, b, c, d, e)
-join5Tuple     ((a, b), (c, d, e)) =  (a, b, c, d, e)
-
-
-
-instance
-  ( Groundring a ~ Groundring b
-  , Groundring a ~ Groundring c
-  , RModule a, RModule b, RModule c
-  ) => RModule (a, b, c) where
-    type Groundring (a, b, c) = Groundring a
-    zeroVector = join3Tuple zeroVector
-    a *^ v = join3Tuple $ a *^ (break3Tuple v)
-    v1 ^+^ v2 = join3Tuple $ break3Tuple v1 ^+^ break3Tuple v2
-
-instance
-  ( Groundring a ~ Groundring b
-  , Groundring a ~ Groundring c
-  , VectorSpace a, VectorSpace b, VectorSpace c
-  ) => VectorSpace (a, b, c) where
-
-instance
-  ( Groundring a ~ Groundring b
-  , Groundring a ~ Groundring c
-  , InnerProductSpace a, InnerProductSpace b, InnerProductSpace c
-  ) => InnerProductSpace (a, b, c) where
-  v1 `dot` v2 = break3Tuple v1 `dot` break3Tuple v2
-
-instance
-  ( Groundring a ~ Groundring b
-  , Groundring a ~ Groundring c
-  , NormedSpace a, NormedSpace b, NormedSpace c
-  ) => NormedSpace (a, b, c) where
-
-
-
-instance
-  ( Groundring a ~ Groundring b
-  , Groundring a ~ Groundring c
-  , Groundring a ~ Groundring d
-  , RModule a, RModule b, RModule c, RModule d
-  ) => RModule (a, b, c, d) where
-    type Groundring (a, b, c, d) = Groundring a
-    zeroVector = join4Tuple zeroVector
-    a *^ v = join4Tuple $ a *^ (break4Tuple v)
-    v1 ^+^ v2 = join4Tuple $ break4Tuple v1 ^+^ break4Tuple v2
-
-instance
-  ( Groundring a ~ Groundring b
-  , Groundring a ~ Groundring c
-  , Groundring a ~ Groundring d
-  , VectorSpace a, VectorSpace b, VectorSpace c, VectorSpace d
-  ) => VectorSpace (a, b, c, d) where
-
-instance
-  ( Groundring a ~ Groundring b
-  , Groundring a ~ Groundring c
-  , Groundring a ~ Groundring d
-  , InnerProductSpace a, InnerProductSpace b
-  , InnerProductSpace c, InnerProductSpace d
-  ) => InnerProductSpace (a, b, c, d) where
-  v1 `dot` v2 = break4Tuple v1 `dot` break4Tuple v2
-
-instance
-  ( Groundring a ~ Groundring b
-  , Groundring a ~ Groundring c
-  , Groundring a ~ Groundring d
-  , NormedSpace a, NormedSpace b, NormedSpace c, NormedSpace d
-  ) => NormedSpace (a, b, c, d) where
-
-
-
-instance
-  ( Groundring a ~ Groundring b
-  , Groundring a ~ Groundring c
-  , Groundring a ~ Groundring d
-  , Groundring a ~ Groundring e
-  , RModule a, RModule b, RModule c, RModule d, RModule e
-  ) => RModule (a, b, c, d, e) where
-    type Groundring (a, b, c, d, e) = Groundring a
-    zeroVector = join5Tuple zeroVector
-    a *^ v = join5Tuple $ a *^ (break5Tuple v)
-    v1 ^+^ v2 = join5Tuple $ break5Tuple v1 ^+^ break5Tuple v2
-
-instance
-  ( Groundring a ~ Groundring b
-  , Groundring a ~ Groundring c
-  , Groundring a ~ Groundring d
-  , Groundring a ~ Groundring e
-  , VectorSpace a, VectorSpace b, VectorSpace c, VectorSpace d, VectorSpace e
-  ) => VectorSpace (a, b, c, d, e) where
-
-instance
-  ( Groundring a ~ Groundring b
-  , Groundring a ~ Groundring c
-  , Groundring a ~ Groundring d
-  , Groundring a ~ Groundring e
-  , InnerProductSpace a, InnerProductSpace b, InnerProductSpace c
-  , InnerProductSpace d, InnerProductSpace e
-  ) => InnerProductSpace (a, b, c, d, e) where
-  v1 `dot` v2 = break5Tuple v1 `dot` break5Tuple v2
-
-instance
-  ( Groundring a ~ Groundring b
-  , Groundring a ~ Groundring c
-  , Groundring a ~ Groundring d
-  , Groundring a ~ Groundring e
-  , NormedSpace a, NormedSpace b, NormedSpace c, NormedSpace d, NormedSpace e
-  ) => NormedSpace (a, b, c, d, e) where
-
-
--- * Vector spaces from arbitrary 'Fractional's
-
--- | Wrap an arbitrary 'Fractional' in this newtype
---   in order to get 'VectorSpace', and related instances.
-newtype FractionalVectorSpace a = FractionalVectorSpace { getFractional :: a }
-  deriving (Num, Fractional)
-
-
-instance Num a => RModule (FractionalVectorSpace a) where
-  type Groundring (FractionalVectorSpace a) = a
-  v1 ^+^ v2 = FractionalVectorSpace $ getFractional v1 + getFractional v2
-  v ^* a = FractionalVectorSpace $ getFractional v * a
-  zeroVector = FractionalVectorSpace 0
-
-instance Fractional a => VectorSpace (FractionalVectorSpace a) where
-
-instance Num a => InnerProductSpace (FractionalVectorSpace a) where
-  v1 `dot` v2 = getFractional v1 * getFractional v2
-
-instance Floating a => NormedSpace (FractionalVectorSpace a) where
