diff --git a/knead.cabal b/knead.cabal
--- a/knead.cabal
+++ b/knead.cabal
@@ -1,5 +1,5 @@
 Name:             knead
-Version:          0.2.1
+Version:          0.2.2
 License:          BSD3
 License-File:     LICENSE
 Author:           Henning Thielemann <haskell@henning-thielemann.de>
@@ -47,7 +47,7 @@
 Build-Type:       Simple
 
 Source-Repository this
-  Tag:         0.2.1
+  Tag:         0.2.2
   Type:        darcs
   Location:    http://hub.darcs.net/thielema/knead/
 
diff --git a/src/Data/Array/Knead/Expression.hs b/src/Data/Array/Knead/Expression.hs
--- a/src/Data/Array/Knead/Expression.hs
+++ b/src/Data/Array/Knead/Expression.hs
@@ -10,11 +10,15 @@
 import LLVM.Extra.Multi.Value (PatternTuple, Decomposed, Atom, atom, )
 
 import qualified Control.Monad as Monad
-import qualified Data.Tuple.HT as Tuple
 
-import Prelude hiding (fst, snd, min, max, zip, unzip, zip3, unzip3, )
+import qualified Data.Tuple.HT as TupleHT
+import qualified Data.Tuple as Tuple
+import Data.Complex (Complex((:+)))
 
+import Prelude
+   hiding (fst, snd, min, max, zip, unzip, zip3, unzip3, curry, uncurry, pi)
 
+
 newtype Exp a = Exp {unExp :: forall r. LLVM.CodeGenFunction r (MultiValue.T a)}
 
 
@@ -122,6 +126,7 @@
     lift1 (\(MultiValue.Cons (_,_,c,_)) -> MultiValue.Cons c) abcd,
     lift1 (\(MultiValue.Cons (_,_,_,d)) -> MultiValue.Cons d) abcd)
 
+
 fst :: (Value val) => val (a, b) -> val a
 fst = lift1 MultiValue.fst
 
@@ -129,15 +134,40 @@
 snd = lift1 MultiValue.snd
 
 mapFst :: (Exp a -> Exp b) -> Exp (a, c) -> Exp (b, c)
-mapFst f = modify (atom, atom) $ \(a,c) -> (f a, c)
+mapFst f = modify (atom, atom) $ TupleHT.mapFst f
 
 mapSnd :: (Exp b -> Exp c) -> Exp (a, b) -> Exp (a, c)
-mapSnd f = modify (atom, atom) $ \(a,b) -> (a, f b)
+mapSnd f = modify (atom, atom) $ TupleHT.mapSnd f
 
 swap :: (Value val) => val (a, b) -> val (b, a)
 swap = lift1 MultiValue.swap
 
+curry :: (Exp (a,b) -> c) -> (Exp a -> Exp b -> c)
+curry f = Tuple.curry (f . Tuple.uncurry zip)
 
+uncurry :: (Exp a -> Exp b -> c) -> (Exp (a,b) -> c)
+uncurry f = Tuple.uncurry f . unzip
+
+
+fst3 :: (Value val) => val (a,b,c) -> val a
+fst3 = lift1 MultiValue.fst3
+
+snd3 :: (Value val) => val (a,b,c) -> val b
+snd3 = lift1 MultiValue.snd3
+
+thd3 :: (Value val) => val (a,b,c) -> val c
+thd3 = lift1 MultiValue.thd3
+
+mapFst3 :: (Exp a0 -> Exp a1) -> Exp (a0,b,c) -> Exp (a1,b,c)
+mapFst3 f = modify (atom, atom, atom) $ TupleHT.mapFst3 f
+
+mapSnd3 :: (Exp b0 -> Exp b1) -> Exp (a,b0,c) -> Exp (a,b1,c)
+mapSnd3 f = modify (atom, atom, atom) $ TupleHT.mapSnd3 f
+
+mapThd3 :: (Exp c0 -> Exp c1) -> Exp (a,b,c0) -> Exp (a,b,c1)
+mapThd3 f = modify (atom, atom, atom) $ TupleHT.mapThd3 f
+
+
 modifyMultiValue ::
    (Value val,
     MultiValue.Compose a,
@@ -236,7 +266,7 @@
 
 instance Compose () where
    type Composed () = ()
-   compose = lift0 . MultiValue.cons
+   compose = cons
 
 instance Decompose () where
    decompose _ _ = ()
@@ -244,22 +274,22 @@
 
 instance (Compose a, Compose b) => Compose (a,b) where
    type Composed (a,b) = (Composed a, Composed b)
-   compose = uncurry zip . Tuple.mapPair (compose, compose)
+   compose = Tuple.uncurry zip . TupleHT.mapPair (compose, compose)
 
 instance (Decompose pa, Decompose pb) => Decompose (pa,pb) where
    decompose (pa,pb) =
-      Tuple.mapPair (decompose pa, decompose pb) . unzip
+      TupleHT.mapPair (decompose pa, decompose pb) . unzip
 
 
 instance (Compose a, Compose b, Compose c) => Compose (a,b,c) where
    type Composed (a,b,c) = (Composed a, Composed b, Composed c)
-   compose = Tuple.uncurry3 zip3 . Tuple.mapTriple (compose, compose, compose)
+   compose = TupleHT.uncurry3 zip3 . TupleHT.mapTriple (compose, compose, compose)
 
 instance
    (Decompose pa, Decompose pb, Decompose pc) =>
       Decompose (pa,pb,pc) where
    decompose (pa,pb,pc) =
-      Tuple.mapTriple (decompose pa, decompose pb, decompose pc) . unzip3
+      TupleHT.mapTriple (decompose pa, decompose pb, decompose pc) . unzip3
 
 
 instance (Compose a, Compose b, Compose c, Compose d) => Compose (a,b,c,d) where
@@ -275,8 +305,37 @@
             (decompose pa a, decompose pb b, decompose pc c, decompose pd d)
 
 
+instance (Compose a) => Compose (Complex a) where
+   type Composed (Complex a) = Complex (Composed a)
+   compose (r:+i) = consComplex (compose r) (compose i)
+
+instance (Decompose p) => Decompose (Complex p) where
+   decompose (pr:+pi) =
+      Tuple.uncurry (:+) .
+      TupleHT.mapPair (decompose pr, decompose pi) . deconsComplex
+
+{- |
+You can construct complex numbers this way,
+but they will not make you happy,
+because the numeric operations require a RealFloat instance
+that we could only provide with lots of undefined methods
+(also in its superclasses).
+You may either define your own arithmetic
+or use the NumericPrelude type classes.
+-}
+consComplex :: Exp a -> Exp a -> Exp (Complex a)
+consComplex = lift2 MultiValue.consComplex
+
+deconsComplex :: Exp (Complex a) -> (Exp a, Exp a)
+deconsComplex c = (lift1 MultiValue.realPart c, lift1 MultiValue.imagPart c)
+
+
+
+cons :: (MultiValue.C a) => a -> Exp a
+cons = lift0 . MultiValue.cons
+
 unit :: Exp ()
-unit = lift0 $ MultiValue.cons ()
+unit = cons ()
 
 zero :: (MultiValue.C a) => Exp a
 zero = lift0 MultiValue.zero
@@ -327,8 +386,8 @@
 
 
 true, false :: Exp Bool
-true = lift0 $ MultiValue.cons True
-false = lift0 $ MultiValue.cons False
+true = cons True
+false = cons False
 
 infixr 3 &&*
 (&&*) :: Exp Bool -> Exp Bool -> Exp Bool
