-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Nat singletons represented by Int -- -- This package implements a type SInt that links a runtime -- Int with a type-level Nat, along with some arithmetic -- and reflection capabilities. -- -- This is useful when mixing type-level Nats with GHC array -- primitives that expect Ints as sizes and indices. -- -- See the module intro of Data.SInt for more details. @package sint @version 0.2.0 -- | Provides a singleton type for a subset of Nats, represented by -- Int. -- -- This is particularly useful when working with length-indexed array -- types, since the array primitives generally expect lengths and indices -- to be Ints. Thus, there's no need to pay the runtime cost of -- lugging around Naturals to handle greater-than-maxInt-length -- arrays, since the underlying primitives don't handle them either. -- -- An SInt n is trusted absolutely by downstream code to -- contain an Int n' s.t. fromIntegral n' == natVal' -- @n Proxy#. In particular, this trust extends to a willingness to -- use two runtime-equal SInts as proof that their type parameters -- are equal, or to use GHC primitives in a way that's only memory-safe -- if this property holds. This means it should be considered -- unsafe to construct an SInt in any way that's not -- statically guaranteed to produce the correct runtime value, and to -- construct one with an incorrect runtime value is equivalent to using -- unsafeCoerce incorrectly. -- -- SInt should be seen as a more efficient implementation of -- data SNat n = KnownNat n => SNat, so that constructing an -- incorrect SInt would be equivalent to producing an incorrect -- KnownNat instance. -- -- SInts are constructed safely by staticSIntVal with no -- overhead, by sintVal with runtime bounds checks based on a -- KnownNat instance, or by various arithmetic functions. module Data.SInt -- | A singleton type linking a runtime Int and a type-level -- Nat. data SInt (n :: Nat) -- | Construct an SInt unsafely. Incorrect uses cause undefined -- behavior. -- -- See the module intro for more details; prefer to use safe methods to -- construct SInts, and treat this constructor equivalently to -- unsafeCoerce. pattern SI# :: Int -> SInt n -- | A unidirectional pattern for safely deconstructing SInts. -- -- This lets us export unSInt as if it were a field selector, -- without making it legal to use in record updates (because this pattern -- is unidirectional). pattern SI :: Int -> SInt n -- | Produce an SInt for a given KnownNat, or Nothing -- if out of range. trySIntVal :: forall n. KnownNat n => Maybe (SInt n) -- | Produce an SInt for a given KnownNat, or error if -- out of range. sintVal :: forall n. (HasCallStack, KnownNat n) => SInt n -- | Bring an SInt back into the type level as a KnownNat -- instance. reifySInt :: forall n r. SInt n -> (KnownNat n => r) -> r -- | Use an Int as an existentially-quantified SInt. withSInt :: HasCallStack => Int -> (forall n. SInt n -> r) -> r -- | Add two SInts with bounds checks; error if the result -- overflows. addSInt :: HasCallStack => SInt m -> SInt n -> SInt (m + n) -- | Subtract two SInts with bounds checks; error if the -- result is negative. subSInt :: HasCallStack => SInt m -> SInt n -> SInt (m - n) -- | Subtract two SInts, using an inequality constraint to rule out -- overflow. subSIntLE :: n <= m => SInt m -> SInt n -> SInt (m - n) -- | "Un-add" an SInt from another SInt, on the left. -- -- This form of subSInt is more convenient in certain cases when a -- type signature ensures a particular SInt is of the form m + -- n. subSIntL :: SInt (m + n) -> SInt m -> SInt n -- | Multiply two SInts with bounds checks; error if the -- result overflows. mulSInt :: HasCallStack => SInt m -> SInt n -> SInt (m * n) -- | "Un-multiply" an SInt by another SInt, on the left. -- -- This form of divSInt is more convenient in certain cases when -- a type signature ensures a particular SInt is of the form m -- * n. divSIntL :: SInt (m * n) -> SInt m -> SInt n -- | "Un-multiply" an SInt by another SInt, on the right. -- -- This form of divSInt is more convenient in certain cases when -- a type signature ensures a particular SInt is of the form m -- * n. divSIntR :: SInt (m * n) -> SInt n -> SInt m -- | Like sintVal, but with static proof that it's in-bounds. -- -- This optimizes down to an actual primitive literal wrapped in the -- appropriate constructors, unlike sintVal, where the bounds -- checking gets in the way. If you're constructing a statically-known -- SInt, use staticSIntVal; while if you're constructing an -- SInt from a runtime KnownNat instance, you'll have to -- use sintVal. staticSIntVal :: forall n. (CmpNat n IntMaxP1 ~ 'LT, KnownNat n) => SInt n -- | One more than the maximum representable Int on the current -- platform. type IntMaxP1 = 2 ^ (64 - 1) instance Data.Portray.Diff.Diff (Data.SInt.SInt n) instance Data.Portray.Portray (Data.SInt.SInt n) instance GHC.Show.Show (Data.SInt.SInt n)