diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+## 0.7.1.0
+
+* Added `Opaleye.Experimental.Enum` for an easy way to deal with
+  Postgres `ENUM` types.
+
+* Added `Opaleye.Manipulation.rReturningI` which has better type
+  inference.
+
+* Added `Opaleye.Operators.where_` for easier restriction in monadic
+  style.
+
+* Added `Opaleye.Operators.sqlLength` and
+  `Opaleye.Operators.dateOfTimestamp`.
+
 ## 0.7.0.0
 
 * Many renamings have taken place to help make Opaleye easier to
diff --git a/Test/QuickCheck.hs b/Test/QuickCheck.hs
--- a/Test/QuickCheck.hs
+++ b/Test/QuickCheck.hs
@@ -354,8 +354,6 @@
   compareDenotationMaybe2 (q1 . q2) (denotation_ q1 . denotation_ q2)
   where denotation_ = denotationArrMaybeFields
 
--- Would prefer to write 'compare conn (denotation id) id' but that
--- requires extending compare to compare SelectArrs.
 identity :: ArbitraryArgument
          -> Connection
          -> IO TQ.Property
diff --git a/opaleye.cabal b/opaleye.cabal
--- a/opaleye.cabal
+++ b/opaleye.cabal
@@ -1,6 +1,6 @@
 name:            opaleye
 copyright:       Copyright (c) 2014-2018 Purely Agile Limited; 2019-2020 Tom Ellis
-version:         0.7.0.0
+version:         0.7.1.0
 synopsis:        An SQL-generating DSL targeting PostgreSQL
 description:     An SQL-generating DSL targeting PostgreSQL.  Allows
                  Postgres queries to be written within Haskell in a
@@ -52,6 +52,7 @@
                    Opaleye.Column,
                    Opaleye.Constant,
                    Opaleye.Distinct,
+                   Opaleye.Experimental.Enum,
                    Opaleye.Field,
                    Opaleye.FunctionalJoin,
                    Opaleye.Join,
diff --git a/src/Opaleye/Experimental/Enum.hs b/src/Opaleye/Experimental/Enum.hs
new file mode 100644
--- /dev/null
+++ b/src/Opaleye/Experimental/Enum.hs
@@ -0,0 +1,24 @@
+module Opaleye.Experimental.Enum
+  (
+    fromFieldToFieldsEnum
+  ) where
+
+import           Opaleye.Column (Column)
+import qualified Opaleye as O
+import qualified Opaleye.Internal.RunQuery as RQ
+
+import           Data.ByteString.Char8 (unpack)
+
+fromFieldToFieldsEnum :: String
+                      -> (String -> Maybe haskellSum)
+                      -> (haskellSum -> String)
+                      -> (RQ.FromField sqlEnum haskellSum,
+                          O.ToFields haskellSum (Column sqlEnum))
+fromFieldToFieldsEnum type_ from to_ = (fromFieldEnum, toFieldsEnum)
+   where
+     toFieldsEnum = O.toToFields (O.unsafeCast type_ . O.sqlString . to_)
+     fromFieldEnum = flip fmap RQ.unsafeFromFieldRaw $ \(_, mdata) -> case mdata of
+       Nothing -> error "Unexpected NULL"
+       Just s -> case from (unpack s) of
+         Just r -> r
+         Nothing -> error ("Unexpected: " ++ unpack s)
diff --git a/src/Opaleye/Internal/Helpers.hs b/src/Opaleye/Internal/Helpers.hs
--- a/src/Opaleye/Internal/Helpers.hs
+++ b/src/Opaleye/Internal/Helpers.hs
@@ -19,3 +19,6 @@
 
 (.::.) :: (r -> z) -> (a -> b -> c -> d -> e -> r) -> a -> b -> c -> d -> e -> z
 (.::.) f g a b c d e = f (g a b c d e)
+
+atSameType :: p a a -> p a a
+atSameType = id
diff --git a/src/Opaleye/Internal/PGTypesExternal.hs b/src/Opaleye/Internal/PGTypesExternal.hs
--- a/src/Opaleye/Internal/PGTypesExternal.hs
+++ b/src/Opaleye/Internal/PGTypesExternal.hs
@@ -36,6 +36,9 @@
 instance C.SqlNum SqlInt8 where
   sqlFromInteger = pgInt8 . fromInteger
 
+instance C.SqlNum SqlNumeric where
+  sqlFromInteger = pgNumeric . fromInteger
+
 instance C.SqlFractional SqlFloat8 where
   sqlFromRational = pgDouble . fromRational
 
diff --git a/src/Opaleye/Internal/RunQuery.hs b/src/Opaleye/Internal/RunQuery.hs
--- a/src/Opaleye/Internal/RunQuery.hs
+++ b/src/Opaleye/Internal/RunQuery.hs
@@ -135,6 +135,9 @@
         fromField' _ _ Nothing = pure Nothing
         fromField' fp' f bs = fmap Just (fp' f bs)
 
+unsafeFromFieldRaw :: FromField a (PGS.Field, Maybe SBS.ByteString)
+unsafeFromFieldRaw = fieldParserQueryRunnerColumn (\f mdata -> pure (f, mdata))
+
 -- { Instances for automatic derivation
 
 instance DefaultFromField a b =>
@@ -267,8 +270,7 @@
 
 instance (Typeable b, DefaultFromField a b) =>
          DefaultFromField (T.SqlArray a) [b] where
-  defaultFromField = QueryRunnerColumn (P.lmap arrayColumn c) ((fmap . fmap . fmap) fromPGArray (pgArrayFieldParser f))
-    where QueryRunnerColumn c f = defaultFromField
+  defaultFromField = fromFieldArray defaultFromField
 
 fromFieldArray :: Typeable h => FromField f h -> FromField (T.SqlArray f) [h]
 fromFieldArray q =
@@ -278,9 +280,16 @@
 
 -- }
 
-instance (Typeable b, PGS.FromField b, DefaultFromField a b) =>
+instance (Typeable b, DefaultFromField a b) =>
          DefaultFromField (T.PGRange a) (PGSR.PGRange b) where
-  defaultFromField = fromPGSFromField
+  defaultFromField = fromFieldRange defaultFromField
+
+fromFieldRange :: Typeable b
+               => FromField a b
+               -> FromField (T.PGRange a) (PGSR.PGRange b)
+fromFieldRange off =
+  QueryRunnerColumn (P.lmap C.unsafeCoerceColumn c) (PGSR.fromFieldRange pff)
+  where QueryRunnerColumn c pff = off
 
 -- Boilerplate instances
 
diff --git a/src/Opaleye/Manipulation.hs b/src/Opaleye/Manipulation.hs
--- a/src/Opaleye/Manipulation.hs
+++ b/src/Opaleye/Manipulation.hs
@@ -35,6 +35,7 @@
 import qualified Opaleye.Internal.Table as TI
 import           Opaleye.Internal.Column (Column)
 import           Opaleye.Internal.Helpers ((.:), (.:.))
+import           Opaleye.Internal.Inferrable (Inferrable, runInferrable)
 import           Opaleye.Internal.Manipulation (Updater(Updater))
 import qualified Opaleye.Internal.Manipulation as MI
 import           Opaleye.SqlTypes (SqlBool)
@@ -168,6 +169,15 @@
            -- ^
            -> MI.Returning fieldsR [haskells]
 rReturning = rReturningExplicit D.def
+
+-- | Like 'rReturning' but with better inference properties.  On the
+-- other hand the mapping from SQL fields to Haskell types is less
+-- flexible.
+rReturningI :: D.Default (Inferrable RS.FromFields) fields haskells
+            => (fieldsR -> fields)
+            -- ^
+            -> MI.Returning fieldsR [haskells]
+rReturningI = rReturningExplicit (runInferrable D.def)
 
 -- | Return a function of the inserted or updated rows.  Explicit
 -- version.  You probably just want to use 'rReturning' instead.
diff --git a/src/Opaleye/Operators.hs b/src/Opaleye/Operators.hs
--- a/src/Opaleye/Operators.hs
+++ b/src/Opaleye/Operators.hs
@@ -21,6 +21,7 @@
 import qualified Opaleye.Internal.PrimQuery as PQ
 import qualified Opaleye.Internal.Operators as O
 import           Opaleye.Internal.Helpers   ((.:))
+import qualified Opaleye.Lateral as L
 import qualified Opaleye.Order as Ord
 import qualified Opaleye.Select   as S
 import qualified Opaleye.SqlTypes as T
@@ -38,16 +39,21 @@
 
 -- * Restriction operators
 
-{-| Keep only the rows of a query satisfying a given condition, using
-an SQL @WHERE@ clause.
+{-| Keep only the rows of a query satisfying a given condition, using an
+SQL @WHERE@ clause.  It is equivalent to the Haskell function
 
-You would typically use 'restrict' if you want to write your query
-using 'A.Arrow' notation.  If you want to use a "point free" style
-then 'keepWhen' will suit you better.
+@
+where_ :: Bool -> [()]
+where_ True  = [()]
+where_ False = []
+@
+-}
+where_ :: F.Field T.SqlBool -> S.Select ()
+where_ = L.viaLateral restrict
 
-(If you are familiar with 'Control.Monad.MonadPlus' or
-'Control.Applicative.Alternative' it may help you to know that
-'restrict' corresponds to the 'Control.Monad.guard' function.) -}
+{-| You would typically use 'restrict' if you want to write your query
+using 'A.Arrow' notation.  If you want to use monadic style
+then 'where_' will suit you better. -}
 restrict :: S.SelectArr (F.Field T.SqlBool) ()
 restrict = O.restrict
 
@@ -63,21 +69,6 @@
   f (a, primQ, t0) = ((), PQ.notExists primQ existsQ, t1) where
     (_, existsQ, t1) = runSimpleQueryArr criteria (a, t0)
 
-{-| Keep only the rows of a query satisfying a given condition, using
-an SQL @WHERE@ clause.
-
-You would typically use 'keepWhen' if you want to write
-your query using a "point free" style.  If you want to use 'A.Arrow'
-notation then 'restrict' will suit you better.
-
-This is the 'S.SelectArr' equivalent of 'Prelude.filter' from the
-'Prelude'.
--}
-keepWhen :: (a -> F.Field T.SqlBool) -> S.SelectArr a a
-keepWhen p = proc a -> do
-  restrict  -< p a
-  A.returnA -< a
-
 -- * Equality operators
 
 infix 4 .==
@@ -197,9 +188,15 @@
 ilike :: F.Field T.SqlText -> F.Field T.SqlText -> F.Field T.SqlBool
 ilike = C.binOp HPQ.OpILike
 
+-- {-# DEPRECATED charLength "You probably want to use 'sqlLength' instead" #-}
+-- | Do not use.  Will be deprecated in 0.8.  You probably want to use
+-- 'sqlLength' instead.
 charLength :: C.PGString a => Column a -> Column Int
 charLength (Column e) = Column (HPQ.FunExpr "char_length" [e])
 
+sqlLength :: C.PGString a => F.Field a -> F.Field T.SqlInt4
+sqlLength  (Column e) = Column (HPQ.FunExpr "length" [e])
+
 -- * Containment operators
 
 -- | 'in_' is designed to be used in prefix form.
@@ -398,6 +395,9 @@
                       -> F.Field T.SqlTimestamp
 timestamptzAtTimeZone = C.binOp HPQ.OpAtTimeZone
 
+dateOfTimestamp :: F.Field T.SqlTimestamp -> F.Field T.SqlDate
+dateOfTimestamp (Column e) = Column (HPQ.FunExpr "date" [e])
+
 -- * Deprecated
 
 {-# DEPRECATED exists "Identical to 'restrictExists'.  Will be removed in version 0.8." #-}
@@ -412,3 +412,21 @@
 inQuery :: D.Default O.EqPP fields fields
         => fields -> Query fields -> S.Select (F.Field T.SqlBool)
 inQuery = inSelect
+
+{-| This function is probably not useful and is likely to be deprecated
+  in the future.
+
+Keep only the rows of a query satisfying a given condition, using
+an SQL @WHERE@ clause.
+
+You would typically use 'keepWhen' if you want to write
+your query using a "point free" style.  If you want to use 'A.Arrow'
+notation then 'restrict' will suit you better.
+
+This is the 'S.SelectArr' equivalent of 'Prelude.filter' from the
+'Prelude'.
+-}
+keepWhen :: (a -> F.Field T.SqlBool) -> S.SelectArr a a
+keepWhen p = proc a -> do
+  restrict  -< p a
+  A.returnA -< a
diff --git a/src/Opaleye/Sql.hs b/src/Opaleye/Sql.hs
--- a/src/Opaleye/Sql.hs
+++ b/src/Opaleye/Sql.hs
@@ -17,7 +17,7 @@
 import qualified Opaleye.Internal.Unpackspec as U
 import qualified Opaleye.Internal.Print as Pr
 import qualified Opaleye.Internal.Optimize as Op
-import           Opaleye.Internal.Helpers ((.:))
+import           Opaleye.Internal.Helpers ((.:), atSameType)
 import qualified Opaleye.Internal.QueryArr as Q
 
 import qualified Opaleye.Select as S
@@ -41,18 +41,16 @@
 -- @
 -- showSql :: Select (Foo (Field a) (Field b) (Field c)) -> Maybe String
 -- @
-showSql :: forall fields.
-           D.Default U.Unpackspec fields fields
+showSql :: D.Default U.Unpackspec fields fields
         => S.Select fields
         -> Maybe String
-showSql = showSqlExplicit (D.def :: U.Unpackspec fields fields)
+showSql = showSqlExplicit (atSameType D.def)
 
 -- | Show the unoptimized SQL query string generated from the 'S.Select'.
-showSqlUnopt :: forall fields.
-                D.Default U.Unpackspec fields fields
+showSqlUnopt :: D.Default U.Unpackspec fields fields
              => S.Select fields
              -> Maybe String
-showSqlUnopt = showSqlUnoptExplicit (D.def :: U.Unpackspec fields fields)
+showSqlUnopt = showSqlUnoptExplicit (atSameType D.def)
 
 showSqlExplicit :: U.Unpackspec fields b -> S.Select fields -> Maybe String
 showSqlExplicit = Pr.formatAndShowSQL
