diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.1.1 (2023-07-20)
+  * add work-in-progress store-style generic `foldMap`, encoding constructors by
+    their index, at `Generic.Data.Function.FoldMap.SumConsByte`
+
 ## 0.1.0 (2023-06-23)
 Initial release.
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -7,6 +7,36 @@
 to pass a handful of definitions. Obtain simple, type-safe generic
 serializers/reducers and parsers for almost zero effort.
 
+Well, OK, so really this is a generic binary serialization library. It just so
+happens that the generics look like `foldMap` and `traverse`.
+
+## Really?
+Kind of. We only handle *sequential concatenation*, being cleanly represented by
+builtin type classes. Weirder cases like JSON parsing/serialization have more
+going on, and aren't sensibly discussed generically. So you are probably only
+going to use this with bytestrings and simple binary formats.
+
+## Why?
+It is 2023. There are a number of competing parsing and serialization Haskell
+libraries, recently some notable high-performance ones. These are often fairly
+experimental. Maybe you want some generics to benchmark some real-world use case
+against popular libraries like binary and cereal. But maybe generics aren't
+provided. Shucks.
+
+That's a shame, because a binary/cereal-esque generic binary parser or
+serializer doesn't have much work to do:
+
+  * traverse the generic sum-of-products tree of the given type left to right
+  * defer to the appropriate type class for base cases
+
+Sum types necessitate a little more work. Otherwise, most such parsers and
+serializers look fairly comparable to each other. Why are we rewriting this
+stuff over and over again?
+
+generic-data-functions provides *reusable generics* which have holes in for your
+favorite parsers and serializers. Fill out a few definitions to receive a fresh
+new generic instance for your own library, without all the boilerplate.
+
 ## Functions
 ### `foldMap` (L->R)
 ```haskell
@@ -45,47 +75,3 @@
 
 ## License
 Provided under the MIT license. See `LICENSE` for license text.
-
----
-
-senserial is a small library providing reusable generics for (binary) parsers
-and serializers. No need to muddle through boilerplate generics that look the
-same as everyone else's; just provide a few definitions and senserial can give
-you powerful generic instances.
-
-Currently an unofficial library, distributed as part of binrep. Reader, please
-let the author know if you'd like it released separately.
-
-## Why?
-It is 2023. There are a number of competing parsing and serialization Haskell
-libraries, and some notable high-performance binary serialization libraries.
-These are often fairly experimental. Maybe you want some generics to benchmark
-some real-world use case against popular libraries like binary and cereal. But
-maybe generics aren't provided. Shucks.
-
-That's a shame, because a pure generic binary parser or serializer doesn't have
-much work to do:
-
-  * traverse the generic sum-of-products tree of the given type left to right
-  * defer to the appropriate type class for base cases
-
-Sum types necessitate a little more work. Otherwise, most generic binary parsers
-and serializers look fairly comparable to each other. Why are we rewriting this
-stuff over and over again?
-
-senserial provides *reusable generics* which have holes in for your favourite
-parsers and serializers. Fill out a few definitions to receive a fresh new
-generic instance for your own library, without all the boilerplate.
-
-## Really?
-Kind of. In reality, this library can only handle cases where no configuration
-is needed other than what is provided in the data type itself. senserial
-provides the generic traversal, and you can't alter that. Plus, the only
-often rewritten and straightforward traversal I can think of is sequential field
-concatenation. So though the code isn't limited to bytestrings and binary
-serialization formats, you will have trouble using it for anything else, because
-anything else will probably require a very different traversal (e.g. JSON
-serialization).
-
-In short, the primary use of this library is to pull out the common generics
-patterns from binary serialization libraries for easy reuse.
diff --git a/generic-data-functions.cabal b/generic-data-functions.cabal
--- a/generic-data-functions.cabal
+++ b/generic-data-functions.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           generic-data-functions
-version:        0.1.0
+version:        0.1.1
 synopsis:       Familiar functions lifted to generic data types
 description:    Please see README.md.
 category:       Data, Serialization
@@ -28,10 +28,12 @@
   exposed-modules:
       Generic.Data.Function
       Generic.Data.Function.Error
+      Generic.Data.Function.Example
       Generic.Data.Function.FoldMap
       Generic.Data.Function.FoldMap.Constructor
       Generic.Data.Function.FoldMap.NonSum
       Generic.Data.Function.FoldMap.Sum
+      Generic.Data.Function.FoldMap.SumConsByte
       Generic.Data.Function.Traverse
       Generic.Data.Function.Traverse.Constructor
       Generic.Data.Function.Traverse.NonSum
diff --git a/src/Generic/Data/Function/Example.hs b/src/Generic/Data/Function/Example.hs
new file mode 100644
--- /dev/null
+++ b/src/Generic/Data/Function/Example.hs
@@ -0,0 +1,14 @@
+module Generic.Data.Function.Example where
+
+import GHC.Generics ( Generic )
+import Generic.Data.Function.FoldMap.Constructor ( GenericFoldMap(..) )
+
+data D a = D1 a | D2 a a deriving stock (Generic, Show)
+
+newtype Showly a = Showly { unShowly :: a }
+    deriving Show via a
+    deriving (Semigroup, Monoid) via a
+
+instance GenericFoldMap (Showly String) where
+    type GenericFoldMapC (Showly String) a = Show a
+    genericFoldMapF = Showly . show
diff --git a/src/Generic/Data/Function/FoldMap.hs b/src/Generic/Data/Function/FoldMap.hs
--- a/src/Generic/Data/Function/FoldMap.hs
+++ b/src/Generic/Data/Function/FoldMap.hs
@@ -29,6 +29,7 @@
   ( GenericFoldMap(..)
   , genericFoldMapNonSum, GFoldMapNonSum
   , genericFoldMapSum,    GFoldMapSum
+  , genericFoldMapSumConsByte,    GFoldMapSumConsByte
   ) where
 
 import GHC.Generics
@@ -36,6 +37,8 @@
 import Generic.Data.Function.FoldMap.NonSum
 import Generic.Data.Function.FoldMap.Sum
 import Generic.Data.Function.FoldMap.Constructor
+import Generic.Data.Function.FoldMap.SumConsByte
+import Data.Word ( Word8 )
 
 -- | Generic 'foldMap' over a term of non-sum data type @a@.
 --
@@ -51,9 +54,28 @@
 -- @a@ must have at least two constructors.
 --
 -- You must provide a function for mapping constructor names to monoidal values.
+--
+-- This is the most generic option, but depending on your string manipulation
+-- may be slower.
 genericFoldMapSum
     :: forall m a
     .  (Generic a, GFoldMapSum m (Rep a))
     => (String -> m)
     -> a -> m
 genericFoldMapSum f = gFoldMapSum f . from
+
+-- | Generic 'foldMap' over a term of sum data type @a@ where constructors are
+-- mapped to their index (distance from first/leftmost constructor)
+--
+-- @a@ must have at least two constructors.
+--
+-- You must provide a function for mapping bytes to monoidal values.
+--
+-- This should be fairly fast, but sadly I think it's slower than the generics
+-- in store and binary/cereal libraries.
+genericFoldMapSumConsByte
+    :: forall m a
+    .  (Generic a, GFoldMapSumConsByte m (Rep a))
+    => (Word8 -> m)
+    -> a -> m
+genericFoldMapSumConsByte f = gFoldMapSumConsByte f . from
diff --git a/src/Generic/Data/Function/FoldMap/Sum.hs b/src/Generic/Data/Function/FoldMap/Sum.hs
--- a/src/Generic/Data/Function/FoldMap/Sum.hs
+++ b/src/Generic/Data/Function/FoldMap/Sum.hs
@@ -1,5 +1,13 @@
 {-# LANGUAGE UndecidableInstances #-} -- required below GHC 9.6
 
+{- | 'foldMap' for sum types where constructors are encoded by mapping the
+      constructor name.
+
+Note that constructor names are unique per type. So as long as your mapping
+function similarly outputs unique values of your monoid for each constructor,
+you should be able to "reverse" the process (e.g. for generic 'traverse').
+-}
+
 module Generic.Data.Function.FoldMap.Sum where
 
 import GHC.Generics
@@ -23,6 +31,10 @@
 instance TypeError ENoEmpty => GFoldMapSum m V1 where
     gFoldMapSum = undefined
 
+-- | Sum type handler prefixing constructor contents with their mapped
+--   constructor name via a provided @String -> m@.
+--
+-- TODO rename
 class GFoldMapCSum m f where gFoldMapCSum :: (String -> m) -> f p -> m
 
 instance (GFoldMapCSum m l, GFoldMapCSum m r) => GFoldMapCSum m (l :+: r) where
diff --git a/src/Generic/Data/Function/FoldMap/SumConsByte.hs b/src/Generic/Data/Function/FoldMap/SumConsByte.hs
new file mode 100644
--- /dev/null
+++ b/src/Generic/Data/Function/FoldMap/SumConsByte.hs
@@ -0,0 +1,93 @@
+{-# LANGUAGE UndecidableInstances #-} -- required below GHC 9.6
+{-# LANGUAGE AllowAmbiguousTypes #-} -- due to type class design
+{-# LANGUAGE CPP #-} -- due to TypeErrorMessage hack
+
+{- | 'foldMap' for sum types, where constructors are encoded by index
+     (distance from first/leftmost constructor) in a single byte, which is
+     prepended to their contents.
+
+TODO. Clumsy and limited. And yet, still handy enough I think.
+-}
+
+module Generic.Data.Function.FoldMap.SumConsByte where
+
+import GHC.Generics
+import GHC.TypeLits
+import Data.Kind ( Type, Constraint )
+import Generic.Data.Function.Util.TypeNats ( natVal'' )
+import Generic.Data.Function.Error ( type ENoEmpty, type EUnexpectedNonSum )
+import Generic.Data.Function.FoldMap.Constructor ( GFoldMapC(gFoldMapC) )
+
+import Data.Word ( Word8 )
+
+class GFoldMapSumConsByte m f where
+    gFoldMapSumConsByte :: (Word8 -> m) -> f p -> m
+
+instance GFoldMapSumConsByte m f => GFoldMapSumConsByte m (D1 c f) where
+    gFoldMapSumConsByte f (M1 a) = gFoldMapSumConsByte f a
+
+instance
+  ( FitsInByte (SumArity (l :+: r))
+  , GFoldMapCSumCtrArityByte m 0 (l :+: r)
+  , GFoldMapCSumCtr m (l :+: r)
+  , Semigroup m
+  ) => GFoldMapSumConsByte m (l :+: r) where
+    gFoldMapSumConsByte f lr =
+        gFoldMapCSumCtrArityByte @m @0 f lr <> gFoldMapCSumCtr lr
+
+instance TypeError EUnexpectedNonSum => GFoldMapSumConsByte m (C1 c f) where
+    gFoldMapSumConsByte _ = undefined
+
+instance TypeError ENoEmpty => GFoldMapSumConsByte m V1 where
+    gFoldMapSumConsByte _ = undefined
+
+---
+
+-- | Sum type handler handling constructors only. Useful if you handle
+--   constructor prefixes elsewhere.
+class GFoldMapCSumCtr m f where gFoldMapCSumCtr :: f p -> m
+
+instance (GFoldMapCSumCtr m l, GFoldMapCSumCtr m r)
+  => GFoldMapCSumCtr m (l :+: r) where
+    gFoldMapCSumCtr = \case L1 l -> gFoldMapCSumCtr l
+                            R1 r -> gFoldMapCSumCtr r
+
+instance GFoldMapC m f => GFoldMapCSumCtr m (C1 c f) where
+    gFoldMapCSumCtr (M1 a) = gFoldMapC a
+
+---
+
+class GFoldMapCSumCtrArityByte m (arity :: Natural) f where
+    gFoldMapCSumCtrArityByte :: (Word8 -> m) -> f p -> m
+
+instance
+  ( GFoldMapCSumCtrArityByte m arity l
+  , GFoldMapCSumCtrArityByte m (arity + SumArity l) r
+  ) => GFoldMapCSumCtrArityByte m arity (l :+: r) where
+    gFoldMapCSumCtrArityByte f = \case
+      L1 l -> gFoldMapCSumCtrArityByte @m @arity                f l
+      R1 r -> gFoldMapCSumCtrArityByte @m @(arity + SumArity l) f r
+
+instance KnownNat arity => GFoldMapCSumCtrArityByte m arity (C1 c f) where
+    gFoldMapCSumCtrArityByte f _ = f (fromIntegral (natVal'' @arity))
+
+---
+
+type family SumArity (a :: Type -> Type) :: Natural where
+    SumArity (C1 c a) = 1
+    SumArity (x :+: y) = SumArity x + SumArity y
+
+type FitsInByte n = FitsInByteResult (n <=? 255)
+
+type family FitsInByteResult (b :: Bool) :: Constraint where
+    FitsInByteResult 'True = ()
+    FitsInByteResult 'False = TypeErrorMessage
+        "TODO ya type had more than 255 constructors"
+
+type family TypeErrorMessage (a :: Symbol) :: Constraint where
+#if MIN_VERSION_base(4,9,0)
+    TypeErrorMessage a = TypeError ('Text a)
+-- GHC < 8.0 does not support empty closed type families
+#elif __GLASGOW_HASKELL__ < 800
+    TypeErrorMessage a = a ~ ""
+#endif
diff --git a/src/Generic/Data/Function/Traverse/Sum.hs b/src/Generic/Data/Function/Traverse/Sum.hs
--- a/src/Generic/Data/Function/Traverse/Sum.hs
+++ b/src/Generic/Data/Function/Traverse/Sum.hs
@@ -13,7 +13,7 @@
 import Control.Applicative qualified as Applicative
 import Control.Applicative ( Alternative((<|>)) )
 
-{- | Sum-type monads that can be generically 'traverse'd.
+{- | Sum type monads that can be generically 'traverse'd.
 
 For sum types, we require a monad with choice to differentiate constructors.
 -}
