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 +2/−1
- src/Data/Finite.hs +1/−62
- src/Data/Finite/Internal.hs +64/−2
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)