diff --git a/call-haskell-from-anything.cabal b/call-haskell-from-anything.cabal
--- a/call-haskell-from-anything.cabal
+++ b/call-haskell-from-anything.cabal
@@ -1,5 +1,5 @@
 name:          call-haskell-from-anything
-version:       0.2.0.0
+version:       1.0.0.0
 license:       MIT
 author:        Niklas Hambüchen (mail@nh2.me)
 maintainer:    Niklas Hambüchen (mail@nh2.me)
@@ -34,7 +34,6 @@
   exposed-modules:
     FFI.Anything.TH
     FFI.Anything.TypeUncurry
-    FFI.Anything.TypeUncurry.ReturnResult
     FFI.Anything.TypeUncurry.Msgpack
     FFI.Anything.TypeUncurry.DataKinds
   build-depends:
diff --git a/src/FFI/Anything/TypeUncurry/DataKinds.hs b/src/FFI/Anything/TypeUncurry/DataKinds.hs
--- a/src/FFI/Anything/TypeUncurry/DataKinds.hs
+++ b/src/FFI/Anything/TypeUncurry/DataKinds.hs
@@ -12,28 +12,11 @@
 -- like tuples/lists, but de-serializing *fuction arguments* is not that simple.
 --
 -- Using this module, you can write an instance how to unpack the 'TypeList' type,
--- and then use 'translateCall' to make any function take such a single 'TypeList'
+-- and then use 'translate' to make any function take such a single 'TypeList'
 -- instead of multiple function arguments.
---
--- There is currently a technical limitation:
--- The result type must be wrapped in the 'Identity' monad.
---
--- Example:
---
--- >-- Assume your library provides some unpack function, e.g. it allows you to write:
--- >unpack someBytestring :: (Int, String, Double)
--- >
--- >-- and you have a function
--- >f :: Int -> String -> Double -> Identity Char
--- >
--- >-- then you can use:
--- >f' :: (Int, String, Double) -> Identity Char
--- >f' = translateCall f
--- >
--- >result = f' (unpack someBytestring)
 module FFI.Anything.TypeUncurry.DataKinds where
 
-import           Control.Monad.Identity
+import           Data.Proxy
 
 
 -- * Type-level lists (containing types)
@@ -72,18 +55,15 @@
 -}
 
 -- | Arguments to a function, e.g. @[String, Int]@ for @String -> Int -> r@.
-type family Param f :: [*]
--- | For pure functions, we need an 'Identity' monad wrapper here to not conflict with @a -> f@.
-type instance Param (Identity r) = '[]
-type instance Param (IO r) = '[]
-type instance Param (a -> f) = a ': Param f
+type family Param f :: [*] where
+  Param (a -> f) = a ': Param f
+  Param r = '[]
 
 -- | The result of a function, e.g. @r@ for @String -> Int -> r@.
-type family Result f :: *
--- | For pure functions, we need an 'Identity' monad wrapper here to not conflict with @a -> f@.
-type instance Result (Identity r) = r
-type instance Result (IO r) = IO r
-type instance Result (a -> f) = Result f
+type family Result f :: * where
+  Result (IO r) = IO r
+  Result (a -> f) = Result f
+  Result r = r
 
 
 -- | Function f can be translated to 'TypeList' l with result type r.
@@ -94,25 +74,28 @@
   -- Example: @t1 -> ... -> tn -> r@ becomes @TypeList [t1, ..., tn] -> r@.
   translate :: f -> TypeList l -> r
 
--- | Recursive case: A function of type @a -> ... -> r@
--- can be translated to @TypeList [a, ...] -> r@.
-instance ToTypeList (Identity r) '[] r where
-  translate (Identity r) Nil = r
 
--- | Base case: A "pure" function without arguments (just @Identity r@)
+-- | Base case: A "pure" function without arguments
 -- can be translated to @TypeList Nil -> r@.
 instance (ToTypeList f l r) => ToTypeList (a -> f) (a ': l) r where
   translate f (a ::: l) = translate (f a) l
 
--- | Base case: An IO function without arguments (just @Identity r@)
+-- | Base case: An IO function without arguments (just @IO r@)
 -- can be translated to @TypeList Nil -> r@.
 instance ToTypeList (IO r) '[] (IO r) where
   translate ior Nil = ior
 
+-- | Base case: A value @r@ can be translated to @TypeList Nil -> r@.
+instance (Param f ~ '[], Result f ~ r, f ~ r) => ToTypeList f '[] r where
+  -- Could also be written as
+  --   (Param r ~ '[], Result r ~ r) => ToTypeList r '[] r
+  -- but I find the other way clearer.
+  translate r Nil = r
 
+
 -- Now an example:
 --
--- someFunction :: Int -> Double -> Identity String
+-- someFunction :: Int -> Double -> String
 -- someFunction _i _d = return "asdf"
 --
 -- exampleAutoTranslate = translate someFunction
@@ -122,24 +105,17 @@
 
 -- * Length of type-level lists
 
--- | A proxy type that can contain an arbitrary type.
---
--- Needed for some type-level computations, like 'paramLength'.
-data Proxy k = Proxy
-
-
 -- | Allows to calculate the length of a 'TypeList', at compile time.
 --
 -- We need to use a 'Proxy' for this.
 class ParamLength (l :: [*]) where
   -- | Calculates the length of a type list, put into a proxy. Usage:
   --
-  -- >paramLength (undefined :: Proxy l)
+  -- >paramLength (Proxy :: Proxy l)
   paramLength :: Proxy l -> Int
 
 instance ParamLength '[] where
   paramLength _ = 0
 
 instance (ParamLength l) => ParamLength (a ': l) where
-  paramLength _ = succ $ paramLength (undefined :: Proxy l)
-
+  paramLength _ = succ $ paramLength (Proxy :: Proxy l)
diff --git a/src/FFI/Anything/TypeUncurry/Msgpack.hs b/src/FFI/Anything/TypeUncurry/Msgpack.hs
--- a/src/FFI/Anything/TypeUncurry/Msgpack.hs
+++ b/src/FFI/Anything/TypeUncurry/Msgpack.hs
@@ -27,7 +27,6 @@
 , byteStringToCStringFunIO
 , export
 , exportIO
-, module FFI.Anything.TypeUncurry.ReturnResult
 ) where
 
 import           Data.ByteString (ByteString)
@@ -35,12 +34,11 @@
 import qualified Data.ByteString.Lazy as BSL
 import           Data.Maybe (fromMaybe)
 import qualified Data.MessagePack as MSG
+import           Data.Proxy
 import           Data.Vector (Vector)
 import qualified Data.Vector as V
 import           Foreign.C
 
-import FFI.Anything.TypeUncurry.ReturnResult
-
 import FFI.Anything.TypeUncurry
 
 
@@ -79,7 +77,7 @@
 errorMsg locationStr = "call-haskell-from-anything: " ++ locationStr ++ ": got wrong number of function arguments or non-array"
 
 
--- | Translates a function of type @a -> b -> ... -> Identity r@ to
+-- | Translates a function of type @a -> b -> ... -> r@ to
 -- a function that:
 --
 -- * takes as a single argument a 'ByteString' containing all arguments serialized in a MessagePack array
@@ -139,7 +137,7 @@
   return res_cs
 
 
--- | Exports a "pure" function (usually it has to be wrapped in the Identity monad)
+-- | Exports a "pure" function
 -- to an FFI function that takes its arguments as a serialized MessagePack message.
 --
 -- Calling this function throws an 'error' if the de-serialization of the arguments fails!
diff --git a/src/FFI/Anything/TypeUncurry/ReturnResult.hs b/src/FFI/Anything/TypeUncurry/ReturnResult.hs
deleted file mode 100644
--- a/src/FFI/Anything/TypeUncurry/ReturnResult.hs
+++ /dev/null
@@ -1,48 +0,0 @@
-module FFI.Anything.TypeUncurry.ReturnResult where
-
-import Control.Monad.Identity
-
-
-return1 :: (Monad m) => r -> m r
-return1 = return
-
-return2 :: (Monad m) => (a -> r) -> a -> m r
-return2 f a = return $ f a
-
-return3 :: (Monad m) => (a -> b -> r) -> a -> b -> m r
-return3 f a b = return $ f a b
-
-return4 :: (Monad m) => (a -> b -> c -> r) -> a -> b -> c -> m r
-return4 f a b c = return $ f a b c
-
-return5 :: (Monad m) => (a -> b -> c -> d -> r) -> a -> b -> c -> d -> m r
-return5 f a b c d = return $ f a b c d
-
-return6 :: (Monad m) => (a -> b -> c -> d -> e -> r) -> a -> b -> c -> d -> e -> m r
-return6 f a b c d e = return $ f a b c d e
-
-return7 :: (Monad m) => (a -> b -> c -> d -> e -> f -> r) -> a -> b -> c -> d -> e -> f -> m r
-return7 f a b c d e = return . f a b c d e -- We don't want to use f again, haha!
-
-
-returnId1 :: r -> Identity r
-returnId1 = return1
-
-returnId2 :: (a -> r) -> a -> Identity r
-returnId2 = return2
-
-returnId3 :: (a -> b -> r) -> a -> b -> Identity r
-returnId3 = return3
-
-returnId4 :: (a -> b -> c -> r) -> a -> b -> c -> Identity r
-returnId4 = return4
-
-returnId5 :: (a -> b -> c -> d -> r) -> a -> b -> c -> d -> Identity r
-returnId5 = return5
-
-returnId6 :: (a -> b -> c -> d -> e -> r) -> a -> b -> c -> d -> e -> Identity r
-returnId6 = return6
-
-returnId7 :: (a -> b -> c -> d -> e -> f -> r) -> a -> b -> c -> d -> e -> f -> Identity r
-returnId7 = return7
-
diff --git a/test/Test1.hs b/test/Test1.hs
--- a/test/Test1.hs
+++ b/test/Test1.hs
@@ -6,9 +6,7 @@
 import           Data.ByteString (ByteString)
 import qualified Data.ByteString as BS
 import qualified Data.ByteString.Lazy as BSL
-import           Data.Monoid
 import qualified Data.MessagePack as MSG
-import           Control.Monad.Identity
 
 import Foreign.C
 
@@ -41,17 +39,8 @@
     return res_cs
 
 
-f1_identity :: Int -> Double -> Identity String
-f1_identity a b = return $ f1 a b
-
-
--- Only works in GHC 7.6
--- f1_t :: CString -> IO CString
--- f1_t :: ByteString -> ByteString
--- f1_t = translateCall f1_identity
-
 f1_t :: ByteString -> ByteString
-f1_t = uncurryMsgpack f1_identity
+f1_t = uncurryMsgpack f1
 
 foreign export ccall f1_t_export :: CString -> IO CString
 f1_t_export :: CString -> IO CString
@@ -73,7 +62,7 @@
 
 foreign export ccall fib_export :: CString -> IO CString
 fib_export :: CString -> IO CString
-fib_export = export . returnId2 $ fib
+fib_export = export fib
 
 
 -- TODO the sole *presence* of this function seems to make the calls in Python slower
