packages feed

finite-typelits 0.1.0.0 → 0.1.1.0

raw patch · 3 files changed

+67/−65 lines, 3 filesdep +deepseqPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: deepseq

API changes (from Hackage documentation)

- Data.Finite: instance GHC.Classes.Eq (Data.Finite.Internal.Finite n)
- Data.Finite: instance GHC.Classes.Ord (Data.Finite.Internal.Finite n)
- Data.Finite: instance GHC.Show.Show (Data.Finite.Internal.Finite n)
- Data.Finite: instance GHC.TypeLits.KnownNat n => GHC.Enum.Bounded (Data.Finite.Internal.Finite n)
- Data.Finite: instance GHC.TypeLits.KnownNat n => GHC.Enum.Enum (Data.Finite.Internal.Finite n)
- Data.Finite: instance GHC.TypeLits.KnownNat n => GHC.Num.Num (Data.Finite.Internal.Finite n)
- Data.Finite: instance GHC.TypeLits.KnownNat n => GHC.Real.Integral (Data.Finite.Internal.Finite n)
- Data.Finite: instance GHC.TypeLits.KnownNat n => GHC.Real.Real (Data.Finite.Internal.Finite n)
+ Data.Finite: infix 4 `equals`
+ Data.Finite.Internal: finite :: KnownNat n => Integer -> Finite n
+ Data.Finite.Internal: getFinite :: Finite n -> Integer
+ Data.Finite.Internal: instance Control.DeepSeq.NFData (Data.Finite.Internal.Finite n)
+ Data.Finite.Internal: instance GHC.Classes.Eq (Data.Finite.Internal.Finite n)
+ Data.Finite.Internal: instance GHC.Classes.Ord (Data.Finite.Internal.Finite n)
+ Data.Finite.Internal: instance GHC.Generics.Generic (Data.Finite.Internal.Finite n)
+ Data.Finite.Internal: instance GHC.Show.Show (Data.Finite.Internal.Finite n)
+ Data.Finite.Internal: instance GHC.TypeLits.KnownNat n => GHC.Enum.Bounded (Data.Finite.Internal.Finite n)
+ Data.Finite.Internal: instance GHC.TypeLits.KnownNat n => GHC.Enum.Enum (Data.Finite.Internal.Finite n)
+ Data.Finite.Internal: instance GHC.TypeLits.KnownNat n => GHC.Num.Num (Data.Finite.Internal.Finite n)
+ Data.Finite.Internal: instance GHC.TypeLits.KnownNat n => GHC.Real.Integral (Data.Finite.Internal.Finite n)
+ Data.Finite.Internal: instance GHC.TypeLits.KnownNat n => GHC.Real.Real (Data.Finite.Internal.Finite n)

Files

finite-typelits.cabal view
@@ -1,5 +1,5 @@ name:                finite-typelits-version:             0.1.0.0+version:             0.1.1.0 synopsis:            A type inhabited by finitely many values, indexed by type-level naturals. description:         A type inhabited by finitely many values, indexed by type-level naturals. homepage:            https://github.com/mniip/finite-typelits@@ -14,5 +14,6 @@ library   exposed-modules:     Data.Finite, Data.Finite.Internal   build-depends:       base == 4.*+                     , deepseq >= 1.4   hs-source-dirs:      src   default-language:    Haskell2010
src/Data/Finite.hs view
@@ -27,10 +27,9 @@     where  import Data.Maybe-import Data.Ratio import GHC.TypeLits -import Data.Finite.Internal (Finite(Finite))+import Data.Finite.Internal  -- | Convert an 'Integer' into a 'Finite', returning 'Nothing' if the input is out of bounds. packFinite :: KnownNat n => Integer -> Maybe (Finite n)@@ -44,78 +43,18 @@ packFiniteProxy :: KnownNat n => proxy n -> Integer -> Maybe (Finite n) packFiniteProxy _ = packFinite --- | Convert an 'Integer' into a 'Finite', throwing an error if the input is out of bounds.-finite :: KnownNat n => Integer -> Finite n-finite x = result-    where-        result = if x < natVal result && x >= 0-            then Finite x-            else error $ "finite: Integer " ++ show x ++ " is not representable in Finite " ++ show (natVal result)- -- | Same as 'finite' but with a proxy argument to avoid type signatures. finiteProxy :: KnownNat n => proxy n -> Integer -> Finite n finiteProxy _ = finite --- | Convert a 'Finite' into the corresponding 'Integer'.-getFinite :: Finite n -> Integer-getFinite (Finite x) = x--instance Eq (Finite n) where-    Finite x == Finite y = x == y- -- | Test two different types of finite numbers for equality. equals :: Finite n -> Finite m -> Bool equals (Finite x) (Finite y) = x == y infix 4 `equals` -instance Ord (Finite n) where-    Finite x `compare` Finite y = x `compare` y- -- | Compare two different types of finite numbers. cmp :: Finite n -> Finite m -> Ordering cmp (Finite x) (Finite y) = x `compare` y---- | Throws an error for @'Finite' 0@-instance KnownNat n => Bounded (Finite n) where-    maxBound = result-        where-            result = if natVal result > 0-                then Finite $ natVal result - 1-                else error "maxBound: Finite 0 is uninhabited"-    minBound = result-        where-            result = if natVal result > 0-                then Finite 0-                else error "minBound: Finite 0 is uninhabited"--instance KnownNat n => Enum (Finite n) where-    fromEnum = fromEnum . getFinite-    toEnum = finite . toEnum-    enumFrom x = enumFromTo x maxBound-    enumFromThen x y = enumFromThenTo x y (if x >= y then minBound else maxBound)--instance Show (Finite n) where-    showsPrec d (Finite x) = showParen (d > 9) $ showString "finite " . showsPrec 10 x---- | Modulo arithmetic. Only the 'fromInteger' function is supposed to be useful.-instance KnownNat n => Num (Finite n) where-    fx@(Finite x) + Finite y = Finite $ (x + y) `mod` natVal fx-    fx@(Finite x) - Finite y = Finite $ (x - y) `mod` natVal fx-    fx@(Finite x) * Finite y = Finite $ (x * y) `mod` natVal fx-    abs fx = fx-    signum _ = fromInteger 1-    fromInteger x = result-        where-            result = if x < natVal result && x >= 0-                then Finite x-                else error $ "fromInteger: Integer " ++ show x ++ " is not representable in Finite " ++ show (natVal result)--instance KnownNat n => Real (Finite n) where-    toRational (Finite x) = x % 1--instance KnownNat n => Integral (Finite n) where-    quotRem (Finite x) (Finite y) = (Finite $ x `quot` y, Finite $ x `rem` y)-    toInteger (Finite x) = x  -- | Convert a type-level literal into a 'Finite'. natToFinite :: (KnownNat n, KnownNat m, n + 1 <= m) => proxy n -> Finite m
src/Data/Finite/Internal.hs view
@@ -7,17 +7,79 @@ -- Stability   :  experimental -- Portability :  portable ---------------------------------------------------------------------------------{-# LANGUAGE KindSignatures, DataKinds #-}+{-# LANGUAGE KindSignatures, DataKinds, DeriveGeneric #-} module Data.Finite.Internal     (-        Finite(Finite)+        Finite(Finite),+        finite,+        getFinite     )     where  import GHC.TypeLits+import GHC.Generics+import Control.DeepSeq+import Data.Ratio  -- | Finite number type. @'Finite' n@ is inhabited by exactly @n@ values. Invariants: -- -- prop> getFinite x < natVal x -- prop> getFinite x >= 0 newtype Finite (n :: Nat) = Finite Integer+                          deriving (Eq, Ord, Generic)++-- | Convert an 'Integer' into a 'Finite', throwing an error if the input is out of bounds.+finite :: KnownNat n => Integer -> Finite n+finite x = result+    where+        result = if x < natVal result && x >= 0+            then Finite x+            else error $ "finite: Integer " ++ show x ++ " is not representable in Finite " ++ show (natVal result)++-- | Convert a 'Finite' into the corresponding 'Integer'.+getFinite :: Finite n -> Integer+getFinite (Finite x) = x++-- | Throws an error for @'Finite' 0@+instance KnownNat n => Bounded (Finite n) where+    maxBound = result+        where+            result = if natVal result > 0+                then Finite $ natVal result - 1+                else error "maxBound: Finite 0 is uninhabited"+    minBound = result+        where+            result = if natVal result > 0+                then Finite 0+                else error "minBound: Finite 0 is uninhabited"++instance KnownNat n => Enum (Finite n) where+    fromEnum = fromEnum . getFinite+    toEnum = finite . toEnum+    enumFrom x = enumFromTo x maxBound+    enumFromThen x y = enumFromThenTo x y (if x >= y then minBound else maxBound)++instance Show (Finite n) where+    showsPrec d (Finite x) = showParen (d > 9) $ showString "finite " . showsPrec 10 x++-- | Modulo arithmetic. Only the 'fromInteger' function is supposed to be useful.+instance KnownNat n => Num (Finite n) where+    fx@(Finite x) + Finite y = Finite $ (x + y) `mod` natVal fx+    fx@(Finite x) - Finite y = Finite $ (x - y) `mod` natVal fx+    fx@(Finite x) * Finite y = Finite $ (x * y) `mod` natVal fx+    abs fx = fx+    signum _ = fromInteger 1+    fromInteger x = result+        where+            result = if x < natVal result && x >= 0+                then Finite x+                else error $ "fromInteger: Integer " ++ show x ++ " is not representable in Finite " ++ show (natVal result)++instance KnownNat n => Real (Finite n) where+    toRational (Finite x) = x % 1++instance KnownNat n => Integral (Finite n) where+    quotRem (Finite x) (Finite y) = (Finite $ x `quot` y, Finite $ x `rem` y)+    toInteger (Finite x) = x++instance NFData (Finite n)