diff --git a/src/Control/Applicative/HT.hs b/src/Control/Applicative/HT.hs
--- a/src/Control/Applicative/HT.hs
+++ b/src/Control/Applicative/HT.hs
@@ -12,6 +12,13 @@
 mapTriple fgh = Tuple.uncurry3 (liftA3 (,,)) . Tuple.mapTriple fgh
 
 
+curry :: (Applicative f) => (f (a,b) -> g) -> f a -> f b -> g
+curry f a b = f $ lift2 (,) a b
+
+curry3 :: (Applicative f) => (f (a,b,c) -> g) -> f a -> f b -> f c -> g
+curry3 f a b c = f $ lift3 (,,) a b c
+
+
 {-# INLINE lift #-}
 lift :: Applicative m => (a -> r) -> m a -> m r
 lift = fmap
diff --git a/src/Control/Functor/HT.hs b/src/Control/Functor/HT.hs
--- a/src/Control/Functor/HT.hs
+++ b/src/Control/Functor/HT.hs
@@ -1,8 +1,12 @@
 module Control.Functor.HT where
 
-import Data.Tuple.HT (fst3, snd3, thd3, )
+import qualified Data.Tuple.HT as Tuple
+import Data.Tuple.HT (fst3, snd3, thd3)
 
+import qualified Prelude as P
+import Prelude (Functor, fmap, flip, const, (.), ($), fst, snd)
 
+
 void :: Functor f => f a -> f ()
 void = fmap (const ())
 
@@ -27,6 +31,19 @@
 -}
 unzip3 :: Functor f => f (a, b, c) -> (f a, f b, f c)
 unzip3 x = (fmap fst3 x, fmap snd3 x, fmap thd3 x)
+
+
+{- |
+Caution: See 'unzip'.
+-}
+uncurry :: Functor f => (f a -> f b -> g) -> f (a, b) -> g
+uncurry f = P.uncurry f . unzip
+
+{- |
+Caution: See 'unzip'.
+-}
+uncurry3 :: Functor f => (f a -> f b -> f c -> g) -> f (a, b, c) -> g
+uncurry3 f = Tuple.uncurry3 f . unzip3
 
 
 mapFst :: Functor f => (a -> f c) -> (a, b) -> f (c, b)
diff --git a/src/Data/Function/HT/Private.hs b/src/Data/Function/HT/Private.hs
--- a/src/Data/Function/HT/Private.hs
+++ b/src/Data/Function/HT/Private.hs
@@ -1,6 +1,8 @@
 module Data.Function.HT.Private where
 
-import Data.List (genericReplicate, )
+import Data.List (genericReplicate, unfoldr)
+import Data.Maybe.HT (toMaybe)
+import Data.Tuple.HT (swap)
 
 {- |
 Compositional power of a function,
@@ -16,11 +18,7 @@
 nest1 n f = foldr (.) id (replicate n f)
 nest2 n f x = iterate f x !! n
 
-propNest :: (Eq a) => Int -> (a -> a) -> a -> Bool
-propNest n f x =
-   nest n f x == nest1 n f x
 
-
 {- |
 @powerAssociative@ is an auxiliary function that,
 for an associative operation @op@,
@@ -32,16 +30,20 @@
 -}
 
 {-# INLINE powerAssociative #-}
-{-# INLINE powerAssociative1 #-}
-powerAssociative, powerAssociative1 ::
+powerAssociative, powerAssociativeList, powerAssociativeNaive ::
    (a -> a -> a) -> a -> a -> Integer -> a
-powerAssociative _  a0 _ 0 = a0
-powerAssociative op a0 a n =
-   powerAssociative op
-      (if even n then a0 else (op a0 a))
-      (op a a) (div n 2)
+powerAssociative op =
+   let go acc _ 0 = acc
+       go acc a n = go (if even n then acc else op acc a) (op a a) (div n 2)
+   in  go
 
-powerAssociative1 op a0 a n =
+powerAssociativeList op a0 a n =
+   foldl (\acc (bit,pow) -> if bit==0 then acc else op acc pow) a0 $
+   zip
+      (unfoldr (\k -> toMaybe (k>0) $ swap $ divMod k 2) n)
+      (iterate (\pow -> op pow pow) a)
+
+powerAssociativeNaive op a0 a n =
    foldr op a0 (genericReplicate n a)
 
 
diff --git a/src/Data/Tuple/HT.hs b/src/Data/Tuple/HT.hs
--- a/src/Data/Tuple/HT.hs
+++ b/src/Data/Tuple/HT.hs
@@ -24,6 +24,9 @@
 import Data.Tuple.Lazy
 
 
+{- |
+Known as @dup@ in the 'Arrow' literature.
+-}
 {-# INLINE double #-}
 double :: a -> (a,a)
 double a = (a,a)
diff --git a/src/Data/Tuple/Lazy.hs b/src/Data/Tuple/Lazy.hs
--- a/src/Data/Tuple/Lazy.hs
+++ b/src/Data/Tuple/Lazy.hs
@@ -32,6 +32,10 @@
 mapSnd :: (b -> c) -> (a,b) -> (a,c)
 mapSnd f ~(a,b) = (a, f b)
 
+{-# INLINE zipPair #-}
+zipPair :: (a,b) -> (c,d) -> ((a,c),(b,d))
+zipPair ~(a,b) ~(c,d) = ((a,c),(b,d))
+
 {-# INLINE zipWithPair #-}
 zipWithPair :: (a -> c -> e, b -> d -> f) -> (a,b) -> (c,d) -> (e,f)
 zipWithPair ~(e,f) ~(a,b) ~(c,d) = (e a c, f b d)
diff --git a/src/Data/Tuple/Strict.hs b/src/Data/Tuple/Strict.hs
--- a/src/Data/Tuple/Strict.hs
+++ b/src/Data/Tuple/Strict.hs
@@ -14,6 +14,10 @@
 mapSnd :: (b -> c) -> (a,b) -> (a,c)
 mapSnd f (a,b) = (a, f b)
 
+{-# INLINE zipPair #-}
+zipPair :: (a,b) -> (c,d) -> ((a,c),(b,d))
+zipPair (a,b) (c,d) = ((a,c),(b,d))
+
 {-# INLINE zipWithPair #-}
 zipWithPair :: (a -> c -> e, b -> d -> f) -> (a,b) -> (c,d) -> (e,f)
 zipWithPair (e,f) (a,b) (c,d) = (e a c, f b d)
diff --git a/src/Test/Data/Function.hs b/src/Test/Data/Function.hs
--- a/src/Test/Data/Function.hs
+++ b/src/Test/Data/Function.hs
@@ -2,17 +2,26 @@
 
 import qualified Data.Function.HT.Private as FuncHT
 
-import Test.QuickCheck (Property, quickCheck, (==>), )
+import Test.QuickCheck (NonNegative(NonNegative), quickCheck)
 
 
+nest :: (Eq a) => NonNegative Int -> (a -> a) -> a -> Bool
+nest (NonNegative n) f x =
+   FuncHT.nest n f x == FuncHT.nest1 n f x &&
+   FuncHT.nest n f x == FuncHT.nest2 n f x
+
 powerAssociative :: Eq a =>
-   (a -> a -> a) -> a -> a -> Integer -> Property
-powerAssociative op a0 a n =
-   n>0 ==>
-      FuncHT.powerAssociative op a0 a n == FuncHT.powerAssociative1 op a0 a n
+   (a -> a -> a) -> a -> a -> NonNegative Integer -> Bool
+powerAssociative op a0 a (NonNegative n) =
+   FuncHT.powerAssociative op a0 a n == FuncHT.powerAssociativeList op a0 a n &&
+   FuncHT.powerAssociative op a0 a n == FuncHT.powerAssociativeNaive op a0 a n
 
 
 tests :: [(String, IO ())]
 tests =
-   ("powerAssociative", quickCheck (powerAssociative (+) :: Integer -> Integer -> Integer -> Property)) :
+   ("nest",
+      quickCheck (flip nest succ :: NonNegative Int -> Integer -> Bool)) :
+   ("powerAssociative",
+      quickCheck (powerAssociative (+) ::
+         Integer -> Integer -> NonNegative Integer -> Bool)) :
    []
diff --git a/utility-ht.cabal b/utility-ht.cabal
--- a/utility-ht.cabal
+++ b/utility-ht.cabal
@@ -1,5 +1,5 @@
 Name:             utility-ht
-Version:          0.0.14
+Version:          0.0.15
 License:          BSD3
 License-File:     LICENSE
 Author:           Henning Thielemann <haskell@henning-thielemann.de>
@@ -44,7 +44,7 @@
 Source-Repository this
   type:     darcs
   location: http://code.haskell.org/~thielema/utility/
-  tag:      0.0.14
+  tag:      0.0.15
 
 Library
   Build-Depends:
