diff --git a/interpolate.cabal b/interpolate.cabal
--- a/interpolate.cabal
+++ b/interpolate.cabal
@@ -1,11 +1,11 @@
--- This file has been generated from package.yaml by hpack version 0.26.0.
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.34.2.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: cc8a15b9e3938bac2066e1f8e454e027bd589000a0baf42191f06ceb39e9ce04
 
 name:             interpolate
-version:          0.2.0
+version:          0.2.1
 homepage:         https://github.com/sol/interpolate#readme
 bug-reports:      https://github.com/sol/interpolate/issues
 license:          MIT
@@ -14,7 +14,6 @@
 author:           Simon Hengel <sol@typeful.net>
 maintainer:       Simon Hengel <sol@typeful.net>
 build-type:       Simple
-cabal-version:    >= 1.10
 category:         Data, Text
 stability:        experimental
 synopsis:         String interpolation done right
diff --git a/src/Data/String/Interpolate.hs b/src/Data/String/Interpolate.hs
--- a/src/Data/String/Interpolate.hs
+++ b/src/Data/String/Interpolate.hs
@@ -15,7 +15,7 @@
 
 import           Data.String.Interpolate.Internal.Util
 import           Data.String.Interpolate.Parse
-import           Data.String.Interpolate.Compat (Q, Exp, appE, reportError)
+import           Language.Haskell.TH
 
 -- |
 -- A `QuasiQuoter` for string interpolation.  Expression enclosed within
@@ -48,20 +48,37 @@
   where
     err name = error ("Data.String.Interpolate.i: This QuasiQuoter can not be used as a " ++ name ++ "!")
 
-    toExp:: [Node] -> Q Exp
-    toExp nodes = case nodes of
-      [] -> [|""|]
-      (x:xs) -> f x `appE` toExp xs
+    toExp :: [Node ()] -> Q Exp
+    toExp input = do
+      nodes <- mapM generateName input
+      e <- go nodes
+      return $ foldr lambda e [name | Abstraction name <- nodes]
       where
-        f (Literal s) = [|showString s|]
-        f (Expression e) = [|(showString . toString) $(reifyExpression e)|]
+        lambda :: Name -> Exp -> Exp
+        lambda name e = LamE [VarP name] e
 
-        reifyExpression :: String -> Q Exp
-        reifyExpression s = case parseExp s of
-          Left _ -> do
-            reportError "Parse error in expression!"
-            [|""|]
-          Right e -> return e
+        generateName :: Node () -> Q (Node Name)
+        generateName (Abstraction ()) = Abstraction <$> newName "x"
+        generateName (Literal s) = return (Literal s)
+        generateName (Expression e) = return (Expression e)
+
+        go :: [Node Name] -> Q Exp
+        go nodes = case nodes of
+          [] -> [|""|]
+          (x:xs) -> eval x `appE` go xs
+          where
+            eval (Literal s) = [|showString s|]
+            eval (Expression e) = interpolate (reifyExpression e)
+            eval (Abstraction name) = interpolate $ (return $ VarE name)
+
+            interpolate :: Q Exp -> Q Exp
+            interpolate e = [|(showString . toString) $(e)|]
+
+            reifyExpression :: String -> Q Exp
+            reifyExpression s = case parseExp s of
+              Left _ -> do
+                fail "Parse error in expression!" :: Q Exp
+              Right e -> return e
 
 decodeNewlines :: String -> String
 decodeNewlines = go
diff --git a/src/Data/String/Interpolate/Compat.hs b/src/Data/String/Interpolate/Compat.hs
--- a/src/Data/String/Interpolate/Compat.hs
+++ b/src/Data/String/Interpolate/Compat.hs
@@ -1,13 +1,8 @@
 {-# LANGUAGE CPP #-}
 module Data.String.Interpolate.Compat (
   readMaybe
-, module Language.Haskell.TH
-#if !MIN_VERSION_template_haskell(2,8,0)
-, reportError
-#endif
 ) where
 
-import           Language.Haskell.TH
 import           Text.Read
 
 #if !MIN_VERSION_base(4,6,0)
@@ -36,9 +31,4 @@
 readMaybe s = case readEither s of
                 Left _  -> Nothing
                 Right a -> Just a
-#endif
-
-#if !MIN_VERSION_template_haskell(2,8,0)
-reportError :: String -> Q ()
-reportError = report True
 #endif
diff --git a/src/Data/String/Interpolate/Parse.hs b/src/Data/String/Interpolate/Parse.hs
--- a/src/Data/String/Interpolate/Parse.hs
+++ b/src/Data/String/Interpolate/Parse.hs
@@ -2,19 +2,23 @@
 
 import           Data.String.Interpolate.Internal.Util
 
-data Node = Literal String | Expression String
+data Node a = Literal String | Expression String | Abstraction a
 
-parseNodes :: String -> [Node]
+parseNodes :: String -> [Node ()]
 parseNodes = go ""
   where
-    go :: String -> String -> [Node]
+    go :: String -> String -> [Node ()]
     go acc input = case input of
-      ""  -> [(lit . reverse) acc]
+      ""  -> lit []
       '\\':x:xs -> go (x:'\\':acc) xs
-      '#':'{':xs -> case span (/= '}') xs of
-        (ys, _:zs) -> (lit . reverse) acc : Expression ys : go "" zs
-        (_, "") -> [lit (reverse acc ++ input)]
+      '#':'{':xs | (e, '}':ys) <- span (/= '}') xs -> lit $ expression e : go "" ys
       x:xs -> go (x:acc) xs
+      where
+        expression e
+          | null e = Abstraction ()
+          | otherwise = Expression e
 
-    lit :: String -> Node
-    lit = Literal . unescape
+        lit :: [Node ()] -> [Node ()]
+        lit nodes
+          | null acc = nodes
+          | otherwise = (Literal . unescape $ reverse acc) : nodes
diff --git a/test/Data/String/Interpolate/ParseSpec.hs b/test/Data/String/Interpolate/ParseSpec.hs
--- a/test/Data/String/Interpolate/ParseSpec.hs
+++ b/test/Data/String/Interpolate/ParseSpec.hs
@@ -6,8 +6,8 @@
 
 import           Data.String.Interpolate.Parse
 
-deriving instance Eq Node
-deriving instance Show Node
+deriving instance Eq a => Eq (Node a)
+deriving instance Show a => Show (Node a)
 
 main :: IO ()
 main = hspec spec
@@ -17,6 +17,12 @@
   describe "parseNodes" $ do
     it "parses string literals" $ do
       parseNodes "foo" `shouldBe` [Literal "foo"]
+
+    it "parses abstractions" $ do
+      parseNodes "#{}" `shouldBe` [Abstraction ()]
+
+    it "parses expressions" $ do
+      parseNodes "#{foo}" `shouldBe` [Expression "foo"]
 
     it "parses embedded expressions" $ do
       parseNodes "foo #{bar} baz" `shouldBe` [Literal "foo ", Expression "bar", Literal " baz"]
diff --git a/test/Data/String/InterpolateSpec.hs b/test/Data/String/InterpolateSpec.hs
--- a/test/Data/String/InterpolateSpec.hs
+++ b/test/Data/String/InterpolateSpec.hs
@@ -18,6 +18,9 @@
     it "interpolates an expression of type String" $ do
       property $ \xs ys -> [i|foo #{xs ++ ys} bar|] `shouldBe` "foo " ++ xs ++ ys ++ " bar"
 
+    it "interpolates abstractions" $ do
+      [i|foo #{} bar #{} baz|] (23 :: Int) "test" `shouldBe` "foo 23 bar test baz"
+
     it "accepts character escapes" $ do
       [i|foo \955 bar|] `shouldBe` "foo \955 bar"
 
