packages feed

natural-arithmetic 0.1.2.0 → 0.1.3.0

raw patch · 5 files changed

+52/−2 lines, 5 filesdep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Arithmetic.Fin: lift :: Fin# n -> Fin n
+ Arithmetic.Fin: unlift :: Fin n -> Fin# n
+ Arithmetic.Unsafe: [Fin#] :: Int# -> Fin# n
+ Arithmetic.Unsafe: newtype Fin# :: Nat -> TYPE 'IntRep
- Arithmetic.Lt: constant :: forall a b. CmpNat a b ~ 'LT => a < b
+ Arithmetic.Lt: constant :: forall a b. CmpNat a b ~ 'LT => a < b
- Arithmetic.Lte: constant :: forall a b. IsLte (CmpNat a b) ~ 'True => a <= b
+ Arithmetic.Lte: constant :: forall a b. IsLte (CmpNat a b) ~ 'True => a <= b
- Arithmetic.Unsafe: Nat :: Int -> Nat
+ Arithmetic.Unsafe: Nat :: Int -> Nat (n :: Nat)
- Arithmetic.Unsafe: [getNat] :: Nat -> Int
+ Arithmetic.Unsafe: [getNat] :: Nat (n :: Nat) -> Int

Files

CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for natural-arithmetic +## 0.1.3.0 -- 2022-05-23++* Add strict variant of descend.+* Add unboxed Fin type+ ## 0.1.2.0 -- 2019-01-20  * Add strict variant of descend.
natural-arithmetic.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: natural-arithmetic-version: 0.1.2.0+version: 0.1.3.0 synopsis: Arithmetic of natural numbers description:   A search for terms like `arithmetic` and `natural` on hackage reveals@@ -74,7 +74,7 @@     Arithmetic.Types     Arithmetic.Unsafe     Arithmetic.Plus-  build-depends: base>=4.11 && <5+  build-depends: base>=4.14 && <5   hs-source-dirs: src   default-language: Haskell2010   ghc-options: -Wall -O2
src/Arithmetic/Fin.hs view
@@ -3,6 +3,7 @@ {-# language ExplicitNamespaces #-} {-# language GADTs #-} {-# language KindSignatures #-}+{-# language MagicHash #-} {-# language ScopedTypeVariables #-} {-# language TypeApplications #-} {-# language TypeOperators #-}@@ -35,12 +36,16 @@   , absurd     -- * Demote   , demote+    -- * Lift and Unlift+  , lift+  , unlift   ) where  import Prelude hiding (last)  import Arithmetic.Nat ((<?)) import Arithmetic.Types (Fin(..),Difference(..),Nat,type (<), type (<=), type (:=:))+import GHC.Exts (Int(I#)) import GHC.TypeNats (type (+))  import qualified Arithmetic.Lt as Lt@@ -48,20 +53,24 @@ import qualified Arithmetic.Equal as Eq import qualified Arithmetic.Nat as Nat import qualified Arithmetic.Plus as Plus+import qualified Arithmetic.Unsafe as Unsafe  -- | Raise the index by @m@ and weaken the bound by @m@, adding -- @m@ to the right-hand side of @n@. incrementR :: forall n m. Nat m -> Fin n -> Fin (n + m)+{-# inline incrementR #-} incrementR m (Fin i pf) = Fin (Nat.plus i m) (Lt.incrementR @m pf)  -- | Raise the index by @m@ and weaken the bound by @m@, adding -- @m@ to the left-hand side of @n@. incrementL :: forall n m. Nat m -> Fin n -> Fin (m + n)+{-# inline incrementL #-} incrementL m (Fin i pf) = Fin (Nat.plus m i) (Lt.incrementL @m pf)  -- | Weaken the bound by @m@, adding it to the left-hand side of -- the existing bound. This does not change the index. weakenL :: forall n m. Fin n -> Fin (m + n)+{-# inline weakenL #-} weakenL (Fin i pf) = Fin i   ( Lt.substituteR     (Plus.commutative @n @m)@@ -71,15 +80,18 @@ -- | Weaken the bound by @m@, adding it to the right-hand side of -- the existing bound. This does not change the index. weakenR :: forall n m. Fin n -> Fin (n + m)+{-# inline weakenR #-} weakenR (Fin i pf) = Fin i (Lt.plus pf Lte.zero)  -- | Weaken the bound, replacing it by another number greater than -- or equal to itself. This does not change the index. weaken :: forall n m. (n <= m) -> Fin n -> Fin m+{-# inline weaken #-} weaken lt (Fin i pf) = Fin i (Lt.transitiveNonstrictR pf lt)  -- | A finite set of no values is impossible. absurd :: Fin 0 -> void+{-# inline absurd #-} absurd (Fin _ pf) = Lt.absurd pf  -- | Fold over the numbers bounded by @n@ in descending@@ -325,4 +337,13 @@ -- at a boundary where a safe interface meets the unsafe primitives -- on top of which it is built. demote :: Fin n -> Int+{-# inline demote #-} demote (Fin i _) = Nat.demote i++lift :: Unsafe.Fin# n -> Fin n+{-# inline lift #-}+lift (Unsafe.Fin# i) = Fin (Unsafe.Nat (I# i)) Unsafe.Lt++unlift :: Fin n -> Unsafe.Fin# n+{-# inline unlift #-}+unlift (Fin (Unsafe.Nat (I# i)) _) = Unsafe.Fin# i
src/Arithmetic/Nat.hs view
@@ -42,19 +42,23 @@  -- | Infix synonym of 'testLessThan'. (<?) :: Nat a -> Nat b -> Maybe (a < b)+{-# inline (<?) #-} (<?) = testLessThan  -- | Infix synonym of 'testLessThanEqual'. (<=?) :: Nat a -> Nat b -> Maybe (a <= b)+{-# inline (<=?) #-} (<=?) = testLessThanEqual  -- | Infix synonym of 'testEqual'. (=?) :: Nat a -> Nat b -> Maybe (a :=: b)+{-# inline (=?) #-} (=?) = testEqual  -- | Is the first argument strictly less than the second -- argument? testLessThan :: Nat a -> Nat b -> Maybe (a < b)+{-# inline testLessThan #-} testLessThan (Nat x) (Nat y) = if x < y   then Just Lt   else Nothing@@ -62,28 +66,33 @@ -- | Is the first argument less-than-or-equal-to the second -- argument? testLessThanEqual :: Nat a -> Nat b -> Maybe (a <= b)+{-# inline testLessThanEqual #-} testLessThanEqual (Nat x) (Nat y) = if x <= y   then Just Lte   else Nothing  -- | Are the two arguments equal to one another? testEqual :: Nat a -> Nat b -> Maybe (a :=: b)+{-# inline testEqual #-} testEqual (Nat x) (Nat y) = if x == y   then Just Eq   else Nothing  -- | Is zero equal to this number or less than it? testZero :: Nat a -> Either (0 :=: a) (0 < a)+{-# inline testZero #-} testZero (Nat x) = case x of   0 -> Left Eq   _ -> Right Lt  -- | Add two numbers. plus :: Nat a -> Nat b -> Nat (a + b)+{-# inline plus #-} plus (Nat x) (Nat y) = Nat (x + y)  -- | The successor of a number. succ :: Nat a -> Nat (a + 1)+{-# inline succ #-} succ n = plus n one  -- | Subtract the second argument from the first argument.@@ -95,30 +104,36 @@  -- | The number zero. zero :: Nat 0+{-# inline zero #-} zero = Nat 0  -- | The number one. one :: Nat 1+{-# inline one #-} one = Nat 1  -- | The number two. two :: Nat 2+{-# inline two #-} two = Nat 2  -- | The number three. three :: Nat 3+{-# inline three #-} three = Nat 3  -- | Use GHC's built-in type-level arithmetic to create a witness -- of a type-level number. This only reduces if the number is a -- constant. constant :: forall n. KnownNat n => Nat n+{-# inline constant #-} constant = Nat (fromIntegral (natVal' (proxy# :: Proxy# n)))  -- | Extract the 'Int' from a 'Nat'. This is intended to be used -- at a boundary where a safe interface meets the unsafe primitives -- on top of which it is built. demote :: Nat n -> Int+{-# inline demote #-} demote (Nat n) = n  -- | Run a computation on a witness of a type-level number. The@@ -126,4 +141,5 @@ -- not checked. Failure to upload this invariant will lead to a -- segfault. with :: Int -> (forall n. Nat n -> a) -> a+{-# inline with #-} with i f = f (Nat i)
src/Arithmetic/Unsafe.hs view
@@ -4,12 +4,15 @@ {-# language GADTSyntax #-} {-# language GeneralizedNewtypeDeriving #-} {-# language KindSignatures #-}+{-# language MagicHash #-} {-# language RoleAnnotations #-} {-# language StandaloneDeriving #-} {-# language TypeOperators #-}+{-# language UnliftedNewtypes #-}  module Arithmetic.Unsafe   ( Nat(..)+  , Fin#(..)   , type (<)(Lt)   , type (<=)(Lte)   , type (:=:)(Eq)@@ -19,6 +22,7 @@  import Control.Category (Category) import Data.Kind (Type)+import GHC.Exts (Int#,TYPE,RuntimeRep(IntRep))  import qualified Control.Category import qualified GHC.TypeNats as GHC@@ -38,6 +42,10 @@ type role Nat nominal  deriving newtype instance Show (Nat n)++-- | Finite numbers without the overhead of carrying around a proof.+newtype Fin# :: GHC.Nat -> TYPE 'IntRep where+  Fin# :: Int# -> Fin# n  -- | Proof that the first argument is strictly less than the -- second argument.