diff --git a/examples/brackets.hs b/examples/brackets.hs
--- a/examples/brackets.hs
+++ b/examples/brackets.hs
@@ -1,22 +1,22 @@
 -- From https://byorgey.wordpress.com/2016/10/25/adventures-in-enumerating-balanced-brackets/
 import Data.Unfolder
-import Data.MemoTrie (memo2)
+import Data.MemoTrie (memo)
 import Control.Applicative
 
-enumBrackets :: Unfolder f => Int -> f String
-enumBrackets n = enumBracketsTail n 0
+enumBrackets :: Unfolder f => f String
+enumBrackets = enumBracketsTail 0
 
-enumBracketsTail :: Unfolder f => Int -> Int -> f String
+enumBracketsTail :: Unfolder f => Int -> f String
 enumBracketsTail = enumBracketsTail'
   where
     -- Ensure memoization happens for a specific `f`
-    enumBracketsTail' = memo2 enumBracketsTail''
-    enumBracketsTail'' 0 c = pure (replicate c ')')
-    enumBracketsTail'' n 0 = ('(':) <$> enumBracketsTail' (n-1) 1
-    enumBracketsTail'' n c =
-      ('(':) <$> enumBracketsTail' (n-1) (c+1)
+    enumBracketsTail' = memo enumBracketsTail''
+    enumBracketsTail'' 0 = pure "" <|> choose [('(':) <$> enumBracketsTail' 1]
+    enumBracketsTail'' c =
+      choose [('(':) <$> enumBracketsTail' (c+1)]
       <|>
-      ((')':) <$> enumBracketsTail' n (c-1))
+      ((')':) <$> enumBracketsTail' (c-1))
+
 
 {-
 
diff --git a/examples/tree.hs b/examples/tree.hs
--- a/examples/tree.hs
+++ b/examples/tree.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DeriveFunctor, DeriveGeneric, DeriveAnyClass #-}
 
 import GHC.Generics
 import Data.Unfoldable
@@ -8,10 +8,8 @@
 import System.Random
 
 
-data Tree a = Empty | Node (Tree a) a (Tree a) deriving (Show, Generic1)
+data Tree a = Empty | Node (Tree a) a (Tree a) deriving (Show, Generic1, Unfoldable)
 
-instance Unfoldable Tree
-    
 tree7 :: Tree Int
 tree7 = fromJust $ fromList [0..6]
 
@@ -21,5 +19,10 @@
 treeShapes' :: [Tree ()]
 treeShapes' = take 20 $ bfsBySum unfold_
 
-randomTree :: IO (Tree Bool)
-randomTree = getStdRandom randomDefault
+data Pair a = Pair a a
+  deriving (Show, Functor, Generic1, Unfoldable)
+data PerfectTree a = Leaf a | Branch (PerfectTree (Pair a))
+  deriving (Show, Functor, Generic1, Unfoldable)
+
+ptreeShapes :: [PerfectTree ()]
+ptreeShapes = take 5 unfoldBF_
diff --git a/src/Data/Unfoldable.hs b/src/Data/Unfoldable.hs
--- a/src/Data/Unfoldable.hs
+++ b/src/Data/Unfoldable.hs
@@ -54,6 +54,7 @@
 
 #ifdef GENERICS
 import GHC.Generics
+import Generics.OneLiner
 #endif
 
 -- | Data structures that can be unfolded.
@@ -91,40 +92,8 @@
   unfold :: Unfolder f => f a -> f (t a)
 
 #ifdef GENERICS
-
-  default unfold :: (Generic1 t, GUnfold (Rep1 t), Unfolder f) => f a -> f (t a)
-  unfold fa = to1 <$> choose (gunfold fa)
-
-class GUnfold r where
-  gunfold :: Unfolder f => f a -> [f (r a)]
-
-instance GUnfold V1 where
-  gunfold _ = []
-
-instance GUnfold U1 where
-  gunfold _ = [pure U1]
-
-instance GUnfold Par1 where
-  gunfold fa = [Par1 <$> fa]
-
-instance Unfoldable f => GUnfold (Rec1 f) where
-  gunfold fa = [Rec1 <$> unfold fa]
-
-instance (Bounded c, Enum c) => GUnfold (K1 i c) where
-  gunfold _ = [K1 <$> boundedEnum]
-
-instance GUnfold f => GUnfold (M1 i c f) where
-  gunfold fa = map (M1 <$>) (gunfold fa)
-
-instance (GUnfold f, GUnfold g) => GUnfold (f :+: g) where
-  gunfold fa = map (L1 <$>) (gunfold fa) ++ map (R1 <$>) (gunfold fa)
-
-instance (GUnfold f, GUnfold g) => GUnfold (f :*: g) where
-  gunfold fa = liftA2 (:*:) <$> gunfold fa <*> gunfold fa
-
-instance (GUnfold f, GUnfold g) => GUnfold (f :.: g) where
-  gunfold fa = map (Comp1 <$>) (gunfold (choose (gunfold fa)))
-
+  default unfold :: (ADT1 t, Constraints1 t Unfoldable, Unfolder f) => f a -> f (t a)
+  unfold = choose . getCompose . createA1 (For :: For Unfoldable) (Compose . return . unfold . foldr (<|>) empty . getCompose) . Compose . return
 #endif
 
 -- | Unfold the structure, always using @()@ as elements.
diff --git a/src/Data/Unfolder.hs b/src/Data/Unfolder.hs
--- a/src/Data/Unfolder.hs
+++ b/src/Data/Unfolder.hs
@@ -120,7 +120,7 @@
 between :: (Unfolder f, Enum a) => a -> a -> f a
 between lb ub = (\x -> toEnum (x + fromEnum lb)) <$> chooseInt (1 + fromEnum ub - fromEnum lb)
 
--- | If a datatype is also bounded, we choose between all possible values.
+-- | If a datatype is also bounded, we can choose between all possible values.
 --
 -- > boundedEnum = between minBound maxBound
 boundedEnum :: (Unfolder f, Bounded a, Enum a) => f a
diff --git a/unfoldable.cabal b/unfoldable.cabal
--- a/unfoldable.cabal
+++ b/unfoldable.cabal
@@ -1,5 +1,5 @@
 Name:                 unfoldable
-Version:              0.9.1
+Version:              0.9.2
 Synopsis:             Class of data structures that can be unfolded.
 Description:          Just as there's a Foldable class, there should also be an Unfoldable class.
                       .
@@ -44,7 +44,9 @@
 
   if impl(ghc >= 7.6)
     cpp-options:   -DGENERICS
-    build-depends: ghc-prim >= 0.2
+    build-depends:
+        ghc-prim     >= 0.2
+      , one-liner    >= 0.7 && < 0.8
 
   Other-extensions:
       GeneralizedNewtypeDeriving
