diff --git a/CHANGES b/CHANGES
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+* 0.3: 2 May 2013
+
+  - generalize PosInf to Inf, which supports making monoids out of
+    semigroups under both min and max
+
 * 0.2.2.3: 28 March 2013
 
   - bump upper bound to allow base-4.7
diff --git a/monoid-extras.cabal b/monoid-extras.cabal
--- a/monoid-extras.cabal
+++ b/monoid-extras.cabal
@@ -1,5 +1,5 @@
 name:                monoid-extras
-version:             0.2.2.3
+version:             0.3.0.0
 synopsis:            Various extra monoid-related definitions and utilities
 description:         Various extra monoid-related definitions and utilities,
                      such as monoid actions, monoid coproducts, \"deletable\"
@@ -24,8 +24,8 @@
                      Data.Monoid.Coproduct,
                      Data.Monoid.Cut,
                      Data.Monoid.Deletable,
+                     Data.Monoid.Inf,
                      Data.Monoid.MList,
-                     Data.Monoid.PosInf,
                      Data.Monoid.Recommend,
                      Data.Monoid.Split,
                      Data.Monoid.WithSemigroup
diff --git a/src/Data/Monoid/Inf.hs b/src/Data/Monoid/Inf.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Monoid/Inf.hs
@@ -0,0 +1,79 @@
+{-# LANGUAGE FlexibleInstances #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Monoid.Inf
+-- Copyright   :  (c) 2012 diagrams-core team (see LICENSE)
+-- License     :  BSD-style (see LICENSE)
+-- Maintainer  :  diagrams-discuss@googlegroups.com
+--
+-- Make semigroup under 'min' or 'max' into monoids by adjoining an
+-- element corresponding to infinity (positive or negative,
+-- respectively). These types are similar to @Option (Min a)@ and
+-- @Option (Max a)@ respectively, except that the 'Ord' instance
+-- matches the 'Monoid' instance.
+--
+-----------------------------------------------------------------------------
+
+module Data.Monoid.Inf
+       ( Inf(..)
+       , PosInf, NegInf
+       , minimum, maximum
+       -- * Type-restricted constructors
+       , posInfty, negInfty
+       , posFinite, negFinite
+       ) where
+
+import           Data.Semigroup
+import qualified Prelude as P
+import           Prelude hiding (minimum, maximum)
+
+data Pos
+data Neg
+
+data Inf p a = Infinity | Finite a
+  deriving (Eq, Show, Read)
+
+type PosInf a = Inf Pos a
+type NegInf a = Inf Neg a
+
+instance Ord a => Ord (Inf Pos a) where
+  compare Infinity Infinity = EQ
+  compare Infinity Finite{} = GT
+  compare Finite{} Infinity = LT
+  compare (Finite a) (Finite b) = compare a b
+
+instance Ord a => Ord (Inf Neg a) where
+  compare Infinity Infinity = EQ
+  compare Infinity Finite{} = LT
+  compare Finite{} Infinity = GT
+  compare (Finite a) (Finite b) = compare a b
+
+instance Ord a => Semigroup (Inf Pos a) where
+  (<>) = min
+
+instance Ord a => Semigroup (Inf Neg a) where
+  (<>) = max
+
+instance Ord a => Monoid (Inf Pos a) where
+  mempty = Infinity
+  mappend = (<>)
+
+instance Ord a => Monoid (Inf Neg a) where
+  mempty = Infinity
+  mappend = (<>)
+
+minimum :: Ord a => [a] -> PosInf a
+minimum xs = P.minimum (Infinity : map Finite xs)
+
+maximum :: Ord a => [a] -> NegInf a
+maximum xs = P.maximum (Infinity : map Finite xs)
+
+posInfty :: PosInf a
+negInfty :: NegInf a
+posFinite :: a -> PosInf a
+negFinite :: a -> NegInf a
+
+posInfty = Infinity
+negInfty = Infinity
+posFinite = Finite
+negFinite = Finite
diff --git a/src/Data/Monoid/PosInf.hs b/src/Data/Monoid/PosInf.hs
deleted file mode 100644
--- a/src/Data/Monoid/PosInf.hs
+++ /dev/null
@@ -1,33 +0,0 @@
------------------------------------------------------------------------------
--- |
--- Module      :  Data.Monoid.PosInf
--- Copyright   :  (c) 2012 diagrams-core team (see LICENSE)
--- License     :  BSD-style (see LICENSE)
--- Maintainer  :  diagrams-discuss@googlegroups.com
---
--- Make a semigroup under 'min' into a monoid by adjoining an element
--- corresponding to positive infinity.
---
------------------------------------------------------------------------------
-
-module Data.Monoid.PosInf
-       ( PosInf(..)
-       , minimum
-       ) where
-
-import           Data.Semigroup
-import qualified Prelude as P
-import           Prelude hiding (minimum)
-
-data PosInf a = Finite a | PosInfty
-  deriving (Eq, Ord, Show)
-
-instance Ord a => Semigroup (PosInf a) where
-  (<>) = min
-
-instance Ord a => Monoid (PosInf a) where
-  mempty = PosInfty
-  mappend = (<>)
-
-minimum :: Ord a => [a] -> PosInf a
-minimum xs = P.minimum (PosInfty : map Finite xs)
