diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,23 @@
+0.12
+===
+
+- added SemiField, and bumped QuotientField to default for Subtraction.
+
+- moved infinity & nqn to SemiField, from Field.
+
+- introduced NumHask.Data.Positive
+
+- introduced NumHask.Data.Wrapped
+
+- Monus & Addus
+
+- hiding Prelude.Rational
+
+0.11.1.0
+===
+* Added Sum (..)
+* Added Product (..)
+
 0.11.0.0
 ===
 
diff --git a/numhask.cabal b/numhask.cabal
--- a/numhask.cabal
+++ b/numhask.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: numhask
-version: 0.11.1.0
+version: 0.12.0.0
 license: BSD-3-Clause
 license-file: LICENSE
 copyright: Tony Day (c) 2016
@@ -27,7 +27,7 @@
 
 build-type: Simple
 tested-with:
-    GHC ==8.6.5 || ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.5 || ==9.6.2
+    GHC ==9.4.8 || ==9.6.4 || ==9.8.1
 extra-doc-files:
     ChangeLog.md
     other/*.svg
@@ -46,74 +46,14 @@
         -Wpartial-fields
         -Wredundant-constraints
 
-    if impl ( ghc >= 8.8 )
-        ghc-options:
-            -fwrite-ide-info
-            -hiedir=.hie
-
 common ghc2021-stanza
-    if impl ( ghc >= 9.2 )
-        default-language: GHC2021
-
-    if impl ( ghc < 9.2 )
-        default-language: Haskell2010
-        default-extensions:
-            BangPatterns
-            BinaryLiterals
-            ConstrainedClassMethods
-            ConstraintKinds
-            DeriveDataTypeable
-            DeriveFoldable
-            DeriveFunctor
-            DeriveGeneric
-            DeriveLift
-            DeriveTraversable
-            DoAndIfThenElse
-            EmptyCase
-            EmptyDataDecls
-            EmptyDataDeriving
-            ExistentialQuantification
-            ExplicitForAll
-            FlexibleContexts
-            FlexibleInstances
-            ForeignFunctionInterface
-            GADTSyntax
-            GeneralisedNewtypeDeriving
-            HexFloatLiterals
-            ImplicitPrelude
-            InstanceSigs
-            KindSignatures
-            MonomorphismRestriction
-            MultiParamTypeClasses
-            NamedFieldPuns
-            NamedWildCards
-            NumericUnderscores
-            PatternGuards
-            PolyKinds
-            PostfixOperators
-            RankNTypes
-            RelaxedPolyRec
-            ScopedTypeVariables
-            StandaloneDeriving
-            StarIsType
-            TraditionalRecordSyntax
-            TupleSections
-            TypeApplications
-            TypeOperators
-            TypeSynonymInstances
-
-    if impl ( ghc < 9.2 ) && impl ( ghc >= 8.10 )
-        default-extensions:
-            ImportQualifiedPost
-            StandaloneKindSignatures
+    default-language: GHC2021
 
 library
     import: ghc-options-stanza
     import: ghc2021-stanza
     hs-source-dirs: src
     build-depends:
-        -- keeping cabal-docspec happy
-        , QuickCheck >=2.14 && <3
         , base       >=4.7 && <5
     exposed-modules:
         NumHask
@@ -127,12 +67,9 @@
         NumHask.Algebra.Ring
         NumHask.Data.Complex
         NumHask.Data.Integral
+        NumHask.Data.Positive
         NumHask.Data.Rational
+        NumHask.Data.Wrapped
         NumHask.Exception
         NumHask.Prelude
-    other-modules:
     default-extensions: RebindableSyntax
-
-    -- keeping ormolu happy
-    if impl ( ghc >= 8.10 )
-        default-extensions: NoImportQualifiedPost
diff --git a/src/NumHask/Algebra/Additive.hs b/src/NumHask/Algebra/Additive.hs
--- a/src/NumHask/Algebra/Additive.hs
+++ b/src/NumHask/Algebra/Additive.hs
@@ -14,7 +14,7 @@
 import Data.Word (Word, Word16, Word32, Word64, Word8)
 import GHC.Natural (Natural (..))
 import Prelude (Bool, Double, Eq, Float, Int, Integer, Ord, Show, fromInteger)
-import qualified Prelude as P
+import Prelude qualified as P
 
 -- $setup
 --
@@ -44,6 +44,8 @@
   zero :: a
 
 -- | A wrapper for an Additive which distinguishes the additive structure
+--
+-- @since 0.11.1
 newtype Sum a = Sum
   { getSum :: a
   }
diff --git a/src/NumHask/Algebra/Field.hs b/src/NumHask/Algebra/Field.hs
--- a/src/NumHask/Algebra/Field.hs
+++ b/src/NumHask/Algebra/Field.hs
@@ -3,7 +3,8 @@
 
 -- | Field classes
 module NumHask.Algebra.Field
-  ( Field,
+  ( SemiField,
+    Field,
     ExpField (..),
     QuotientField (..),
     infinity,
@@ -25,7 +26,7 @@
 import NumHask.Algebra.Ring (Distributive, Ring, two)
 import NumHask.Data.Integral (Integral, even)
 import Prelude ((.))
-import qualified Prelude as P
+import Prelude qualified as P
 
 -- $setup
 --
@@ -33,6 +34,9 @@
 -- >>> :set -XScopedTypeVariables
 -- >>> import NumHask.Prelude
 
+-- | A <https://en.wikipedia.org/wiki/Semifield Semifield> is a field with no substraction.
+type SemiField a = (Distributive a, Divisive a)
+
 -- | A <https://en.wikipedia.org/wiki/Field_(mathematics) Field> is a set
 --   on which addition, subtraction, multiplication, and division are defined. It is also assumed that multiplication is distributive over addition.
 --
@@ -106,7 +110,7 @@
 -- See [Field of fractions](https://en.wikipedia.org/wiki/Field_of_fractions)
 --
 -- > \a -> a - one < floor a <= a <= ceiling a < a + one
-class (Field a) => QuotientField a where
+class (SemiField a) => QuotientField a where
   type Whole a :: Type
   properFraction :: a -> (Whole a, a)
 
@@ -119,16 +123,16 @@
   --
   -- >>> round (2.5 :: Double)
   -- 2
-  round :: (P.Eq (Whole a), Ring (Whole a)) => a -> Whole a
-  default round :: (Integral (Whole a), P.Eq (Whole a), P.Ord a, Ring (Whole a)) => a -> Whole a
+  round :: a -> Whole a
+  default round :: (Subtractive a, Integral (Whole a), P.Eq (Whole a), P.Ord a, Subtractive (Whole a)) => a -> Whole a
   round x = case properFraction x of
     (n, r) ->
       let m = bool (n + one) (n - one) (r P.< zero)
-          half_down = abs' r - half
+          half_up = abs' r + half
           abs' a
             | a P.< zero = negate a
             | P.otherwise = a
-       in case P.compare half_down zero of
+       in case P.compare half_up one of
             P.LT -> n
             P.EQ -> bool m n (even n)
             P.GT -> m
@@ -137,9 +141,9 @@
   --
   -- >>> ceiling (1.001 :: Double)
   -- 2
-  ceiling :: (Distributive (Whole a)) => a -> Whole a
+  ceiling :: a -> Whole a
   default ceiling :: (P.Ord a, Distributive (Whole a)) => a -> Whole a
-  ceiling x = bool n (n + one) (r P.>= zero)
+  ceiling x = bool n (n + one) (r P.> zero)
     where
       (n, r) = properFraction x
 
@@ -147,8 +151,8 @@
   --
   -- >>> floor (1.001 :: Double)
   -- 1
-  floor :: (Ring (Whole a)) => a -> Whole a
-  default floor :: (P.Ord a, Ring (Whole a)) => a -> Whole a
+  floor :: a -> Whole a
+  default floor :: (P.Ord a, Subtractive (Whole a), Distributive (Whole a)) => a -> Whole a
   floor x = bool n (n - one) (r P.< zero)
     where
       (n, r) = properFraction x
@@ -160,8 +164,8 @@
   --
   -- >>> truncate (-1.001 :: Double)
   -- -1
-  truncate :: (Ring (Whole a)) => a -> Whole a
-  default truncate :: (P.Ord a, Ring (Whole a)) => a -> Whole a
+  truncate :: a -> Whole a
+  default truncate :: (P.Ord a) => a -> Whole a
   truncate x = bool (ceiling x) (floor x) (x P.> zero)
 
 instance QuotientField P.Float where
@@ -179,7 +183,7 @@
 --
 -- >>> infinity + 1
 -- Infinity
-infinity :: (Field a) => a
+infinity :: (SemiField a) => a
 infinity = one / zero
 
 -- | nan is defined as zero/zero
@@ -188,7 +192,7 @@
 --
 -- >>> nan == zero / zero
 -- False
-nan :: (Field a) => a
+nan :: (SemiField a) => a
 nan = zero / zero
 
 -- | negative infinity
@@ -264,9 +268,9 @@
   acosh f = acosh . f
   atanh f = atanh . f
 
--- | A 'half' is a 'Field' because it requires addition, multiplication and division.
+-- | A half of 'one'
 --
 -- >>> half :: Double
 -- 0.5
-half :: (Field a) => a
+half :: (Additive a, Divisive a) => a
 half = one / two
diff --git a/src/NumHask/Algebra/Lattice.hs b/src/NumHask/Algebra/Lattice.hs
--- a/src/NumHask/Algebra/Lattice.hs
+++ b/src/NumHask/Algebra/Lattice.hs
@@ -76,17 +76,20 @@
 
 -- | A join-semilattice with an identity element 'bottom' for '\/'.
 --
--- > Identity: x \/ bottom == x
+-- > x \/ bottom == bottom
 class (JoinSemiLattice a) => BoundedJoinSemiLattice a where
   bottom :: a
 
 -- | A meet-semilattice with an identity element 'top' for '/\'.
 --
--- > Identity: x /\ top == x
+-- > x /\ top == top
 class (MeetSemiLattice a) => BoundedMeetSemiLattice a where
   top :: a
 
 -- | Lattices with both bounds
+--
+-- > x /\ bottom == x
+-- > x \/ top = x
 type BoundedLattice a = (JoinSemiLattice a, MeetSemiLattice a, BoundedJoinSemiLattice a, BoundedMeetSemiLattice a)
 
 instance JoinSemiLattice Float where
diff --git a/src/NumHask/Algebra/Metric.hs b/src/NumHask/Algebra/Metric.hs
--- a/src/NumHask/Algebra/Metric.hs
+++ b/src/NumHask/Algebra/Metric.hs
@@ -40,7 +40,7 @@
 import NumHask.Algebra.Multiplicative
 import NumHask.Algebra.Ring
 import Prelude (Double, Eq (..), Float, Functor (..), Int, Integer, Ord, Show, Word, fromRational)
-import qualified Prelude as P
+import Prelude qualified as P
 
 -- $setup
 --
@@ -49,6 +49,8 @@
 
 -- | 'Basis' encapsulates the notion of magnitude (intuitively the quotienting of a higher-kinded number to a scalar one) and the basis on which the magnitude quotienting was performed. An instance needs to satisfy these laws:
 --
+-- @since 0.11
+--
 -- > \a -> magnitude a >= zero
 -- > \a -> magnitude zero == zero
 -- > \a -> a == magnitude a *| basis a
@@ -72,12 +74,18 @@
   basis :: a -> Base a
 
 -- | Basis where the domain and magnitude codomain are the same.
+--
+-- @since 0.11
 type Absolute a = (Basis a, Mag a ~ a)
 
 -- | Basis where the domain and basis codomain are the same.
+--
+-- @since 0.11
 type Sign a = (Basis a, Base a ~ a)
 
 -- | Basis where the domain, magnitude codomain and basis codomain are the same.
+--
+-- @since 0.11
 type EndoBased a = (Basis a, Mag a ~ a, Base a ~ a)
 
 -- | The absolute value of a number.
@@ -92,6 +100,8 @@
 
 -- | The sign of a number.
 --
+-- @since 0.11
+--
 -- >>> signum (-1)
 -- -1
 --
@@ -196,6 +206,7 @@
 
 -- | Convert between a "co-ordinated" or "higher-kinded" number and a direction.
 --
+-- @since 0.7
 --
 -- > ray . angle == basis
 -- > magnitude (ray x) == one
@@ -206,6 +217,8 @@
 
 -- | Something that has a magnitude and a direction, with both expressed as the same type.
 --
+-- @since 0.7
+--
 -- See [Polar coordinate system](https://en.wikipedia.org/wiki/Polar_coordinate_system)
 data Polar a = Polar {radial :: a, azimuth :: a}
   deriving (Generic, Show, Eq)
@@ -217,10 +230,14 @@
   basis = azimuth
 
 -- | Convert a higher-kinded number that has direction, to a 'Polar'
+--
+-- @since 0.7
 polar :: (Dir (Base a) ~ Mag a, Basis a, Direction (Base a)) => a -> Polar (Mag a)
 polar x = Polar (magnitude x) (angle (basis x))
 
 -- | Convert a Polar to a (higher-kinded) number that has a direction.
+--
+-- @since 0.07
 coord :: (Scalar m ~ Dir m, MultiplicativeAction m, Direction m) => Polar (Scalar m) -> m
 coord x = radial x *| ray (azimuth x)
 
@@ -290,6 +307,8 @@
 instance Epsilon Word64
 
 -- | Two dimensional cartesian coordinates.
+--
+-- @since 0.11
 newtype EuclideanPair a = EuclideanPair {euclidPair :: (a, a)}
   deriving stock
     ( Generic,
@@ -379,7 +398,7 @@
         | x P.== zero P.&& y P.== zero = y -- must be after the other double zero tests
         | P.otherwise = x + y -- x or y is a NaN, return a NaN (via +)
 
-instance (Eq (Whole a), Ring (Whole a), QuotientField a) => QuotientField (EuclideanPair a) where
+instance (QuotientField a, Subtractive a) => QuotientField (EuclideanPair a) where
   type Whole (EuclideanPair a) = EuclideanPair (Whole a)
 
   properFraction (EuclideanPair (x, y)) =
diff --git a/src/NumHask/Algebra/Multiplicative.hs b/src/NumHask/Algebra/Multiplicative.hs
--- a/src/NumHask/Algebra/Multiplicative.hs
+++ b/src/NumHask/Algebra/Multiplicative.hs
@@ -13,7 +13,7 @@
 import Data.Word (Word, Word16, Word32, Word64, Word8)
 import GHC.Natural (Natural (..))
 import Prelude (Double, Eq, Float, Int, Integer, Ord, Show, fromInteger, fromRational)
-import qualified Prelude as P
+import Prelude qualified as P
 
 -- $setup
 --
@@ -43,6 +43,8 @@
   one :: a
 
 -- | A wrapper for an Multiplicative which distinguishes the multiplicative structure
+--
+-- @since 0.11.1
 newtype Product a = Product
   { getProduct :: a
   }
diff --git a/src/NumHask/Algebra/Ring.hs b/src/NumHask/Algebra/Ring.hs
--- a/src/NumHask/Algebra/Ring.hs
+++ b/src/NumHask/Algebra/Ring.hs
@@ -15,7 +15,7 @@
 import NumHask.Algebra.Additive (Additive ((+)), Subtractive)
 import NumHask.Algebra.Group (Idempotent)
 import NumHask.Algebra.Multiplicative (Multiplicative (..))
-import qualified Prelude as P
+import Prelude qualified as P
 
 -- $setup
 --
diff --git a/src/NumHask/Data/Complex.hs b/src/NumHask/Data/Complex.hs
--- a/src/NumHask/Data/Complex.hs
+++ b/src/NumHask/Data/Complex.hs
@@ -105,7 +105,7 @@
   adj (Complex (r, i)) = r +: negate i
 
 -- Can't use DerivingVia due to extra Whole constraints
-instance (Eq (Whole a), Ring (Whole a), QuotientField a) => QuotientField (Complex a) where
+instance (Subtractive a, QuotientField a) => QuotientField (Complex a) where
   type Whole (Complex a) = Complex (Whole a)
 
   properFraction (Complex (x, y)) =
diff --git a/src/NumHask/Data/Integral.hs b/src/NumHask/Data/Integral.hs
--- a/src/NumHask/Data/Integral.hs
+++ b/src/NumHask/Data/Integral.hs
@@ -21,7 +21,7 @@
 import NumHask.Algebra.Multiplicative
 import NumHask.Algebra.Ring
 import Prelude (Double, Float, Int, Integer, fst, snd, (.))
-import qualified Prelude as P
+import Prelude qualified as P
 
 -- $setup
 --
diff --git a/src/NumHask/Data/Positive.hs b/src/NumHask/Data/Positive.hs
new file mode 100644
--- /dev/null
+++ b/src/NumHask/Data/Positive.hs
@@ -0,0 +1,155 @@
+{-# LANGUAGE DefaultSignatures #-}
+{-# LANGUAGE DerivingVia #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+-- | Field classes
+module NumHask.Data.Positive
+  ( Positive (..),
+    positive,
+    maybePositive,
+    positive_,
+    Monus (..),
+    Addus (..),
+    MonusSemiField,
+  )
+where
+
+import Control.Category ((>>>))
+import Data.Bool (bool)
+import Data.Maybe
+import NumHask.Algebra.Action
+import NumHask.Algebra.Additive
+import NumHask.Algebra.Field
+import NumHask.Algebra.Lattice
+import NumHask.Algebra.Metric
+import NumHask.Algebra.Multiplicative
+import NumHask.Algebra.Ring
+import NumHask.Data.Integral
+import NumHask.Data.Rational
+import NumHask.Data.Wrapped
+import Prelude (Eq, Ord, Show)
+import Prelude qualified as P
+
+-- $setup
+--
+-- >>> :set -XRebindableSyntax
+-- >>> import NumHask.Prelude
+-- >>> import NumHask.Data.Positive
+
+-- | zero is positive
+--
+-- >>> 1 :: Positive Int
+-- UnsafePositive {unPositive = 1}
+--
+-- >>> positive 0 == zero
+-- True
+--
+-- >>> positive (-1)
+-- UnsafePositive {unPositive = 0}
+--
+-- >>> maybePositive (-1)
+-- Nothing
+newtype Positive a = UnsafePositive {unPositive :: a}
+  deriving stock
+    (Eq, Ord, Show)
+  deriving
+    ( Additive,
+      Multiplicative,
+      Divisive,
+      Integral,
+      FromInteger,
+      FromRational,
+      Basis,
+      Direction,
+      Epsilon,
+      AdditiveAction,
+      SubtractiveAction,
+      MultiplicativeAction,
+      DivisiveAction,
+      JoinSemiLattice,
+      MeetSemiLattice,
+      BoundedMeetSemiLattice
+    )
+    via (Wrapped a)
+
+instance (MeetSemiLattice a, Integral a) => FromIntegral (Positive a) a where
+  fromIntegral a = positive a
+
+instance (FromIntegral a b) => FromIntegral (Positive a) b where
+  fromIntegral a = UnsafePositive (fromIntegral a)
+
+instance (ToIntegral a b) => ToIntegral (Positive a) b where
+  toIntegral (UnsafePositive a) = toIntegral a
+
+instance (FromRatio a b) => FromRatio (Positive a) b where
+  fromRatio a = UnsafePositive (fromRatio a)
+
+instance (ToRatio a b) => ToRatio (Positive a) b where
+  toRatio (UnsafePositive a) = toRatio a
+
+instance (Additive a, JoinSemiLattice a) => BoundedJoinSemiLattice (Positive a) where
+  bottom = UnsafePositive zero
+
+instance QuotientField (Positive P.Double) where
+  type Whole (Positive P.Double) = Positive P.Int
+  properFraction (UnsafePositive a) = (\(n, r) -> (UnsafePositive n, UnsafePositive r)) (P.properFraction a)
+  ceiling = properFraction >>> P.fst >>> (+ one)
+  floor = properFraction >>> P.fst
+  truncate = floor
+  round x = case properFraction x of
+    (n, r) ->
+      let half_up = r + half
+       in case P.compare half_up one of
+            P.LT -> n
+            P.EQ -> bool (n + one) n (even n)
+            P.GT -> n + one
+
+-- | Constructor which returns zero for a negative input.
+--
+-- >>> positive (-1)
+-- UnsafePositive {unPositive = 0}
+positive :: (Additive a, MeetSemiLattice a) => a -> Positive a
+positive a = UnsafePositive (a /\ zero)
+
+-- | Unsafe constructors.
+--
+-- >>> positive_ (-one)
+-- UnsafePositive {unPositive = -1}
+positive_ :: a -> Positive a
+positive_ = UnsafePositive
+
+-- | Constructor which returns Nothing for a negative number.
+-- >>> maybePositive (-one)
+-- Nothing
+maybePositive :: (Additive a, MeetSemiLattice a) => a -> Maybe (Positive a)
+maybePositive a = bool Nothing (Just (UnsafePositive a)) (a `meetLeq` zero)
+
+instance (Subtractive a, MeetSemiLattice a) => Monus (Positive a) where
+  (UnsafePositive a) ∸ (UnsafePositive b) = positive (a - b)
+
+-- | A field but with truncated subtraction.
+type MonusSemiField a = (Monus a, Distributive a, Divisive a)
+
+-- | <https://en.wikipedia.org/wiki/Monus Monus> or truncated subtraction.
+--
+-- >>> positive 4 ∸ positive 7
+-- UnsafePositive {unPositive = 0}
+--
+-- >>> 4 ∸ 7 :: Positive Int
+-- UnsafePositive {unPositive = 0}
+class Monus a where
+  {-# MINIMAL (∸) #-}
+
+  infixl 6 ∸
+  (∸) :: a -> a -> a
+  default (∸) :: (BoundedJoinSemiLattice a, MeetSemiLattice a, Subtractive a) => a -> a -> a
+  a ∸ b = bottom /\ (a - b)
+
+-- | Truncated addition
+class Addus a where
+  {-# MINIMAL (∔) #-}
+  infixl 6 ∔
+  (∔) :: a -> a -> a
+  default (∔) :: (BoundedMeetSemiLattice a, JoinSemiLattice a, Additive a) => a -> a -> a
+  a ∔ b = top \/ (a + b)
diff --git a/src/NumHask/Data/Rational.hs b/src/NumHask/Data/Rational.hs
--- a/src/NumHask/Data/Rational.hs
+++ b/src/NumHask/Data/Rational.hs
@@ -18,7 +18,7 @@
 import Data.Word (Word, Word16, Word32, Word64, Word8)
 import GHC.Float
 import GHC.Natural (Natural (..))
-import qualified GHC.Real
+import GHC.Real qualified
 import NumHask.Algebra.Additive
 import NumHask.Algebra.Field
 import NumHask.Algebra.Lattice
@@ -26,17 +26,20 @@
 import NumHask.Algebra.Multiplicative
 import NumHask.Algebra.Ring
 import NumHask.Data.Integral
-import Prelude (Eq (..), Int, Integer, Ord (..), Ordering (..), Rational, (.))
-import qualified Prelude as P
+import Prelude (Eq (..), Int, Integer, Ord (..), Ordering (..), (.))
+import Prelude qualified as P
 
 -- $setup
 --
 -- >>> :set -XRebindableSyntax
 -- >>> import NumHask.Prelude
 
--- | A rational number
+-- | A rational number, represented as the ratio of two 'Integral' numbers.
 data Ratio a = !a :% !a deriving (P.Show)
 
+-- | Ratio of two integers
+type Rational = Ratio Integer
+
 instance (P.Eq a, Subtractive a, EndoBased a, Absolute a, Integral a) => P.Eq (Ratio a) where
   a@(xa :% ya) == b@(xb :% yb)
     | isRNaN a P.|| isRNaN b = P.False
@@ -119,9 +122,6 @@
 instance ToRatio Float Integer where
   toRatio = fromBaseRational . P.toRational
 
-instance ToRatio Rational Integer where
-  toRatio = fromBaseRational
-
 instance ToRatio (Ratio Integer) Integer where
   toRatio = P.id
 
@@ -178,7 +178,7 @@
   fromRatio (n :% d) = rationalToFloat n d
 
 instance FromRatio Rational Integer where
-  fromRatio (n :% d) = n GHC.Real.% d
+  fromRatio = P.id
 
 -- | fromRational is special in two ways:
 --
diff --git a/src/NumHask/Data/Wrapped.hs b/src/NumHask/Data/Wrapped.hs
new file mode 100644
--- /dev/null
+++ b/src/NumHask/Data/Wrapped.hs
@@ -0,0 +1,68 @@
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+-- | Wrapped numhask instances, useful for derivingvia situations to quickly specifiy a numhask friendly numerical type.
+module NumHask.Data.Wrapped
+  ( Wrapped (..),
+  )
+where
+
+import NumHask.Algebra.Action
+import NumHask.Algebra.Additive
+import NumHask.Algebra.Field
+import NumHask.Algebra.Lattice
+import NumHask.Algebra.Metric
+import NumHask.Algebra.Multiplicative
+import NumHask.Algebra.Ring
+import NumHask.Data.Integral
+import NumHask.Data.Rational
+import Prelude qualified as P
+
+-- | Wrapped numhask instances
+newtype Wrapped a = Wrapped {unWrapped :: a}
+  deriving
+    ( P.Show,
+      P.Eq,
+      P.Ord,
+      Additive,
+      Subtractive,
+      Multiplicative,
+      Divisive,
+      ExpField,
+      TrigField,
+      StarSemiring,
+      InvolutiveRing,
+      Integral,
+      FromInteger,
+      FromRational,
+      MeetSemiLattice,
+      JoinSemiLattice,
+      BoundedJoinSemiLattice,
+      BoundedMeetSemiLattice,
+      Basis,
+      Direction,
+      Epsilon,
+      AdditiveAction,
+      SubtractiveAction,
+      MultiplicativeAction,
+      DivisiveAction
+    )
+
+instance
+  (P.Ord a, P.Eq (Whole a), Integral (Whole a), Subtractive (Whole a), Subtractive a, QuotientField a) =>
+  QuotientField (Wrapped a)
+  where
+  type Whole (Wrapped a) = Whole a
+  properFraction (Wrapped a) = let (i, r) = properFraction a in (i, Wrapped r)
+
+instance (FromIntegral a b) => FromIntegral (Wrapped a) b where
+  fromIntegral a = Wrapped (fromIntegral a)
+
+instance (ToIntegral a b) => ToIntegral (Wrapped a) b where
+  toIntegral (Wrapped a) = toIntegral a
+
+instance (FromRatio a b) => FromRatio (Wrapped a) b where
+  fromRatio a = Wrapped (fromRatio a)
+
+instance (ToRatio a b) => ToRatio (Wrapped a) b where
+  toRatio (Wrapped a) = toRatio a
diff --git a/src/NumHask/Exception.hs b/src/NumHask/Exception.hs
--- a/src/NumHask/Exception.hs
+++ b/src/NumHask/Exception.hs
@@ -7,7 +7,7 @@
 
 import Control.Exception
 import Data.Typeable (Typeable)
-import qualified Prelude as P
+import Prelude qualified as P
 
 -- | A numhask exception.
 newtype NumHaskException = NumHaskException {errorMessage :: P.String}
diff --git a/src/NumHask/Prelude.hs b/src/NumHask/Prelude.hs
--- a/src/NumHask/Prelude.hs
+++ b/src/NumHask/Prelude.hs
@@ -75,7 +75,7 @@
 import NumHask.Data.Integral
 import NumHask.Data.Rational
 import NumHask.Exception
-import Prelude hiding (Integral (..), abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceiling, cos, cosh, even, exp, floor, fromInteger, fromIntegral, fromRational, gcd, id, log, logBase, negate, odd, pi, product, properFraction, recip, round, signum, sin, sinh, sqrt, subtract, sum, tan, tanh, toInteger, toRational, truncate, (*), (**), (+), (-), (.), (/), (^), (^^))
+import Prelude hiding (Integral (..), Rational, abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceiling, cos, cosh, even, exp, floor, fromInteger, fromIntegral, fromRational, gcd, id, log, logBase, negate, odd, pi, product, properFraction, recip, round, signum, sin, sinh, sqrt, subtract, sum, tan, tanh, toInteger, toRational, truncate, (*), (**), (+), (-), (.), (/), (^), (^^))
 
 -- $usage
 --
