packages feed

closed 0.2.0.3 → 0.2.1.0

raw patch · 4 files changed

+119/−56 lines, 4 filesdep +randomPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: random

API changes (from Hackage documentation)

- Closed.Internal: instance (n Data.Type.Ord.<= m, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat m) => Data.Aeson.Types.FromJSON.FromJSON (Closed.Internal.Closed n m)
- Closed.Internal: instance (n Data.Type.Ord.<= m, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat m) => Data.Csv.Conversion.FromField (Closed.Internal.Closed n m)
- Closed.Internal: instance (n Data.Type.Ord.<= m, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat m) => Database.Persist.Class.PersistField.PersistField (Closed.Internal.Closed n m)
- Closed.Internal: instance (n Data.Type.Ord.<= m, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat m) => Database.Persist.Sql.Class.PersistFieldSql (Closed.Internal.Closed n m)
- Closed.Internal: instance (n Data.Type.Ord.<= m, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat m) => GHC.Enum.Bounded (Closed.Internal.Closed n m)
- Closed.Internal: instance (n Data.Type.Ord.<= m, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat m) => GHC.Enum.Enum (Closed.Internal.Closed n m)
- Closed.Internal: instance (n Data.Type.Ord.<= m, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat m) => GHC.Num.Num (Closed.Internal.Closed n m)
- Closed.Internal: instance (n Data.Type.Ord.<= m, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat m) => GHC.Real.Integral (Closed.Internal.Closed n m)
- Closed.Internal: instance (n Data.Type.Ord.<= m, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat m) => GHC.Real.Real (Closed.Internal.Closed n m)
- Closed.Internal: instance (n Data.Type.Ord.<= m, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat m) => Test.QuickCheck.Arbitrary.Arbitrary (Closed.Internal.Closed n m)
- Closed.Internal: instance Control.DeepSeq.NFData (Closed.Internal.Closed n m)
- Closed.Internal: instance Data.Aeson.Types.ToJSON.ToJSON (Closed.Internal.Closed n m)
- Closed.Internal: instance Data.Csv.Conversion.ToField (Closed.Internal.Closed n m)
- Closed.Internal: instance Data.Hashable.Class.Hashable (Closed.Internal.Closed n m)
- Closed.Internal: instance GHC.Classes.Eq (Closed.Internal.Closed n m)
- Closed.Internal: instance GHC.Classes.Ord (Closed.Internal.Closed n m)
- Closed.Internal: instance GHC.Generics.Generic (Closed.Internal.Closed n m)
- Closed.Internal: instance GHC.Show.Show (Closed.Internal.Closed n m)
+ Closed.Internal: instance (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b, a Data.Type.Ord.<= b) => Data.Aeson.Types.FromJSON.FromJSON (Closed.Internal.Closed a b)
+ Closed.Internal: instance (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b, a Data.Type.Ord.<= b) => Data.Csv.Conversion.FromField (Closed.Internal.Closed a b)
+ Closed.Internal: instance (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b, a Data.Type.Ord.<= b) => Database.Persist.Class.PersistField.PersistField (Closed.Internal.Closed a b)
+ Closed.Internal: instance (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b, a Data.Type.Ord.<= b) => Database.Persist.Sql.Class.PersistFieldSql (Closed.Internal.Closed a b)
+ Closed.Internal: instance (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b, a Data.Type.Ord.<= b) => GHC.Enum.Bounded (Closed.Internal.Closed a b)
+ Closed.Internal: instance (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b, a Data.Type.Ord.<= b) => GHC.Enum.Enum (Closed.Internal.Closed a b)
+ Closed.Internal: instance (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b, a Data.Type.Ord.<= b) => GHC.Num.Num (Closed.Internal.Closed a b)
+ Closed.Internal: instance (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b, a Data.Type.Ord.<= b) => GHC.Read.Read (Closed.Internal.Closed a b)
+ Closed.Internal: instance (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b, a Data.Type.Ord.<= b) => GHC.Real.Integral (Closed.Internal.Closed a b)
+ Closed.Internal: instance (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b, a Data.Type.Ord.<= b) => GHC.Real.Real (Closed.Internal.Closed a b)
+ Closed.Internal: instance (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b, a Data.Type.Ord.<= b) => System.Random.Random (Closed.Internal.Closed a b)
+ Closed.Internal: instance (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b, a Data.Type.Ord.<= b) => Test.QuickCheck.Arbitrary.Arbitrary (Closed.Internal.Closed a b)
+ Closed.Internal: instance Control.DeepSeq.NFData (Closed.Internal.Closed a b)
+ Closed.Internal: instance Data.Aeson.Types.ToJSON.ToJSON (Closed.Internal.Closed a b)
+ Closed.Internal: instance Data.Csv.Conversion.ToField (Closed.Internal.Closed a b)
+ Closed.Internal: instance Data.Hashable.Class.Hashable (Closed.Internal.Closed a b)
+ Closed.Internal: instance GHC.Classes.Eq (Closed.Internal.Closed a b)
+ Closed.Internal: instance GHC.Classes.Ord (Closed.Internal.Closed a b)
+ Closed.Internal: instance GHC.Generics.Generic (Closed.Internal.Closed a b)
+ Closed.Internal: instance GHC.Show.Show (Closed.Internal.Closed a b)
- Closed: add :: forall (n :: Nat) (m :: Nat) (o :: Nat) (p :: Nat). Closed n m -> Closed o p -> Closed (n + o) (m + p)
+ Closed: add :: forall (a :: Nat) (b :: Nat) (o :: Nat) (p :: Nat) (n :: Natural) (m :: Natural). Closed a b -> Closed o p -> Closed (n + o) (m + p)
- Closed: clamp :: forall (n :: Nat) (m :: Nat) a. (KnownNat n, KnownNat m, n <= m, Integral a) => a -> Closed n m
+ Closed: clamp :: forall (a :: Nat) (b :: Nat) i. (Integral i, KnownNat a, KnownNat b, a <= b) => i -> Closed a b
- Closed: closed :: forall (n :: Nat) (m :: Nat). (n <= m, KnownNat n, KnownNat m) => Integer -> Maybe (Closed n m)
+ Closed: closed :: forall (a :: Nat) (b :: Nat). (KnownNat a, KnownNat b, a <= b) => Integer -> Maybe (Closed a b)
- Closed: cmp :: forall (n :: Nat) (m :: Nat) (o :: Nat) (p :: Nat). Closed n m -> Closed o p -> Ordering
+ Closed: cmp :: forall (a :: Nat) (b :: Nat) (o :: Nat) (p :: Nat). Closed a b -> Closed o p -> Ordering
- Closed: data Closed (n :: Nat) (m :: Nat)
+ Closed: data Closed (a :: Nat) (b :: Nat)
- Closed: equals :: forall (n :: Nat) (m :: Nat) (o :: Nat) (p :: Nat). Closed n m -> Closed o p -> Bool
+ Closed: equals :: forall (a :: Nat) (b :: Nat) (o :: Nat) (p :: Nat). Closed a b -> Closed o p -> Bool
- Closed: getClosed :: Closed n m -> Integer
+ Closed: getClosed :: Closed a b -> Integer
- Closed: isValidClosed :: forall (n :: Nat) (m :: Nat). (KnownNat n, KnownNat m) => Closed n m -> Bool
+ Closed: isValidClosed :: forall (a :: Nat) (b :: Nat). (KnownNat a, KnownNat b) => Closed a b -> Bool
- Closed: lowerBound :: forall (n :: Nat) (m :: Nat). Closed n m -> Proxy n
+ Closed: lowerBound :: forall (a :: Nat) (b :: Nat). Closed a b -> Proxy a
- Closed: multiply :: forall (n :: Nat) (m :: Nat) (o :: Nat) (p :: Nat). Closed n m -> Closed o p -> Closed (n * o) (m * p)
+ Closed: multiply :: forall (a :: Nat) (b :: Nat) (o :: Nat) (p :: Nat). Closed a b -> Closed o p -> Closed (a * o) (b * p)
- Closed: natToClosed :: forall (n :: Nat) (m :: Nat) (x :: Nat) proxy. (n <= x, x <= m, KnownNat x, KnownNat n, KnownNat m) => proxy x -> Closed n m
+ Closed: natToClosed :: forall (a :: Nat) (b :: Nat) (x :: Nat) proxy. (KnownNat a, KnownNat b, KnownNat x, a <= x, x <= b) => proxy x -> Closed a b
- Closed: strengthenLower :: forall (k :: Nat) (n :: Nat) (m :: Nat). (KnownNat n, KnownNat m, KnownNat k, n <= m, n <= k, k <= m) => Closed n m -> Maybe (Closed k m)
+ Closed: strengthenLower :: forall (k :: Nat) (a :: Nat) (b :: Nat). (KnownNat a, KnownNat b, KnownNat k, a <= b, a <= k, k <= b) => Closed a b -> Maybe (Closed k b)
- Closed: strengthenUpper :: forall (k :: Nat) (n :: Nat) (m :: Nat). (KnownNat n, KnownNat m, KnownNat k, n <= m, n <= k, k <= m) => Closed n m -> Maybe (Closed n k)
+ Closed: strengthenUpper :: forall (k :: Nat) (a :: Nat) (b :: Nat). (KnownNat a, KnownNat b, KnownNat k, a <= b, a <= k, k <= b) => Closed a b -> Maybe (Closed a k)
- Closed: sub :: forall (n :: Nat) (m :: Nat) (o :: Nat) (p :: Nat). Closed n m -> Closed o p -> Either (Closed (o - n) (p - m)) (Closed (n - o) (m - p))
+ Closed: sub :: forall (a :: Nat) (b :: Nat) (o :: Nat) (p :: Nat) (n :: Natural) (m :: Natural). Closed a b -> Closed o p -> Either (Closed (o - n) (p - m)) (Closed (n - o) (m - p))
- Closed: unsafeClosed :: forall (n :: Nat) (m :: Nat). (HasCallStack, n <= m, KnownNat n, KnownNat m) => Integer -> Closed n m
+ Closed: unsafeClosed :: forall (a :: Nat) (b :: Nat). (HasCallStack, KnownNat a, KnownNat b, a <= b) => Integer -> Closed a b
- Closed: upperBound :: forall (n :: Nat) (m :: Nat). Closed n m -> Proxy m
+ Closed: upperBound :: forall (a :: Nat) (b :: Nat). Closed a b -> Proxy b
- Closed: weakenLower :: forall (k :: Nat) (n :: Nat) (m :: Nat). (n <= m, k <= n) => Closed n m -> Closed k m
+ Closed: weakenLower :: forall (k :: Nat) (a :: Nat) (b :: Nat). (a <= b, k <= a) => Closed a b -> Closed k b
- Closed: weakenUpper :: forall (k :: Nat) (n :: Nat) (m :: Nat). (n <= m, m <= k) => Closed n m -> Closed n k
+ Closed: weakenUpper :: forall (k :: Nat) (a :: Nat) (b :: Nat). (a <= b, b <= k) => Closed a b -> Closed a k
- Closed.Internal: Closed :: Integer -> Closed (n :: Nat) (m :: Nat)
+ Closed.Internal: Closed :: Integer -> Closed (a :: Nat) (b :: Nat)
- Closed.Internal: [getClosed] :: Closed (n :: Nat) (m :: Nat) -> Integer
+ Closed.Internal: [getClosed] :: Closed (a :: Nat) (b :: Nat) -> Integer
- Closed.Internal: add :: forall (n :: Nat) (m :: Nat) (o :: Nat) (p :: Nat). Closed n m -> Closed o p -> Closed (n + o) (m + p)
+ Closed.Internal: add :: forall (a :: Nat) (b :: Nat) (o :: Nat) (p :: Nat) (n :: Natural) (m :: Natural). Closed a b -> Closed o p -> Closed (n + o) (m + p)
- Closed.Internal: clamp :: forall (n :: Nat) (m :: Nat) a. (KnownNat n, KnownNat m, n <= m, Integral a) => a -> Closed n m
+ Closed.Internal: clamp :: forall (a :: Nat) (b :: Nat) i. (Integral i, KnownNat a, KnownNat b, a <= b) => i -> Closed a b
- Closed.Internal: closed :: forall (n :: Nat) (m :: Nat). (n <= m, KnownNat n, KnownNat m) => Integer -> Maybe (Closed n m)
+ Closed.Internal: closed :: forall (a :: Nat) (b :: Nat). (KnownNat a, KnownNat b, a <= b) => Integer -> Maybe (Closed a b)
- Closed.Internal: cmp :: forall (n :: Nat) (m :: Nat) (o :: Nat) (p :: Nat). Closed n m -> Closed o p -> Ordering
+ Closed.Internal: cmp :: forall (a :: Nat) (b :: Nat) (o :: Nat) (p :: Nat). Closed a b -> Closed o p -> Ordering
- Closed.Internal: equals :: forall (n :: Nat) (m :: Nat) (o :: Nat) (p :: Nat). Closed n m -> Closed o p -> Bool
+ Closed.Internal: equals :: forall (a :: Nat) (b :: Nat) (o :: Nat) (p :: Nat). Closed a b -> Closed o p -> Bool
- Closed.Internal: isValidClosed :: forall (n :: Nat) (m :: Nat). (KnownNat n, KnownNat m) => Closed n m -> Bool
+ Closed.Internal: isValidClosed :: forall (a :: Nat) (b :: Nat). (KnownNat a, KnownNat b) => Closed a b -> Bool
- Closed.Internal: lowerBound :: forall (n :: Nat) (m :: Nat). Closed n m -> Proxy n
+ Closed.Internal: lowerBound :: forall (a :: Nat) (b :: Nat). Closed a b -> Proxy a
- Closed.Internal: multiply :: forall (n :: Nat) (m :: Nat) (o :: Nat) (p :: Nat). Closed n m -> Closed o p -> Closed (n * o) (m * p)
+ Closed.Internal: multiply :: forall (a :: Nat) (b :: Nat) (o :: Nat) (p :: Nat). Closed a b -> Closed o p -> Closed (a * o) (b * p)
- Closed.Internal: natToClosed :: forall (n :: Nat) (m :: Nat) (x :: Nat) proxy. (n <= x, x <= m, KnownNat x, KnownNat n, KnownNat m) => proxy x -> Closed n m
+ Closed.Internal: natToClosed :: forall (a :: Nat) (b :: Nat) (x :: Nat) proxy. (KnownNat a, KnownNat b, KnownNat x, a <= x, x <= b) => proxy x -> Closed a b
- Closed.Internal: newtype Closed (n :: Nat) (m :: Nat)
+ Closed.Internal: newtype Closed (a :: Nat) (b :: Nat)
- Closed.Internal: strengthenLower :: forall (k :: Nat) (n :: Nat) (m :: Nat). (KnownNat n, KnownNat m, KnownNat k, n <= m, n <= k, k <= m) => Closed n m -> Maybe (Closed k m)
+ Closed.Internal: strengthenLower :: forall (k :: Nat) (a :: Nat) (b :: Nat). (KnownNat a, KnownNat b, KnownNat k, a <= b, a <= k, k <= b) => Closed a b -> Maybe (Closed k b)
- Closed.Internal: strengthenUpper :: forall (k :: Nat) (n :: Nat) (m :: Nat). (KnownNat n, KnownNat m, KnownNat k, n <= m, n <= k, k <= m) => Closed n m -> Maybe (Closed n k)
+ Closed.Internal: strengthenUpper :: forall (k :: Nat) (a :: Nat) (b :: Nat). (KnownNat a, KnownNat b, KnownNat k, a <= b, a <= k, k <= b) => Closed a b -> Maybe (Closed a k)
- Closed.Internal: sub :: forall (n :: Nat) (m :: Nat) (o :: Nat) (p :: Nat). Closed n m -> Closed o p -> Either (Closed (o - n) (p - m)) (Closed (n - o) (m - p))
+ Closed.Internal: sub :: forall (a :: Nat) (b :: Nat) (o :: Nat) (p :: Nat) (n :: Natural) (m :: Natural). Closed a b -> Closed o p -> Either (Closed (o - n) (p - m)) (Closed (n - o) (m - p))
- Closed.Internal: unrepresentable :: forall (n :: Nat) (m :: Nat). (KnownNat n, KnownNat m) => Integer -> Closed n m -> String -> String
+ Closed.Internal: unrepresentable :: forall (a :: Nat) (b :: Nat). (KnownNat a, KnownNat b) => Integer -> Closed a b -> String -> String
- Closed.Internal: unsafeClosed :: forall (n :: Nat) (m :: Nat). (HasCallStack, n <= m, KnownNat n, KnownNat m) => Integer -> Closed n m
+ Closed.Internal: unsafeClosed :: forall (a :: Nat) (b :: Nat). (HasCallStack, KnownNat a, KnownNat b, a <= b) => Integer -> Closed a b
- Closed.Internal: upperBound :: forall (n :: Nat) (m :: Nat). Closed n m -> Proxy m
+ Closed.Internal: upperBound :: forall (a :: Nat) (b :: Nat). Closed a b -> Proxy b
- Closed.Internal: weakenLower :: forall (k :: Nat) (n :: Nat) (m :: Nat). (n <= m, k <= n) => Closed n m -> Closed k m
+ Closed.Internal: weakenLower :: forall (k :: Nat) (a :: Nat) (b :: Nat). (a <= b, k <= a) => Closed a b -> Closed k b
- Closed.Internal: weakenUpper :: forall (k :: Nat) (n :: Nat) (m :: Nat). (n <= m, m <= k) => Closed n m -> Closed n k
+ Closed.Internal: weakenUpper :: forall (k :: Nat) (a :: Nat) (b :: Nat). (a <= b, b <= k) => Closed a b -> Closed a k

Files

README.lhs view
@@ -49,6 +49,7 @@ import qualified Data.Csv as CSV import Test.Hspec import Test.Hspec.QuickCheck+import Text.Read (readEither)  main :: IO () main = hspec $ do@@ -167,6 +168,16 @@ Parsing of closed values is strict.  ```haskell+  describe "Read" $ do++    it "should successfully read values in the specified bounds" $ do+      let result = readEither "1" :: Either String (Bounds (Inclusive 1) (Exclusive 10))+      result `shouldBe` Right 1++    it "should fail to read values outside the specified bounds" $ do+      let result = readEither "0" :: Either String (Bounds (Inclusive 1) (Exclusive 10))+      result `shouldBe` Left "Prelude.read: no parse"+   describe "json" $ do      it "should successfully parse values in the specified bounds" $ do
closed.cabal view
@@ -1,6 +1,6 @@ cabal-version:      1.12 name:               closed-version:            0.2.0.3+version:            0.2.1.0 license:            MIT license-file:       LICENSE maintainer:         Freckle Education <engineering@freckle.com>@@ -35,6 +35,7 @@         deepseq >=1.4.3.0,         hashable >=1.2.7.0,         persistent >=2.8.2,+        random >=1.1,         text >=1.2.3.1  test-suite readme
library/Closed.hs view
@@ -1,5 +1,5 @@ module Closed-  ( Endpoint(..)+  ( Endpoint (..)   , Closed   , Bounds   , Single
library/Closed/Internal.hs view
@@ -32,27 +32,30 @@ import GHC.Generics import GHC.Stack import GHC.TypeLits+import System.Random (Random (..)) import Test.QuickCheck+import Text.ParserCombinators.ReadP (pfail, readP_to_S, readS_to_P) -newtype Closed (n :: Nat) (m :: Nat)-  = Closed { getClosed :: Integer }+newtype Closed (a :: Nat) (b :: Nat) = Closed+  { getClosed :: Integer+  }   deriving (Generic)  -- | Describe whether the endpoint of a 'Bounds' includes -- or excludes its argument data Endpoint-  -- | Endpoint includes its argument-  = Inclusive Nat-  -- | Endpoint excludes its argument-  | Exclusive Nat+  = -- | Endpoint includes its argument+    Inclusive Nat+  | -- | Endpoint excludes its argument+    Exclusive Nat  -- | Syntactic sugar to express open and half-open intervals using -- the 'Closed' type type family Bounds (lhs :: Endpoint) (rhs :: Endpoint) :: Type where-  Bounds (Inclusive n) (Inclusive m) = Closed  n       m-  Bounds (Inclusive n) (Exclusive m) = Closed  n      (m - 1)-  Bounds (Exclusive n) (Inclusive m) = Closed (n + 1)  m-  Bounds (Exclusive n) (Exclusive m) = Closed (n + 1) (m - 1)+  Bounds (Inclusive a) (Inclusive b) = Closed a b+  Bounds (Inclusive a) (Exclusive b) = Closed a (b - 1)+  Bounds (Exclusive a) (Inclusive b) = Closed (a + 1) b+  Bounds (Exclusive a) (Exclusive b) = Closed (a + 1) (b - 1)  -- | Syntactic sugar to express a value that has only one non-bottom -- inhabitant using the 'Closed' type@@ -62,15 +65,19 @@ type FiniteNat (rhs :: Endpoint) = Bounds ('Inclusive 0) rhs  -- | Proxy for the lower bound of a 'Closed' value-lowerBound :: Closed n m -> Proxy n+lowerBound :: Closed a b -> Proxy a lowerBound _ = Proxy  -- | Proxy for the upper bound of a 'Closed' value-upperBound :: Closed n m -> Proxy m+upperBound :: Closed a b -> Proxy b upperBound _ = Proxy  -- | Safely create a 'Closed' value using the specified argument-closed :: forall n m. (n <= m, KnownNat n, KnownNat m) => Integer -> Maybe (Closed n m)+closed+  :: forall a b+   . (KnownNat a, KnownNat b, a <= b)+  => Integer+  -> Maybe (Closed a b) closed x = result  where   extracted = fromJust result@@ -79,7 +86,11 @@     pure $ Closed x  -- | Create a 'Closed' value throwing an error if the argument is not in range-unsafeClosed :: forall n m. (HasCallStack, n <= m, KnownNat n, KnownNat m) => Integer -> Closed n m+unsafeClosed+  :: forall a b+   . (HasCallStack, KnownNat a, KnownNat b, a <= b)+  => Integer+  -> Closed a b unsafeClosed x = result  where   result =@@ -88,22 +99,26 @@       else error $ unrepresentable x result "unsafeClosed"  -- | Clamp an @'Integral'@ in the range constrained by a @'Closed'@ interval-clamp :: forall n m a. (KnownNat n, KnownNat m, n <= m, Integral a) => a -> Closed n m+clamp+  :: forall a b i+   . (Integral i, KnownNat a, KnownNat b, a <= b)+  => i+  -> Closed a b clamp x-  | fromIntegral x < getClosed (minBound @(Closed n m)) = minBound-  | fromIntegral x > getClosed (maxBound @(Closed n m)) = maxBound+  | fromIntegral x < getClosed (minBound @(Closed a b)) = minBound+  | fromIntegral x > getClosed (maxBound @(Closed a b)) = maxBound   | otherwise = Closed (fromIntegral x)  -- | Test equality on 'Closed' values in the same range-instance Eq (Closed n m) where+instance Eq (Closed a b) where   Closed x == Closed y = x == y  -- | Compare 'Closed' values in the same range-instance Ord (Closed n m) where+instance Ord (Closed a b) where   Closed x `compare` Closed y = x `compare` y  -- | Generate the lowest and highest inhabitant of a given 'Closed' type-instance (n <= m, KnownNat n, KnownNat m) => Bounded (Closed n m) where+instance (KnownNat a, KnownNat b, a <= b) => Bounded (Closed a b) where   maxBound = result    where     result = Closed (natVal (upperBound result))@@ -113,20 +128,25 @@     result = Closed (natVal (lowerBound result))  -- | Enumerate values in the range of a given 'Closed' type-instance (n <= m, KnownNat n, KnownNat m) => Enum (Closed n m) where+instance (KnownNat a, KnownNat b, a <= b) => Enum (Closed a b) where   fromEnum = fromEnum . getClosed   toEnum = unsafeClosed . toEnum   enumFrom x = enumFromTo x maxBound   enumFromThen x y = enumFromThenTo x y (if x >= y then minBound else maxBound) -instance Show (Closed n m) where+instance Show (Closed a b) where   showsPrec d (Closed x) = showParen (d > 9) $ showString "unsafeClosed " . showsPrec 10 x +instance (KnownNat a, KnownNat b, a <= b) => Read (Closed a b) where+  readsPrec n = readP_to_S $ do+    i <- readS_to_P $ readsPrec @Integer n+    maybe pfail pure $ closed @a @b i+ -- | Bounded arithmetic, e.g. maxBound + 1 == maxBound-instance (n <= m, KnownNat n, KnownNat m) => Num (Closed n m) where-  Closed x + Closed y = Closed $ min (x + y) (fromIntegral (maxBound :: Closed n m))-  Closed x - Closed y = Closed $ max (x - y) (fromIntegral (minBound :: Closed n m))-  Closed x * Closed y = Closed $ min (x * y) (fromIntegral (maxBound :: Closed n m))+instance (KnownNat a, KnownNat b, a <= b) => Num (Closed a b) where+  Closed x + Closed y = Closed $ min (x + y) (fromIntegral (maxBound :: Closed a b))+  Closed x - Closed y = Closed $ max (x - y) (fromIntegral (minBound :: Closed a b))+  Closed x * Closed y = Closed $ min (x * y) (fromIntegral (maxBound :: Closed a b))   abs = id   signum = const 1   fromInteger x = result@@ -136,73 +156,96 @@         then Closed x         else error $ unrepresentable x result "fromInteger" -instance (n <= m, KnownNat n, KnownNat m) => Real (Closed n m) where+instance (KnownNat a, KnownNat b, a <= b) => Real (Closed a b) where   toRational (Closed x) = x % 1 -instance (n <= m, KnownNat n, KnownNat m) => Integral (Closed n m) where+instance (KnownNat a, KnownNat b, a <= b) => Integral (Closed a b) where   quotRem (Closed x) (Closed y) = (Closed $ x `quot` y, Closed $ x `rem` y)   toInteger (Closed x) = x -instance NFData (Closed n m)+instance NFData (Closed a b) -instance Hashable (Closed n m)+instance (KnownNat a, KnownNat b, a <= b) => Random (Closed a b) where+  randomR (a, b) g =+    let (x, g') = randomR (getClosed a, getClosed b) g+    in  (unsafeClosed x, g')+  random = randomR (minBound, maxBound) -instance ToJSON (Closed n m) where+instance Hashable (Closed a b)++instance ToJSON (Closed a b) where   toEncoding = toEncoding . getClosed   toJSON = toJSON . getClosed -instance (n <= m, KnownNat n, KnownNat m) => FromJSON (Closed n m) where+instance (KnownNat a, KnownNat b, a <= b) => FromJSON (Closed a b) where   parseJSON v = do     x <- parseJSON v     case closed x of       Just cx -> pure cx       n -> fail $ unrepresentable x (fromJust n) "parseJSON" -instance CSV.ToField (Closed n m) where+instance CSV.ToField (Closed a b) where   toField = CSV.toField . getClosed -instance (n <= m, KnownNat n, KnownNat m) => CSV.FromField (Closed n m) where+instance (KnownNat a, KnownNat b, a <= b) => CSV.FromField (Closed a b) where   parseField s = do     x <- CSV.parseField s     case closed x of       Just cx -> pure cx       n -> fail $ unrepresentable x (fromJust n) "parseField" -instance (n <= m, KnownNat n, KnownNat m) => Arbitrary (Closed n m) where+instance (KnownNat a, KnownNat b, a <= b) => Arbitrary (Closed a b) where   arbitrary =-    Closed <$> choose (natVal @n Proxy, natVal @m Proxy)+    Closed <$> choose (natVal @a Proxy, natVal @b Proxy) -instance (n <= m, KnownNat n, KnownNat m) => PersistField (Closed n m) where+instance (KnownNat a, KnownNat b, a <= b) => PersistField (Closed a b) where   toPersistValue = toPersistValue . fromIntegral @Integer @Int . getClosed   fromPersistValue value = do     x <- fromIntegral @Int @Integer <$> fromPersistValue value-    case closed @n @m x of+    case closed @a @b x of       Just cx -> pure cx       n -> Left $ pack $ unrepresentable x (fromJust n) "fromPersistValue" -instance (n <= m, KnownNat n, KnownNat m) => PersistFieldSql (Closed n m) where+instance (KnownNat a, KnownNat b, a <= b) => PersistFieldSql (Closed a b) where   sqlType _ = sqlType (Proxy @Int) -unrepresentable :: (KnownNat n, KnownNat m) => Integer -> Closed n m -> String -> String+unrepresentable+  :: (KnownNat a, KnownNat b)+  => Integer+  -> Closed a b+  -> String+  -> String unrepresentable x cx prefix =-  prefix ++ ": Integer " ++ show x ++-  " is not representable in Closed " ++ show (natVal $ lowerBound cx) ++-  " " ++ show (natVal $ upperBound cx)+  prefix+    <> ": Integer "+    <> show x+    <> " is not representable in Closed "+    <> show (natVal $ lowerBound cx)+    <> " "+    <> show (natVal $ upperBound cx)  -- | Convert a type-level literal into a 'Closed' value-natToClosed :: forall n m x proxy. (n <= x, x <= m, KnownNat x, KnownNat n, KnownNat m) => proxy x -> Closed n m+natToClosed+  :: forall a b x proxy+   . (KnownNat a, KnownNat b, KnownNat x, a <= x, x <= b)+  => proxy x+  -> Closed a b natToClosed p = Closed $ natVal p  -- | Add inhabitants at the end-weakenUpper :: forall k n m. (n <= m, m <= k) => Closed n m -> Closed n k+weakenUpper :: forall k a b. (a <= b, b <= k) => Closed a b -> Closed a k weakenUpper (Closed x) = Closed x  -- | Add inhabitants at the beginning-weakenLower :: forall k n m. (n <= m, k <= n) => Closed n m -> Closed k m+weakenLower :: forall k a b. (a <= b, k <= a) => Closed a b -> Closed k b weakenLower (Closed x) = Closed x  -- | Remove inhabitants from the end. Returns 'Nothing' if the input was removed-strengthenUpper :: forall k n m. (KnownNat n, KnownNat m, KnownNat k, n <= m, n <= k, k <= m) => Closed n m -> Maybe (Closed n k)+strengthenUpper+  :: forall k a b+   . (KnownNat a, KnownNat b, KnownNat k, a <= b, a <= k, k <= b)+  => Closed a b+  -> Maybe (Closed a k) strengthenUpper (Closed x) = result  where   result = do@@ -210,7 +253,11 @@     pure $ Closed x  -- | Remove inhabitants from the beginning. Returns 'Nothing' if the input was removed-strengthenLower :: forall k n m. (KnownNat n, KnownNat m, KnownNat k, n <= m, n <= k, k <= m) => Closed n m -> Maybe (Closed k m)+strengthenLower+  :: forall k a b+   . (KnownNat a, KnownNat b, KnownNat k, a <= b, a <= k, k <= b)+  => Closed a b+  -> Maybe (Closed k b) strengthenLower (Closed x) = result  where   result = do@@ -218,32 +265,36 @@     pure $ Closed x  -- | Test two different types of 'Closed' values for equality.-equals :: Closed n m -> Closed o p -> Bool+equals :: Closed a b -> Closed o p -> Bool equals (Closed x) (Closed y) = x == y+ infix 4 `equals`  -- | Compare two different types of 'Closed' values-cmp :: Closed n m -> Closed o p -> Ordering+cmp :: Closed a b -> Closed o p -> Ordering cmp (Closed x) (Closed y) = x `compare` y  -- | Add two different types of 'Closed' values-add :: Closed n m -> Closed o p -> Closed (n + o) (m + p)+add :: Closed a b -> Closed o p -> Closed (n + o) (m + p) add (Closed x) (Closed y) = Closed $ x + y  -- | Subtract two different types of 'Closed' values -- Returns 'Left' for negative results, and 'Right' for positive results.-sub :: Closed n m -> Closed o p -> Either (Closed (o - n) (p - m)) (Closed (n - o) (m - p))+sub+  :: Closed a b+  -> Closed o p+  -> Either (Closed (o - n) (p - m)) (Closed (n - o) (m - p)) sub (Closed x) (Closed y)   | x >= y = Right $ Closed $ x - y   | otherwise = Left $ Closed $ y - x  -- | Multiply two different types of 'Closed' values-multiply :: Closed n m -> Closed o p -> Closed (n * o) (m * p)+multiply :: Closed a b -> Closed o p -> Closed (a * o) (b * p) multiply (Closed x) (Closed y) = Closed $ x * y  -- | Verifies that a given 'Closed' value is valid. -- Should always return 'True' unles you bring the @Closed.Internal.Closed@ constructor into scope, -- or use 'Unsafe.Coerce.unsafeCoerce' or other nasty hacks-isValidClosed :: (KnownNat n, KnownNat m) => Closed n m -> Bool+isValidClosed :: (KnownNat a, KnownNat b) => Closed a b -> Bool isValidClosed cx@(Closed x) =   natVal (lowerBound cx) <= x && x <= natVal (upperBound cx)