diff --git a/LLVM/Core/Instructions.hs b/LLVM/Core/Instructions.hs
--- a/LLVM/Core/Instructions.hs
+++ b/LLVM/Core/Instructions.hs
@@ -16,6 +16,7 @@
     br,
     switch,
     invoke, invokeWithConv,
+    invokeFromFunction, invokeWithConvFromFunction,
     unreachable,
     -- * Arithmetic binary operations
     -- | Arithmetic operations with the normal semantics.
@@ -58,6 +59,8 @@
     -- * Other
     phi, addPhiInputs,
     call, callWithConv,
+    callFromFunction, callWithConvFromFunction,
+    Call, applyCall, runCall,
 
     -- * Classes and types
     Terminate,
@@ -867,19 +870,24 @@
 
 type Caller = FFI.BuilderRef -> [FFI.ValueRef] -> IO FFI.ValueRef
 
+{-
+Function (a -> b -> IO c)
+Value a -> Value b -> CodeGenFunction r c
+-}
+
 -- |Acceptable arguments to 'call'.
 class (f ~ CalledFunction g, r ~ CallerResult g, g ~ CallerFunction f r) =>
          CallArgs f g r where
     type CalledFunction g :: *
     type CallerResult g :: *
     type CallerFunction f r :: *
-    doCall :: Caller -> [FFI.ValueRef] -> f -> g
+    doCall :: Call f -> g
 
 instance (CallArgs b b' r) => CallArgs (a -> b) (Value a -> b') r where
     type CalledFunction (Value a -> b') = a -> CalledFunction b'
     type CallerResult (Value a -> b') = CallerResult b'
     type CallerFunction (a -> b) r = Value a -> CallerFunction b r
-    doCall mkCall args f (Value arg) = doCall mkCall (arg : args) (f (undefined :: a))
+    doCall f a = doCall (applyCall f a)
 
 --instance (CallArgs b b') => CallArgs (a -> b) (ConstValue a -> b') where
 --    doCall mkCall args f (ConstValue arg) = doCall mkCall (arg : args) (f (undefined :: a))
@@ -888,7 +896,7 @@
     type CalledFunction (CodeGenFunction r (Value a)) = IO a
     type CallerResult (CodeGenFunction r (Value a)) = r
     type CallerFunction (IO a) r = CodeGenFunction r (Value a)
-    doCall = doCallDef
+    doCall = runCall
 
 doCallDef :: Caller -> [FFI.ValueRef] -> b -> CodeGenFunction r (Value a)
 doCallDef mkCall args _ =
@@ -898,17 +906,43 @@
 -- | Call a function with the given arguments.  The 'call' instruction is variadic, i.e., the number of arguments
 -- it takes depends on the type of /f/.
 call :: (CallArgs f g r) => Function f -> g
-call (Value f) = doCall (U.makeCall f) [] (undefined :: f)
+call = doCall . callFromFunction
 
+data Call a = Call Caller [FFI.ValueRef]
+
+callFromFunction :: Function a -> Call a
+callFromFunction (Value f) = Call (U.makeCall f) []
+
+-- like Applicative.<*>
+infixl 4 `applyCall`
+
+applyCall :: Call (a -> b) -> Value a -> Call b
+applyCall (Call mkCall args) (Value arg) = Call mkCall (arg:args)
+
+runCall :: Call (IO a) -> CodeGenFunction r (Value a)
+runCall (Call mkCall args) = doCallDef mkCall args ()
+
+
+invokeFromFunction ::
+          BasicBlock         -- ^Normal return point.
+       -> BasicBlock         -- ^Exception return point.
+       -> Function f         -- ^Function to call.
+       -> Call f
+invokeFromFunction (BasicBlock norm) (BasicBlock expt) (Value f) =
+    Call (U.makeInvoke norm expt f) []
+
 -- | Call a function with exception handling.
 invoke :: (CallArgs f g r)
        => BasicBlock         -- ^Normal return point.
        -> BasicBlock         -- ^Exception return point.
        -> Function f         -- ^Function to call.
        -> g
-invoke (BasicBlock norm) (BasicBlock expt) (Value f) =
-    doCall (U.makeInvoke norm expt f) [] (undefined :: f)
+invoke norm expt f = doCall $ invokeFromFunction norm expt f
 
+callWithConvFromFunction :: FFI.CallingConvention -> Function f -> Call f
+callWithConvFromFunction cc (Value f) =
+    Call (U.makeCallWithCc cc f) []
+
 -- | Call a function with the given arguments.  The 'call' instruction
 -- is variadic, i.e., the number of arguments it takes depends on the
 -- type of /f/.
@@ -917,8 +951,17 @@
 -- /instruction/ and the function being /called/ are different, undefined
 -- behavior results.
 callWithConv :: (CallArgs f g r) => FFI.CallingConvention -> Function f -> g
-callWithConv cc (Value f) = doCall (U.makeCallWithCc cc f) [] (undefined :: f)
+callWithConv cc f = doCall $ callWithConvFromFunction cc f
 
+invokeWithConvFromFunction ::
+          FFI.CallingConvention -- ^Calling convention
+       -> BasicBlock         -- ^Normal return point.
+       -> BasicBlock         -- ^Exception return point.
+       -> Function f         -- ^Function to call.
+       -> Call f
+invokeWithConvFromFunction cc (BasicBlock norm) (BasicBlock expt) (Value f) =
+    Call (U.makeInvokeWithCc cc norm expt f) []
+
 -- | Call a function with exception handling.
 -- This also sets the calling convention of the call to the function.
 -- As LLVM itself defines, if the calling conventions of the calling
@@ -930,8 +973,8 @@
                -> BasicBlock         -- ^Exception return point.
                -> Function f         -- ^Function to call.
                -> g
-invokeWithConv cc (BasicBlock norm) (BasicBlock expt) (Value f) =
-    doCall (U.makeInvokeWithCc cc norm expt f) [] (undefined :: f)
+invokeWithConv cc norm expt f =
+    doCall $ invokeWithConvFromFunction cc norm expt f
 
 --------------------------------------
 
diff --git a/LLVM/Util/Arithmetic.hs b/LLVM/Util/Arithmetic.hs
--- a/LLVM/Util/Arithmetic.hs
+++ b/LLVM/Util/Arithmetic.hs
@@ -183,7 +183,7 @@
 callIntrinsicP1 :: forall a b r . (IsFirstClass a, IsFirstClass b, IsPrimitive a) =>
                    String -> Value a -> TValue r b
 callIntrinsicP1 fn x = do
-    op :: Function (a -> IO b) <- externFunction ("llvm." ++ fn ++ "." ++ intrinsicTypeName (undefined :: a))
+    op <- externFunction ("llvm." ++ fn ++ "." ++ intrinsicTypeName (undefined :: a))
 {-
 You can add these attributes,
 but the verifier pass in the optimizer checks whether they match
@@ -191,13 +191,13 @@
 If we omit adding attributes then the right attributes are added automatically.
     addFunctionAttributes op [NoUnwindAttribute, ReadOnlyAttribute]
 -}
-    call op x >>= addReadNone
+    runCall (callFromFunction op `applyCall` x) >>= addReadNone
 
 callIntrinsicP2 :: forall a b c r . (IsFirstClass a, IsFirstClass b, IsFirstClass c, IsPrimitive a) =>
                    String -> Value a -> Value b -> TValue r c
 callIntrinsicP2 fn x y = do
-    op :: Function (a -> b -> IO c) <- externFunction ("llvm." ++ fn ++ "." ++ intrinsicTypeName (undefined :: a))
-    call op x y >>= addReadNone
+    op <- externFunction ("llvm." ++ fn ++ "." ++ intrinsicTypeName (undefined :: a))
+    runCall (callFromFunction op `applyCall` x `applyCall` y) >>= addReadNone
 
 -------------------------------------------
 
diff --git a/LLVM/Util/File.hs b/LLVM/Util/File.hs
--- a/LLVM/Util/File.hs
+++ b/LLVM/Util/File.hs
@@ -1,5 +1,5 @@
 module LLVM.Util.File(writeCodeGenModule, optimizeFunction, optimizeFunctionCG) where
-import System.Cmd(system)
+import System.Process (system)
 
 import LLVM.Core
 import LLVM.ExecutionEngine
diff --git a/llvm-tf.cabal b/llvm-tf.cabal
--- a/llvm-tf.cabal
+++ b/llvm-tf.cabal
@@ -1,5 +1,5 @@
 name:          llvm-tf
-version:       3.0.0.1
+version:       3.0.0.2
 license:       BSD3
 license-file:  LICENSE
 synopsis:      Bindings to the LLVM compiler toolkit using type families.
@@ -90,6 +90,6 @@
   location: http://code.haskell.org/~thielema/llvm-tf/
 
 source-repository this
-  tag:      3.0.0.1
+  tag:      3.0.0.2
   type:     darcs
   location: http://code.haskell.org/~thielema/llvm-tf/
