diff --git a/quantification.cabal b/quantification.cabal
--- a/quantification.cabal
+++ b/quantification.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.0
 name: quantification
-version: 0.5.0
+version: 0.5.1
 synopsis: Rage against the quantification
 description: Data types and typeclasses to deal with universally and existentially quantified types
 homepage: https://github.com/andrewthad/quantification#readme
@@ -20,16 +20,16 @@
     Data.Monoid.Lifted
     Topaz.Rec
     Topaz.Types
-  build-depends: 
-      base >= 4.9 && < 5
+  build-depends:
+      base >= 4.11.1 && < 5
     , binary >= 0.8 && < 0.10
     , ghc-prim >= 0.5 && < 0.6
-    , hashable >= 1.2 && < 1.3
+    , hashable >= 1.2 && < 1.4
     , aeson >= 1.0 && < 1.5
     , text >= 1.0 && < 2.0
     , path-pieces >= 0.2 && < 0.3
     , vector >= 0.11 && < 0.13
-    , containers >= 0.5 && < 0.6
+    , containers >= 0.5 && < 0.7
     , unordered-containers >= 0.2 && < 0.3
   default-language: Haskell2010
   ghc-options: -O2 -Wall
diff --git a/src/Data/Exists.hs b/src/Data/Exists.hs
--- a/src/Data/Exists.hs
+++ b/src/Data/Exists.hs
@@ -13,6 +13,7 @@
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE TypeFamilyDependencies #-}
 {-# LANGUAGE TypeInType #-}
+{-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE UnboxedTuples #-}
 
@@ -58,6 +59,7 @@
   , HashableForall(..)
   , HashableForeach(..)
   , PathPieceExists(..)
+  , FromJSONForall(..) 
   , FromJSONForeach(..)
   , FromJSONExists(..)
   , ToJSONForall(..)
@@ -409,6 +411,9 @@
 class ToJSONForeach f where
   toJSONForeach :: Sing a -> f a -> Aeson.Value
 
+class FromJSONForall f where
+  parseJSONForall :: Sing a -> Aeson.Value -> Aeson.Parser (f a)
+
 class FromJSONForeach f where
   parseJSONForeach :: Sing a -> Aeson.Value -> Aeson.Parser (f a)
 
@@ -518,6 +523,8 @@
 instance FromJSON a => FromJSONForeach (Const a) where
   parseJSONForeach _ = fmap Const . parseJSON
 
+instance ToJSON a => ToJSONForeach (Const a) where
+  toJSONForeach _ = coerce (toJSON @a)
 
 -- I need to get rid of the ToJSONForall and FromJSONForeach constraints
 -- on these two instances.
@@ -604,6 +611,9 @@
     (p >= 11) 
     (showString "Pair " . showsPrecForall 11 f . showChar ' ' . showsPrecForall 11 g)
 
+instance (Ord1 f, OrdForeach g) => OrdForeach (Compose f g) where
+  compareForeach s (Compose x) (Compose y) = liftCompare (compareForeach s) x y
+
 instance (Semigroup1 f, SemigroupForall g) => SemigroupForall (Compose f g) where
   appendForall (Compose x) (Compose y) = Compose (liftAppend appendForall x y)
 
@@ -819,6 +829,11 @@
 
 class FromJSONSing k where
   parseJSONSing :: Aeson.Value -> Aeson.Parser (Exists (Sing :: k -> Type))
+
+instance (Aeson.FromJSON1 f, FromJSONForall g) => FromJSONForall (Compose f g) where
+  parseJSONForall s = fmap Compose . Aeson.liftParseJSON
+      (parseJSONForall s)
+          (Aeson.withArray "Compose" (fmap V.toList . V.mapM (parseJSONForall s)))
 
 instance (FromJSONForeach f, FromJSONSing k) => FromJSON (Some (f :: k -> Type)) where
   parseJSON = Aeson.withArray "Some" $ \v -> if V.length v == 2
diff --git a/src/Topaz/Rec.hs b/src/Topaz/Rec.hs
--- a/src/Topaz/Rec.hs
+++ b/src/Topaz/Rec.hs
@@ -16,6 +16,7 @@
 
 module Topaz.Rec
   ( Rec(..)
+  , (<:)
   , map
   , append
   , traverse
@@ -23,6 +24,7 @@
   , zipWith
   , foldMap
   , foldMap1
+  , foldl'
     -- * Access
   , get
   , put
@@ -31,14 +33,19 @@
     -- * Conversion
   , fromSingList
   , toSingList
+  , fromList
   ) where
 
 import Prelude hiding (map,zipWith,foldMap,traverse)
 import Topaz.Types (Elem(..),type (++),Rec(..))
 import Data.Exists
-import Data.Semigroup (Semigroup)
 import qualified Data.Semigroup as SG
 
+-- | infix RecCons with proper fixity
+infixr 7 <:
+(<:) :: forall a (f :: a -> *) (r :: a) (rs :: [a]).  f r -> Rec f rs -> Rec f (r : rs)
+(<:) = RecCons
+
 map :: (forall x. f x -> g x) -> Rec f as -> Rec g as
 map _ RecNil = RecNil
 map f (RecCons x xs) = RecCons (f x) (map f xs)
@@ -48,6 +55,17 @@
 zipWith f (RecCons a as) (RecCons b bs) =
   RecCons (f a b) (zipWith f as bs)
 
+-- | Strict left fold over the elements of a record.
+foldl' :: forall f a rs.
+     (forall x. a -> f x -> a) -- ^ Reduction
+  -> a -- ^ Initial accumulator
+  -> Rec f rs -- ^ Record
+  -> a
+foldl' g !a0 = go a0 where
+  go :: forall ss. a -> Rec f ss -> a
+  go !a RecNil = a
+  go !a (RecCons r rs) = go (g a r) rs
+
 -- | Map each element of a record to a monoid and combine the results.
 foldMap :: forall f m rs. Monoid m
   => (forall x. f x -> m)
@@ -120,3 +138,7 @@
 toSingList RecNil = SingListNil
 toSingList (RecCons r rs) = SingListCons r (toSingList rs)
 
+fromList :: [Exists f] -> Exists (Rec f)
+fromList [] = Exists RecNil
+fromList (Exists x : xs) = case fromList xs of
+  Exists ys -> Exists (RecCons x ys)
diff --git a/src/Topaz/Types.hs b/src/Topaz/Types.hs
--- a/src/Topaz/Types.hs
+++ b/src/Topaz/Types.hs
@@ -34,7 +34,6 @@
 import Data.Kind (Type)
 import Data.Monoid.Lifted (Semigroup1(..), Monoid1(..), append1)
 import Data.Proxy (Proxy(..))
-import Data.Semigroup (Semigroup)
 import Data.Type.Coercion
 import Data.Type.Equality
 import Foreign.Ptr (castPtr,plusPtr)
