diff --git a/src/Foreign/Storable/Newtype.hs b/src/Foreign/Storable/Newtype.hs
--- a/src/Foreign/Storable/Newtype.hs
+++ b/src/Foreign/Storable/Newtype.hs
@@ -1,5 +1,17 @@
 {- |
 Storable instances for simple wrapped types.
+
+Example:
+
+> import Foreign.Storable.Newtype as Store
+>
+> newtype MuLaw = MuLaw {deMuLaw :: Word8}
+>
+> instance Storable MuLaw where
+>    sizeOf = Store.sizeOf deMuLaw
+>    alignment = Store.alignment deMuLaw
+>    peek = Store.peek MuLaw
+>    poke = Store.poke deMuLaw
 -}
 module Foreign.Storable.Newtype where
 
diff --git a/src/Foreign/Storable/Record.hs b/src/Foreign/Storable/Record.hs
--- a/src/Foreign/Storable/Record.hs
+++ b/src/Foreign/Storable/Record.hs
@@ -1,3 +1,56 @@
+{- |
+Here we show an example of how to
+define a Storable instance with this module.
+
+> import Foreign.Storable.Record as Store
+> import Foreign.Storable (Storable (..), )
+>
+> import Control.Applicative (liftA2, )
+>
+> data Stereo a = Stereo {left, right :: a}
+>
+> store :: Storable a => Store.Dictionary (Stereo a)
+> store =
+>    Store.run $
+>    liftA2 Stereo
+>       (Store.element left)
+>       (Store.element right)
+>
+> instance (Storable a) => Storable (Stereo a) where
+>    sizeOf = Store.sizeOf store
+>    alignment = Store.alignment store
+>    peek = Store.peek store
+>    poke = Store.poke store
+
+
+The @Stereo@ constructor is exclusively used
+for constructing the @peek@ function,
+whereas the accessors in the @element@ calls
+are used for assembling the @poke@ function.
+It is required that the order of arguments of @Stereo@
+matches the record accessors in the @element@ calls.
+If you want that the stored data correctly and fully represents
+your Haskell data, it must hold:
+
+>   Stereo (left x) (right x) = x   .
+
+Unfortunately this cannot be checked automatically.
+However, mismatching types that are caused by swapped arguments
+are detected by the type system.
+Our system performs for you:
+Size and alignment computation, poking and peeking.
+Thus several inconsistency bugs can be prevented using this package,
+like size mismatching the space required by @poke@ actions.
+There is no more restriction,
+thus smart constructors and accessors
+and nested records work, too.
+For nested records however,
+I recommend individual Storable instances for the sub-records.
+
+You see it would simplify class instantiation
+if we could tell the class dictionary at once
+instead of defining each method separately.
+-}
 module Foreign.Storable.Record (
    Dictionary, Access,
    element, run,
@@ -99,8 +152,8 @@
 {-# INLINE element #-}
 element :: Storable a => (r -> a) -> Access r a
 element f =
-   let align = St.alignment (f undefined)
-       size  = St.sizeOf (f undefined)
+   let align = St.alignment (f (error "Storable.Record.element.alignment: content touched"))
+       size  = St.sizeOf (f (error "Storable.Record.element.size: content touched"))
    in  Access $
        Compose $ writer $ flip (,) (Alignment align) $
        Compose $
diff --git a/src/Foreign/Storable/Traversable.hs b/src/Foreign/Storable/Traversable.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Storable/Traversable.hs
@@ -0,0 +1,130 @@
+{- |
+If you have a 'Trav.Traversable' instance of a record,
+you can load and store all elements,
+that are accessible by @Traversable@ methods.
+We treat the record like an array,
+that is we assume, that all elements have the same size and alignment.
+
+Example:
+
+> import Foreign.Storable.Traversable as Store
+>
+> data Stereo a = Stereo {left, right :: a}
+>
+> instance Functor Stereo where
+>    fmap = Trav.fmapDefault
+>
+> instance Foldable Stereo where
+>    foldMap = Trav.foldMapDefault
+>
+> instance Traversable Stereo where
+>    sequenceA ~(Stereo l r) = liftA2 Stereo l r
+>
+> instance (Storable a) => Storable (Stereo a) where
+>    sizeOf = Store.sizeOf
+>    alignment = Store.alignment
+>    peek = Store.peek (error "instance Traversable Stereo is lazy, so we do not provide a real value here")
+>    poke = Store.poke
+
+You would certainly not define the 'Trav.Traversable' and according instances
+just for the implementation of the 'Storable' instance,
+but there are usually similar applications
+where the @Traversable@ instance is useful.
+-}
+module Foreign.Storable.Traversable (
+   alignment, sizeOf,
+   peek, poke,
+   peekApplicative,
+   ) where
+
+import qualified Data.Traversable as Trav
+import qualified Data.Foldable as Fold
+import qualified Control.Applicative as App
+
+import Control.Monad.Trans.State
+          (StateT, evalStateT, get, put, modify, )
+import Control.Monad.Trans (liftIO, )
+
+import Foreign.Storable.FixedArray (roundUp, )
+import qualified Foreign.Storable as St
+
+import Foreign.Ptr (Ptr, castPtr, )
+import Foreign.Storable (Storable, )
+import Foreign.Marshal.Array (advancePtr, )
+
+
+{-# INLINE elementType #-}
+elementType :: f a -> a
+elementType _ =
+   error "Storable.Traversable.alignment and sizeOf may not depend on element values"
+
+{-# INLINE alignment #-}
+alignment ::
+   (Fold.Foldable f, Storable a) =>
+   f a -> Int
+alignment = St.alignment . elementType
+
+{-# INLINE sizeOf #-}
+sizeOf ::
+   (Fold.Foldable f, Storable a) =>
+   f a -> Int
+sizeOf f =
+   Fold.foldl' (\s _ -> s + 1) 0 f *
+   roundUp (alignment f) (St.sizeOf (elementType f))
+
+
+{- |
+@peek skeleton ptr@ fills the @skeleton@ with data read from memory beginning at @ptr@.
+The skeleton is needed formally for using 'Trav.Traversable'.
+For instance when reading a list, it is not clear,
+how many elements shall be read.
+Using the skeleton you can give this information
+and you also provide information that is not contained in the element type @a@.
+For example you can call
+
+> peek (replicate 10 ()) ptr
+
+for reading 10 elements from memory starting at @ptr@.
+-}
+{-# INLINE peek #-}
+peek ::
+   (Trav.Traversable f, Storable a) =>
+   f () -> Ptr (f a) -> IO (f a)
+peek skeleton =
+   evalStateT (Trav.mapM (const peekState) skeleton) .
+   castPtr
+
+{- |
+Like 'peek' but uses 'pure' for construction of the result.
+'pure' would be in class @Pointed@ if that would exist.
+Thus we use the closest approximate 'Applicative'.
+-}
+{-# INLINE peekApplicative #-}
+peekApplicative ::
+   (App.Applicative f, Trav.Traversable f, Storable a) =>
+   Ptr (f a) -> IO (f a)
+peekApplicative =
+   evalStateT (Trav.sequence (App.pure peekState)) . castPtr
+
+{-# INLINE peekState #-}
+peekState ::
+   (Storable a) =>
+   StateT (Ptr a) IO a
+peekState =
+   get >>= \p -> put (advancePtr p 1) >> liftIO (St.peek p)
+
+{-# INLINE poke #-}
+poke ::
+   (Fold.Foldable f, Storable a) =>
+   Ptr (f a) -> f a -> IO ()
+poke ptr x =
+   evalStateT (Fold.traverse_ pokeState x) $
+   castPtr ptr
+
+{-# INLINE pokeState #-}
+pokeState ::
+   (Storable a) =>
+   a -> StateT (Ptr a) IO ()
+pokeState x = do
+   liftIO . flip St.poke x =<< get
+   modify (flip advancePtr 1)
diff --git a/src/Foreign/Storable/TraversableUnequalSizes.hs b/src/Foreign/Storable/TraversableUnequalSizes.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Storable/TraversableUnequalSizes.hs
@@ -0,0 +1,94 @@
+{- |
+If you have a Traversable instance of a record,
+you can load and store all elements,
+that are accessible by Traversable methods.
+In this attempt we support elements of unequal size.
+However this can be awfully slow,
+since the program might perform size computations at run-time.
+-}
+module Foreign.Storable.TraversableUnequalSizes (
+   alignment, sizeOf,
+   peek, poke,
+   ) where
+
+import qualified Data.Traversable as Trav
+import qualified Data.Foldable as Fold
+
+import Control.Monad.Trans.State
+          (StateT, evalStateT, gets, modify, )
+import Control.Monad.Trans (liftIO, )
+
+import Foreign.Storable.FixedArray (roundUp, )
+import qualified Foreign.Storable as St
+
+import Foreign.Ptr (Ptr, )
+import Foreign.Storable (Storable, )
+
+
+{-# INLINE alignment #-}
+alignment ::
+   (Fold.Foldable f, Storable a) =>
+   f a -> Int
+alignment =
+   Fold.foldl' (\n x -> lcm n (St.alignment x)) 1
+
+{-# INLINE sizeOf #-}
+sizeOf ::
+   (Fold.Foldable f, Storable a) =>
+   f a -> Int
+sizeOf =
+   Fold.foldl' (\s x -> roundUp (St.alignment x) s + St.sizeOf x) 0
+
+{-
+This function requires that alignment does not depend on an element value,
+because we cannot not know the value before loading it.
+Thus @alignment (undefined::a)@ must be defined.
+-}
+{-# INLINE peek #-}
+peek ::
+   (Trav.Traversable f, Storable a) =>
+   f () -> Ptr (f a) -> IO (f a)
+peek skeleton ptr =
+   evalStateT (Trav.mapM (const (peekState ptr)) skeleton) 0
+
+{-# INLINE peekState #-}
+peekState ::
+   (Storable a) =>
+   Ptr (f a) -> StateT Int IO a
+peekState p = do
+   let pseudoPeek :: Ptr (f a) -> a
+       pseudoPeek _ = error "Traversable.peek: alignment must not depend on the element value"
+   k <- getOffset (pseudoPeek p)
+   a <- liftIO (St.peekByteOff p k)
+   advanceOffset a
+   return a
+
+{-# INLINE poke #-}
+poke ::
+   (Fold.Foldable f, Storable a) =>
+   Ptr (f a) -> f a -> IO ()
+poke ptr x =
+   evalStateT (Fold.traverse_ (pokeState ptr) x) 0
+
+{-# INLINE pokeState #-}
+pokeState ::
+   (Storable a) =>
+   Ptr (f a) -> a -> StateT Int IO ()
+pokeState p a = do
+   k <- getOffset a
+   liftIO (St.pokeByteOff p k a)
+   advanceOffset a
+
+{-# INLINE getOffset #-}
+getOffset ::
+   (Storable a) =>
+   a -> StateT Int IO Int
+getOffset a =
+   gets (roundUp (St.alignment a))
+
+{-# INLINE advanceOffset #-}
+advanceOffset ::
+   (Storable a) =>
+   a -> StateT Int IO ()
+advanceOffset a =
+   modify ( + St.sizeOf a)
diff --git a/storable-record.cabal b/storable-record.cabal
--- a/storable-record.cabal
+++ b/storable-record.cabal
@@ -1,74 +1,51 @@
 Name:         storable-record
-Version:      0.0.1
+Version:      0.0.2
 Category:     Data, Foreign
 Synopsis:     Elegant definition of Storable instances for records
 Description:
-  With this package definition
+  With this package
   you can build a Storable instance of a record type
-  from Storable instances of its elements.
-  This is as simple as:
-  .
-  > import Foreign.Storable.Record as Store
-  > import Foreign.Storable (Storable (..), )
-  >
-  > import Control.Applicative (liftA2, )
-  >
-  > data Stereo a = Stereo (left, right :: a)
-  > -- parentheses must be curly braces, but Haddock does not like them
-  >
-  > store :: Storable a => Store.Dictionary (Stereo a)
-  > store =
-  >    Store.run $
-  >    liftA2 Stereo
-  >       (Store.element left)
-  >       (Store.element right)
-  >
-  > instance (Storable a) => Storable (Stereo a) where
-  >    sizeOf = Store.sizeOf store
-  >    alignment = Store.alignment store
-  >    peek = Store.peek store
-  >    poke = Store.poke store
-  .
+  from Storable instances of its elements in an elegant way.
+  It does not do any magic,
+  just a bit arithmetic to compute the right offsets,
+  that would be otherwise done manually
+  or by a preprocessor like C2HS.
   I cannot promise that the generated memory layout
   is compatible with that of a corresponding C struct.
   However, the module generates the smallest layout
   that is possible with respect to the alignment of the record elements.
-  Thus this package might provide a Haskell98 alternative to HSC
-  without a preprocessor.
   If you encounter, that a record does not have a compatible layout,
   we should fix that.
   But also without C compatibility this package is useful
   e.g. in connection with StorableVector.
   .
-  The @Stereo@ constructor is exclusively used
-  for constructing the @peek@ function,
-  where as the accessors in the @element@ calls
-  are used for assembling the @poke@ function.
-  It is required that the order of arguments of @Stereo@
-  matches the record accessors in the @element@ calls.
-  If you want that the stored data correctly and fully represents
-  your Haskell data, it must hold:
+  We provide Storable instance support for several cases:
   .
-  >   Stereo (left x) (right x) = x   .
+  * If you wrap a type in a @newtype@,
+    then you can lift its 'Storable' instance to that @newtype@
+    with the module "Foreign.Storable.Newtype".
+    This way you do not need the @GeneralizedNewtypeDeriving@ feature of GHC.
   .
-  Unfortunately this cannot be checked automatically.
-  However, mismatching types that are caused by swapped arguments
-  are detected by the type system.
-  Our system performs for you:
-  Size and alignment computation, poking and peeking.
-  Thus several inconsistency bugs can be prevented using this package,
-  like size mismatches space required by @poke@ actions.
-  There is no more restriction,
-  thus smart constructors and accessors
-  and nested records work, too.
-  For nested records however,
-  I recommend individual Storable instances for the sub-records.
+  * If you have a type that is an instance of 'Traversable',
+    you can use that feature for implementation of 'Storable' methods.
+    The module "Foreign.Storable.Traversable"
+    allows manipulation of the portion of your type,
+    that is accessible by 'Traversable' methods.
+    For instance with the type
+    @data T a = Cons Int [a]@
+    and an according 'Traversable' implementation,
+    you can load and store the elements of the contained list.
+    This may be part of a 'Storable' implementation of the whole type.
   .
-  You see it would simplify class instantiation
-  if we could tell the class dictionary at once
-  instead of defining each method separately.
+  * If you have a record containing elements of various types,
+    then you need module "Foreign.Storable.Record".
   .
-  For examples see packages sox and synthesizer.
+  Note however that the Storable instances
+  defined with this package are quite slow in (up to) GHC-6.12.1.
+  I'm afraid this is due to incomplete inlining,
+  but we have still to investigate the problem.
+  .
+  For examples see packages @storable-tuple@ and @sample-frame@.
 License:             BSD3
 License-file:        LICENSE
 Author:              Henning Thielemann <storable@henning-thielemann.de>
@@ -76,7 +53,7 @@
 Homepage:            http://code.haskell.org/~thielema/storable-record/
 Stability:           Experimental
 Build-Type:          Simple
-Tested-With:         GHC==6.8.2
+Tested-With:         GHC==6.8.2 && ==6.10.4 && ==6.12.1
 Cabal-Version:       >=1.6
 
 Source-Repository head
@@ -86,7 +63,7 @@
 Source-Repository this
   Type:     darcs
   Location: http://code.haskell.org/~thielema/storable-record/
-  Tag:      0.0.1
+  Tag:      0.0.2
 
 Flag splitBase
   description: Choose the new smaller, split-up base package.
@@ -96,7 +73,8 @@
     transformers >=0.0.1 && <0.2,
     utility-ht >=0.0.1 && <0.1
   If flag(splitBase)
-    Build-Depends: base >= 3
+    Build-Depends:
+      base >= 3 && < 6
   Else
     Build-Depends:
       special-functors >= 1.0 && <1.1,
@@ -108,5 +86,7 @@
   Exposed-Modules:
     Foreign.Storable.Record
     Foreign.Storable.Newtype
+    Foreign.Storable.Traversable
   Other-Modules:
     Foreign.Storable.FixedArray
+    Foreign.Storable.TraversableUnequalSizes
