diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 0.2.3
+
+* Implement 'fromRecord' for converting values from record.
+
 # 0.2.2.0
 
 * Add 'Data.Default' instance
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -39,8 +39,8 @@
 is, in:
 
 ~~~ {.haskell}
--- type A = Book '[ "field1" :=> Int, "field2" :=> Bool]
--- type B = Book '[ "field2" :=> Bool "field1" :=> Int ]
+-- type A = Book '[ "field1" :=> Int,  "field2" :=> Bool]
+-- type B = Book '[ "field2" :=> Bool, "field1" :=> Int ]
 ~~~
 
 Types `A` and `B` are the same.
diff --git a/bookkeeper.cabal b/bookkeeper.cabal
--- a/bookkeeper.cabal
+++ b/bookkeeper.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           bookkeeper
-version:        0.2.2.0
+version:        0.2.3
 synopsis:       Anonymous records and overloaded labels
 description:    Please see README.md
 category:       Data Structures, Records
diff --git a/src/Bookkeeper.hs b/src/Bookkeeper.hs
--- a/src/Bookkeeper.hs
+++ b/src/Bookkeeper.hs
@@ -37,6 +37,10 @@
   , Book
   , (:=>)
   , Key
+
+  -- * From Haskell record
+  , fromRecord
+
   -- * Re-exports
   , (&)
 
diff --git a/src/Bookkeeper/Internal.hs b/src/Bookkeeper/Internal.hs
--- a/src/Bookkeeper/Internal.hs
+++ b/src/Bookkeeper/Internal.hs
@@ -3,9 +3,9 @@
 module Bookkeeper.Internal where
 
 import GHC.OverloadedLabels
-import GHC.Generics (Generic)
+import GHC.Generics
 import qualified Data.Type.Map as Map
-import GHC.TypeLits (Symbol, KnownSymbol)
+import GHC.TypeLits (Symbol, KnownSymbol, TypeError, ErrorMessage(..))
 import Data.Default.Class (Default(..))
 import Data.Kind (Type)
 import Data.Type.Map (Map, Mapping((:->)))
@@ -126,7 +126,7 @@
 -- resulting book will have type 'Book new'.
 type Settable field val old new =
   (
-     Map.Submap (Map.AsMap (old Map.:\ field)) old
+    Map.Submap (Map.AsMap (old Map.:\ field)) old
   , Map.Unionable '[ field :=> val] (Map.AsMap (old Map.:\ field))
   , new ~ Map.AsMap (( field :=> val) ': (Map.AsMap (old Map.:\ field)))
   )
@@ -207,6 +207,64 @@
         ) => Key field -> Book' old -> Book (old Map.:\ field)
 delete _ (Book bk) = Book $ Map.submap bk
 
+
+-- * Generics
+
+class FromGeneric a book | a -> book where
+  fromGeneric :: a x -> Book' book
+
+instance FromGeneric cs book => FromGeneric (D1 m cs) book where
+  fromGeneric (M1 xs) = fromGeneric xs
+
+instance FromGeneric cs book => FromGeneric (C1 m cs) book where
+  fromGeneric (M1 xs) = fromGeneric xs
+
+instance (v ~ Map.AsMap ('[name ':-> t]))
+  => FromGeneric (S1 ('MetaSel ('Just name) p s l) (Rec0 t)) v where
+  fromGeneric (M1 (K1 t)) = (Key =: t) emptyBook
+
+instance
+  ( FromGeneric l lbook
+  , FromGeneric r rbook
+  , Map.Unionable lbook rbook
+  , book ~ Map.Union lbook rbook
+  ) => FromGeneric (l :*: r) book where
+  fromGeneric (l :*: r)
+    = Book $ Map.union (getBook (fromGeneric l)) (getBook (fromGeneric r))
+
+type family Expected a where
+  Expected (l :+: r) = TypeError ('Text "Cannot convert sum types into Books")
+  Expected U1        = TypeError ('Text "Cannot convert non-record types into Books")
+
+instance (book ~ Expected (l :+: r)) => FromGeneric (l :+: r) book where
+  fromGeneric = error "impossible"
+
+instance (book ~ Expected U1) => FromGeneric U1 book where
+  fromGeneric = error "impossible"
+
+
+-- | Generate a @Book@ from an ordinary Haskell record via GHC Generics.
+--
+-- >>> data Test = Test {  field1 :: String, field2 :: Int, field3 :: Char } deriving Generic
+-- >>> fromRecord (Test "hello" 0 'c')
+-- Book {field1 = "hello", field2 = 0, field3 = 'c'}
+--
+-- Trying to convert a datatype which is not a record will result in a type
+-- error:
+--
+-- >>> data SomeSumType = LeftSide | RightSide deriving Generic
+-- >>> fromRecord LeftSide
+-- ...
+-- ... • Cannot convert sum types into Books
+-- ...
+--
+-- >>> data Unit = Unit deriving Generic
+-- >>> fromRecord Unit
+-- ...
+-- ... • Cannot convert non-record types into Books
+-- ...
+fromRecord :: (Generic a, FromGeneric (Rep a) bookRep) => a -> Book' bookRep
+fromRecord = fromGeneric . from
 
 -- $setup
 -- >>> import Data.Function ((&))
