diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -53,6 +53,8 @@
 module Example where
 
 import Control.Lens ((.~), (^.), (&), Const (..), Identity, anyOf)
+import Data.Funtor.Const (Const (..))
+import Data.Funtor.Identity (Identity (..))
 import Data.Generic.HKD
 import Data.Maybe (isJust, isNothing)
 import Data.Monoid (Last (..))
@@ -163,14 +165,27 @@
 -- Last {getLast = Just (Triple 123 () "ABC")}
 ```
 
+If none of the above suit your needs, maybe you want to try `build` on for
+size. This function constructs an `HKD`-wrapped version of the type supplied to
+it by taking all its parameters. In other words:
+
+```haskell
+eg6 :: f Int -> f () -> f String -> HKD Triple f
+eg6 = build @Triple
+
+eg7 :: HKD Triple []
+eg7 = eg6 [1] [] ["Tom", "Tim"]
+-- Triple [1] [] ["Tom","Tim"]
+```
+
 ### Field Access
 
 The `field` lens, when given a type-applied field name, allows us to focus on
 fields within a record:
 
 ```haskell
-eg6 :: Last Int
-eg6 = eg0 ^. field @"age"
+eg8 :: Last Int
+eg8 = eg0 ^. field @"age"
 -- Last {getLast = Nothing}
 ```
 
@@ -179,8 +194,8 @@
 choice):
 
 ```haskell
-eg7 :: Partial User
-eg7 = eg0 & field @"name"      .~ pure "Evil Tom"
+eg9 :: Partial User
+eg9 = eg0 & field @"name"      .~ pure "Evil Tom"
           & field @"likesDogs" .~ pure False     
 -- User
 --   { name      = Last {getLast = Just "Evil Tom"}
@@ -193,8 +208,8 @@
 completed for a given partial type:
 
 ```haskell
-eg8 :: Bool
-eg8 = anyOf (field @"name") (isJust . getLast) eg0
+eg10 :: Bool
+eg10 = anyOf (field @"name") (isJust . getLast) eg0
 -- False
 ```
 
@@ -203,8 +218,8 @@
 doesn't exist in our type:
 
 ```haskell
-eg9 :: Identity ()
-eg9 = eg3 ^. field @"oops"
+eg11 :: Identity ()
+eg11 = eg3 ^. field @"oops"
 -- error:
 -- • The type User does not contain a field named 'oops'.
 ```
@@ -215,8 +230,8 @@
 product types:
 
 ```haskell
-eg10 :: Labels Triple
-eg10 = mempty & position @1 .~ Const "hello"
+eg12 :: Labels Triple
+eg12 = mempty & position @1 .~ Const "hello"
               & position @2 .~ Const "world"
 -- Triple
 --   Const "hello"
@@ -227,8 +242,8 @@
 Again, this is a `Lens`, so we can just as easily _set_ values:
 
 ```haskell
-eg11 :: Partial User
-eg11 = eg7 & position @2 .~ pure 25
+eg13 :: Partial User
+eg13 = eg9 & position @2 .~ pure 25
 -- User
 --   { name      = Last {getLast = Just "Evil Tom"}
 --   , age       = Last {getLast = Just 25}
@@ -240,8 +255,8 @@
 type errors are a delight:
 
 ```haskell
-eg9 :: Identity ()
-eg9 = deconstruct @Identity triple ^. position @4
+eg14 :: Identity ()
+eg14 = deconstruct @Identity triple ^. position @4
 -- error:
 -- • The type Triple does not contain a field at position 4
 ```
@@ -253,8 +268,8 @@
 this interface:
 
 ```haskell
-eg10 :: Labels User
-eg10 = label eg11
+eg15 :: Labels User
+eg15 = label eg13
 -- User
 --   { name = Const "name"
 --   , age = Const "age"
@@ -269,7 +284,7 @@
 fields whose values satisfy some predicate:
 
 ```haskell
-eg13 :: [String]
-eg13 = labelsWhere (isNothing . getLast) eg7
+eg16 :: [String]
+eg16 = labelsWhere (isNothing . getLast) eg9
 -- ["age"]
 ```
diff --git a/higgledy.cabal b/higgledy.cabal
--- a/higgledy.cabal
+++ b/higgledy.cabal
@@ -1,7 +1,7 @@
 cabal-version:       2.4
 
 name:                higgledy
-version:             0.1.1.0
+version:             0.1.1.1
 synopsis:            Partial types as a type constructor.
 description:         Use the generic representation of an ADT to get a higher-kinded data-style interface automatically.
 homepage:            https://github.com/i-am-tom/higgledy
@@ -17,6 +17,7 @@
 
 library
   exposed-modules:     Data.Generic.HKD
+                       Data.Generic.HKD.Build
                        Data.Generic.HKD.Construction
                        Data.Generic.HKD.Field
                        Data.Generic.HKD.Labels
@@ -24,20 +25,20 @@
                        Data.Generic.HKD.Types
   -- other-modules:
   -- other-extensions:
-  build-depends:       base ^>=4.12.0.0
-                     , barbies ^>=1.1.0.0
-                     , generic-lens ^>=1.1.0.0
-                     , QuickCheck ^>=2.13.0
+  build-depends:       base ^>=4.12
+                     , barbies ^>=1.1.0
+                     , generic-lens ^>=1.1.0
+                     , QuickCheck ^>=2.12.6
   hs-source-dirs:      src
   default-language:    Haskell2010
 
 test-suite test
-  build-depends:       base
+  build-depends:       base ^>=4.12
                      , doctest ^>=0.16.0
                      , higgledy
-                     , hspec ^>=2.7.0
+                     , hspec ^>=2.6.1
                      , lens ^>=4.17
-                     , QuickCheck
+                     , QuickCheck ^>= 2.12.6
   main-is:             Main.hs
   type:                exitcode-stdio-1.0
   hs-source-dirs:      test
diff --git a/src/Data/Generic/HKD.hs b/src/Data/Generic/HKD.hs
--- a/src/Data/Generic/HKD.hs
+++ b/src/Data/Generic/HKD.hs
@@ -10,6 +10,7 @@
   ( module Exports
   ) where
 
+import Data.Generic.HKD.Build        as Exports
 import Data.Generic.HKD.Construction as Exports
 import Data.Generic.HKD.Field        as Exports
 import Data.Generic.HKD.Labels       as Exports
diff --git a/src/Data/Generic/HKD/Build.hs b/src/Data/Generic/HKD/Build.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Generic/HKD/Build.hs
@@ -0,0 +1,107 @@
+{-# OPTIONS_HADDOCK not-home #-}
+
+{-# LANGUAGE AllowAmbiguousTypes    #-}
+{-# LANGUAGE BlockArguments         #-}
+{-# LANGUAGE DataKinds              #-}
+{-# LANGUAGE FlexibleInstances      #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE GADTs                  #-}
+{-# LANGUAGE PolyKinds              #-}
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE UndecidableInstances   #-}
+
+{-|
+Module      : Data.Generic.HKD.Build
+Description : Construct an HKD structure with its component parameters.
+Copyright   : (c) Tom Harding, 2019
+License     : MIT
+Maintainer  : tom.harding@habito.com
+Stability   : experimental
+-}
+module Data.Generic.HKD.Build
+  ( Build (..)
+  ) where
+
+import Data.Kind (Type)
+import Data.GenericLens.Internal (HList (..))
+import Data.Generic.HKD.Types (HKD (..), GHKD_)
+import GHC.Generics
+import Prelude hiding (uncurry)
+
+class Fill (f :: Type -> Type) (structure :: Type) (types :: [Type])
+    | structure f -> types, types -> f where
+  fill :: HList types -> HKD structure f
+
+class GFill (f :: Type -> Type) (xs :: [Type]) (ys :: [Type]) (rep :: Type -> Type)
+    | xs rep -> ys, ys f rep -> xs, xs -> f where
+  gfill :: HList xs -> (HList ys, GHKD_ f rep p)
+
+instance GFill f xs ys inner
+    => GFill f xs ys (M1 index meta inner) where
+  gfill = fmap M1 . gfill @f
+
+instance (GFill f xs ys left, GFill f ys zs right)
+    => GFill f xs zs (left :*: right) where
+  gfill xs = do
+    let (ys,  left) = gfill @f xs
+        (zs, right) = gfill @f ys
+
+    (zs, left :*: right)
+
+instance GFill f (f x ': xs) xs (Rec0 x) where
+  gfill (x :> xs) = (xs, K1 x)
+
+instance (Generic shape, GFill f with '[] (Rep shape))
+    => Fill f shape with where
+  fill = HKD . snd . gfill @f @_ @'[]
+
+-- | With many HKD applications, we're working with types like 'Maybe' where it
+-- makes sense for us to start with 'mempty' and add values in as we go.
+--
+-- This isn't always the case, however: if all the component parts of our type
+-- are gathered using some 'IO' action, we'd like to construct something like
+-- @HKD MyType IO@, and @IO a@ isn't a 'Monoid' for all types @a@. When this
+-- happens, we need to pass in our parameters /when/ we build our structure.
+--
+-- The 'build' function lets us construct our type by passing explicit values
+-- for each parameter:
+--
+-- >>> :set -XDeriveGeneric -XTypeApplications
+--
+-- >>> :{
+-- data User
+--   = User { name :: String, age :: Int, likesDogs :: Bool }
+--   deriving Generic
+-- :}
+-- 
+-- >>> :{
+-- test :: _
+-- test = build @User
+-- :}
+-- ...
+-- ... • Found type wildcard ‘_’
+-- ...     standing for ‘f [Char] -> f Int -> f Bool -> HKD User f’
+-- ...
+--
+-- Once we call the 'build' function, and indicate the type we want to build,
+-- we are free to pick whichever 'f' we like and get to work!
+class Build (structure :: Type) (f :: Type -> Type) (k :: Type)
+    | f structure -> k where
+  build :: k
+
+class GBuild (f :: Type -> Type) (structure :: Type) (xs :: [Type]) (k :: Type)
+    | f structure xs -> k where
+  gbuild :: (HList xs -> HKD structure f) -> k
+
+instance GBuild f structure xs k
+    => GBuild f structure (x ': xs) (x -> k) where
+  gbuild k x = gbuild @_ @_ @xs \xs -> k (x :> xs)
+
+instance GBuild f structure '[] (HKD structure f) where
+  gbuild k = k Nil
+
+instance (Fill f structure xs, GBuild f structure xs k)
+    => Build structure f k where
+  build = gbuild @f @structure @xs fill
diff --git a/src/Data/Generic/HKD/Position.hs b/src/Data/Generic/HKD/Position.hs
--- a/src/Data/Generic/HKD/Position.hs
+++ b/src/Data/Generic/HKD/Position.hs
@@ -34,7 +34,6 @@
 import qualified Data.GenericLens.Internal as G
 import Data.GenericLens.Internal (type (<?))
 import qualified Data.Generics.Internal.VL.Lens as G
-import Data.Generics.Internal.Profunctor.Lens (ALens)
 
 -- | Product types /without/ named fields can't be addressed by field name (for
 -- very obvious reason), so we instead need to address them with their
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -12,14 +12,12 @@
 
 import Control.Lens (Lens', (.~), (^.))
 import Data.Function ((&), on)
-import Data.Functor.Identity (Identity (..))
 import Data.Generic.HKD
 import Data.Monoid (Last (..))
 import GHC.Generics
 import Test.DocTest
 import Test.Hspec
 import Test.QuickCheck
-import Test.QuickCheck.Arbitrary
 
 type Partial a = HKD a Last
 type WTF     a = HKD a []
@@ -180,16 +178,14 @@
 
 partials = describe "HKD" do
   describe "Eq" do
-    it "is monotonic with respect to ordering (Partial)"
-      $ property \(x :: a) y -> (x <= y) == ((<=) `on` deconstruct @Last) x y
+    it "is monotonic with respect to ordering (Partial)" $ property \(x :: a) y ->
+      (x <= y) == ((<=) `on` deconstruct @Last) x y
 
-    it "is monotonic with respect to ordering (WTF)"
-      $ property \(x :: a) y -> (x <= y) == ((<=) `on` deconstruct @[]) x y
+    it "is monotonic with respect to ordering (WTF)" $ property \(x :: a) y ->
+      (x <= y) == ((<=) `on` deconstruct @[]) x y
 
-    it "round-trips"
-      $ property \(x :: a) ->
-          construct (deconstruct @Last x) == pure x
+    it "round-trips" $ property \(x :: a) ->
+      construct (deconstruct @Last x) == pure x
 
-    it "round-trips"
-      $ property \(x :: a) ->
-          construct (deconstruct @[] x) == pure x
+    it "round-trips" $ property \(x :: a) ->
+      construct (deconstruct @[] x) == pure x
