Copyright | (c) 2018-2021 Iris Ward |
---|---|
License | BSD3 |
Maintainer | aditu.venyhandottir@gmail.com |
Stability | experimental |
Safe Haskell | Safe |
Language | Haskell2010 |
This module provides a unified interface for natural numbers, signed integers, and rationals at the type level, in a way fully compatible with existing code using type-level naturals.
Natural numbers are expressed as always, e.g. 5
. Negative integers
are written as Neg 3
. Ratios are written as 3 :% 2
.
There are some naming conflicts between this module and GHC.TypeLits,
notably the comparison and arithmetic operators. This module reexports
Nat
, KnownNat
, natVal
and natVal'
so you may import just this
module and not GHC.TypeLits.
If you wish to use other functionality from GHC.TypeLits, this package also provides the module Data.TypeLits that includes (almost) full functionality from GHC.TypeLits, but with the conflicts resolving in this packages favour.
Synopsis
- data Nat
- class KnownNat (n :: Nat)
- natVal :: forall (n :: Nat) proxy. KnownNat n => proxy n -> Integer
- natVal' :: forall (n :: Nat). KnownNat n => Proxy# n -> Integer
- data SomeNat = KnownNat n => SomeNat (Proxy n)
- someNatVal :: Integer -> Maybe SomeNat
- data TInt
- class KnownInt (n :: k)
- intVal :: forall n proxy. KnownInt n => proxy n -> Integer
- intVal' :: forall n. KnownInt n => Proxy# n -> Integer
- data SomeInt = forall n.KnownInt n => SomeInt (Proxy n)
- someIntVal :: Integer -> SomeInt
- data Rat = forall k. k :% Nat
- class KnownRat r
- ratVal :: forall proxy r. KnownRat r => proxy r -> Rational
- ratVal' :: forall r. KnownRat r => Proxy# r -> Rational
- data SomeRat = forall r.KnownRat r => SomeRat (Proxy r)
- someRatVal :: Rational -> SomeRat
- type family Simplify (x :: Rat) :: Rat where ...
- type family (a :: k1) ==? (b :: k2) :: Bool where ...
- type (/=?) (a :: k1) (b :: k2) = Not (a ==? b)
- type (==) (a :: k1) (b :: k2) = (a ==? b) ~ 'True
- type (/=) (a :: k1) (b :: k2) = (a ==? b) ~ 'False
- type family (a :: k1) <=? (b :: k2) :: Bool where ...
- type (<=) (a :: k1) (b :: k2) = (a <=? b) ~ 'True
- type (<) (a :: k1) (b :: k2) = (b <=? a) ~ 'False
- type (>=) (a :: k1) (b :: k2) = (b <=? a) ~ 'True
- type (>) (a :: k1) (b :: k2) = (a <=? b) ~ 'False
- type family Abs (x :: k) :: k where ...
- type family Negate (x :: k) :: NegK k where ...
- type family Recip (x :: k) :: Rat where ...
- type family Floor (x :: k) :: TInt where ...
- type family Ceiling (x :: k) :: TInt where ...
- type family Truncate (x :: k) :: TInt where ...
- type (+) a b = Add a b
- type (-) a b = Sub a b
- type * a b = Mul a b
- type (/) a b = RatDiv a b
- type (^) a b = Exp a b
- type family DivMod (x :: k) (y :: Nat) :: (IntDivK k, IntDivK k) where ...
- type family QuotRem (x :: k) (y :: Nat) :: (IntDivK k, IntDivK k) where ...
- type family Div (x :: k) (y :: Nat) :: IntDivK k where ...
- type family Mod (x :: k) (y :: Nat) :: IntDivK k where ...
- type family Quot (x :: k) (y :: Nat) :: IntDivK k where ...
- type family Rem (x :: k) (y :: Nat) :: IntDivK k where ...
- type family GCD (x :: k1) (y :: k2) :: Nat where ...
- type family IntLog (n :: Nat) (x :: k) :: TInt where ...
- type Log2 x = IntLog 2 x
Type level numbers
Naturals
(Kind) This is the kind of type-level natural numbers.
This class gives the integer associated with a type-level natural. There are instances of the class for every concrete literal: 0, 1, 2, etc.
Since: base-4.7.0.0
natSing
This type represents unknown type-level natural numbers.
Since: base-4.10.0.0
someNatVal :: Integer -> Maybe SomeNat #
Convert an integer into an unknown type-level natural.
Since: base-4.7.0.0
Integers
(Kind) An integer that may be negative.
class KnownInt (n :: k) Source #
This class gives the (value-level) integer associated with a type-level
integer. There are instances of this class for every concrete natural:
0, 1, 2, etc. There are also instances of this class for every negated
natural, such as
.Neg
1
intSing
Instances
intVal :: forall n proxy. KnownInt n => proxy n -> Integer Source #
Get the value associated with a type-level integer
This type represents unknown type-level integers.
Since: 0.1.1
someIntVal :: Integer -> SomeInt Source #
Convert an integer into an unknown type-level integer.
Since: 0.1.1
Rationals
Type constructor for a rational
This class gives the (value-level) rational associated with a type-level rational. There are instances of this class for every combination of a concrete integer and concrete natural.
ratSing
Instances
KnownInt n => KnownRat (n :: k) Source # | |
Defined in Data.TypeNums.Rats ratSing :: SRat n | |
(KnownInt n, KnownNat d, d /= 0) => KnownRat (n :% d :: Rat) Source # | |
Defined in Data.TypeNums.Rats | |
(TypeError ('Text "Denominator must not equal 0") :: Constraint) => KnownRat (n :% 0 :: Rat) Source # | |
Defined in Data.TypeNums.Rats |
ratVal :: forall proxy r. KnownRat r => proxy r -> Rational Source #
Get the value associated with a type-level rational
This type represents unknown type-level integers.
Since: 0.1.1
someRatVal :: Rational -> SomeRat Source #
Convert a rational into an unknown type-level rational.
Since: 0.1.1
type family Simplify (x :: Rat) :: Rat where ... Source #
Reduce a type-level rational into its canonical form
Since: 0.1.4
Type level numerical operations
Comparisons
type family (a :: k1) ==? (b :: k2) :: Bool where ... infix 4 Source #
Boolean type-level equals. Useful for e.g.
If
(x ==? 0)
(a :: Rat) ==? (b :: Rat) = (==) (Simplify a) (Simplify b) | |
(a :: Nat) ==? ('Pos a) = 'True | |
('Pos a) ==? (a :: Nat) = 'True | |
(a :: Nat) ==? (r :: Rat) = (a :% 1) ==? r | |
(r :: Rat) ==? (a :: Nat) = r ==? (a :% 1) | |
(a :: TInt) ==? (r :: Rat) = (a :% 1) ==? r | |
(r :: Rat) ==? (a :: TInt) = r ==? (a :% 1) | |
(a :: k) ==? (b :: k) = (==) a b | |
_ ==? _ = 'False |
type (==) (a :: k1) (b :: k2) = (a ==? b) ~ 'True infix 4 Source #
Equality constraint, used as e.g. (x == 3) => _
type family (a :: k1) <=? (b :: k2) :: Bool where ... infix 4 Source #
Boolean comparison of two type-level numbers
(a :: Nat) <=? (b :: Nat) = (<=?) a b | |
('Pos a) <=? ('Pos b) = (<=?) a b | |
('Neg _) <=? ('Pos _) = 'True | |
('Pos 0) <=? ('Neg 0) = 'True | |
('Pos _) <=? ('Neg _) = 'False | |
('Pos a) <=? b = a <=? b | |
a <=? ('Pos b) = a <=? b | |
0 <=? ('Neg 0) = 'True | |
(a :: Nat) <=? ('Neg _) = 'False | |
('Neg a) <=? (b :: Nat) = 'True | |
('Neg a) <=? ('Neg b) = (<=?) b a | |
(n :% 0) <=? _ = TypeError ('Text "Denominator must not equal 0") | |
_ <=? (n :% 0) = TypeError ('Text "Denominator must not equal 0") | |
(n1 :% d1) <=? (n2 :% d2) = (n1 * d2) <=? (n2 * d1) | |
a <=? (n :% d) = (a * d) <=? n | |
(n :% d) <=? b = n <=? (b * d) | |
_ <=? _ = TypeError ('Text "Incomparable") |
Arithmetic
Unary Operations
type family Abs (x :: k) :: k where ... Source #
The absolute value of a type-level number
Since: 0.1.4
type family Recip (x :: k) :: Rat where ... Source #
The reciprocal of a type-level number
Since: 0.1.4
type family Floor (x :: k) :: TInt where ... Source #
Round a type-level number towards negative infinity
Since: 0.1.4
type family Ceiling (x :: k) :: TInt where ... Source #
Round a type-level number towards positive infinity
Since: 0.1.4
type family Truncate (x :: k) :: TInt where ... Source #
Round a type-level number towards zero
Since: 0.1.4
Binary Operations
type (-) a b = Sub a b infixl 6 Source #
The difference of two type-level numbers
For the difference of two naturals a
and b
, a-b
is also a natural,
so only exists for a
>= b
.
type * a b = Mul a b infixl 7 Source #
The product of two type-level numbers.
Due to changes in GHC 8.6, using this operator infix and unqualified requires the NoStarIsType language extension to be active. See the GHC 8.6.x migration guide for details: https://ghc.haskell.org/trac/ghc/wiki/Migration/8.6
type (^) a b = Exp a b infixr 8 Source #
A type-level number raised to an integer power. For Nat
powers, the
result kind is the same as the base. For TInt
powers, the result kind
is Rat
.
Since: 0.1.4
type family DivMod (x :: k) (y :: Nat) :: (IntDivK k, IntDivK k) where ... Source #
The quotient and remainder of a type-level integer and a natural number. For a negative dividend, the remainder part is positive such that x = q*y + r @since 0.1.4
type family QuotRem (x :: k) (y :: Nat) :: (IntDivK k, IntDivK k) where ... Source #
The quotient and remainder of a type-level integer and a natural number. For a negative dividend, the remainder part is negative such that x = q*y + r @since 0.1.4
type family Div (x :: k) (y :: Nat) :: IntDivK k where ... infixl 7 Source #
The quotient of a type-level integer and a natural number.
Since: 0.1.4
type family Mod (x :: k) (y :: Nat) :: IntDivK k where ... infixl 7 Source #
The remainder of a type-level integer and a natural number
For a negative number, behaves similarly to mod
.
@since 0.1.4
type family Quot (x :: k) (y :: Nat) :: IntDivK k where ... infixl 7 Source #
The integer part of the result of dividing an integer by a natural number
Since: 0.1.4
type family Rem (x :: k) (y :: Nat) :: IntDivK k where ... infixl 7 Source #
The remainder of the result of dividing an integer by a natural number
Since: 0.1.4
type family GCD (x :: k1) (y :: k2) :: Nat where ... Source #
The greatest common divisor of two type-level integers
Since: 0.1.4
type family IntLog (n :: Nat) (x :: k) :: TInt where ... Source #
The floor of the logarithm of a type-level number
NB. unlike Log2
, Log n 0
here is a type error.
Since: 0.1.4
IntLog 0 _ = TypeError ('Text "Invalid IntLog base: 0") | |
IntLog 1 _ = TypeError ('Text "Invalid IntLog base: 1") | |
IntLog _ 0 = TypeError ('Text "IntLog n 0 is infinite") | |
IntLog _ ('Pos 0) = TypeError ('Text "IntLog n 0 is infinite") | |
IntLog _ ('Neg 0) = TypeError ('Text "IntLog n 0 is infinite") | |
IntLog _ (0 :% _) = TypeError ('Text "IntLog n 0 is infinite") | |
IntLog _ (_ :% 0) = TypeError ('Text "IntLog parameter has zero denominator") | |
IntLog _ ('Neg _) = TypeError ('Text "IntLog of a negative does not exist") | |
IntLog n (x :: Nat) = IntLog n ('Pos x) | |
IntLog n ('Pos x) = IntLogAux n ('Pos x) | |
IntLog n (x :: Rat) = If (Floor x == 'Pos 0) (NegLogFudge n x (Negate (IntLogAux n (Floor (Recip x))))) (IntLog n (Floor x)) |