diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # Revision history for polyvariadic
 
+## 0.3.0.3  -- 2017-04-19
+
+* Fixed infinite loop on apply and apply'
+
 ## 0.3.0.2  -- 2017-12-19
 
 * Added readme to extra-source-files so it shows up on hackage
diff --git a/Data/Function/Polyvariadic.hs b/Data/Function/Polyvariadic.hs
--- a/Data/Function/Polyvariadic.hs
+++ b/Data/Function/Polyvariadic.hs
@@ -97,7 +97,7 @@
 
 -- | The final type is not reached yet and the application continues
 instance (Apply a b x) => Apply a b (a -> x) where
-  apply' f (x:xs) = apply (f x) xs
+  apply' f (x:xs) = apply' (f x) xs
   apply' _ _ = error "Not enough arguments in polyvariadic application"
 
 -- | The final type is reached and the application terminates
@@ -106,5 +106,5 @@
 
 -- | Like 'apply'' but with an arbitrary 'Foldable' instead if a list
 apply :: (Apply a b x, Foldable t) => x -> t a -> b
-apply f = apply f . toList
+apply f = apply' f . toList
 
diff --git a/polyvariadic.cabal b/polyvariadic.cabal
--- a/polyvariadic.cabal
+++ b/polyvariadic.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                polyvariadic
-version:             0.3.0.2
+version:             0.3.0.3
 synopsis:            Creation and application of polyvariadic functions
 description:         Creation and application of polyvariadic functions, see the docs for usage and examples
 homepage:            https://github.com/fgaz/polyvariadic
@@ -32,4 +32,11 @@
   -- hs-source-dirs:      
   default-language:    Haskell2010
   ghc-options:         -Wall
+
+test-suite tests
+  type: exitcode-stdio-1.0
+  build-depends: base, polyvariadic
+  default-language:    Haskell2010
+  main-is: Main.hs
+  hs-source-dirs: tests
 
diff --git a/tests/Main.hs b/tests/Main.hs
new file mode 100644
--- /dev/null
+++ b/tests/Main.hs
@@ -0,0 +1,35 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE CPP #-}
+import Data.Function.Polyvariadic
+import Data.Accumulator
+import Control.Exception (assert)
+
+#if !MIN_VERSION_base(4,8,0)
+import Data.Foldable
+import Data.Monoid
+#endif
+
+main = do
+  putStrLn one
+  assert (one == "[3,2,1]") $ return ()
+  putStrLn two
+  assert (two == "aaa\"TEST\"bbb123cccTrueddd") $ return ()
+  putStrLn three
+  assert (three == "3") $ return ()
+
+one = show (polyvariadic mempty (id :: [Int] -> [Int]) (1::Int) (2::Int) (3::Int) :: [Int])
+two = printf' "aaa%bbb%ccc%ddd" "TEST" 123 True 1.2
+three = show (apply ((+) :: Int -> Int -> Int) ([1,2] :: [Int]) :: Int)
+
+magicChar = '%'
+
+data PrintfAccum = PrintfAccum { done :: String, todo :: String }
+
+instance Show x => Accumulator PrintfAccum x where
+  accumulate x (PrintfAccum done (_:todo)) = PrintfAccum (done ++ show x ++ takeWhile (/= magicChar) todo) (dropWhile (/= magicChar) todo)
+  accumulate _ acc = acc
+
+printf' str = polyvariadic (PrintfAccum (takeWhile (/= magicChar) str) (dropWhile (/= magicChar) str)) done
+
