#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ > 708
#endif
module Data.Type.Natural.Definitions
(module Data.Type.Natural.Definitions,
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 710
module Data.Singletons.Prelude
#endif
) where
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
import Data.Singletons.TH (singletons)
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 710
import Data.Singletons.Prelude
import Prelude (Num (..), Ord (..))
#else
import Data.Singletons.Prelude hiding ((:<=), Max, MaxSym0, MaxSym1, MaxSym2,
Min, MinSym0, MinSym1, MinSym2, SOrd (..))
#endif
import Data.Singletons.TH (singletons)
#endif
import Data.Constraint hiding ((:-))
import Data.Type.Monomorphic
import Data.Typeable (Typeable)
import Language.Haskell.TH
import Language.Haskell.TH.Quote
import Prelude (Bool (..), Eq (..), Int,
Integral (..), Ord ((<)), Show (..),
error, id, otherwise, undefined,
($), (.))
import qualified Prelude as P
import Proof.Equational
import Unsafe.Coerce
singletons [d|
data Nat = Z | S Nat
deriving (Show, Eq)
|]
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
deriving instance Typeable 'S
deriving instance Typeable 'Z
#endif
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 710
singletons [d|
min :: Nat -> Nat -> Nat
min Z Z = Z
min Z (S _) = Z
min (S _) Z = Z
min (S m) (S n) = S (min m n)
max :: Nat -> Nat -> Nat
max Z Z = Z
max Z (S n) = S n
max (S n) Z = S n
max (S n) (S m) = S (max n m)
|]
instance P.Ord Nat where
Z <= _ = True
S _ <= Z = False
S n <= S m = n P.<= m
min = min
max = max
#else
singletons [d|
instance P.Ord Nat where
Z <= _ = True
S _ <= Z = False
S n <= S m = n <= m
min Z Z = Z
min Z (S _) = Z
min (S _) Z = Z
min (S m) (S n) = S (min m n)
max Z Z = Z
max Z (S n) = S n
max (S n) Z = S n
max (S n) (S m) = S (max n m)
|]
#endif
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 710
singletons [d|
instance P.Num Nat where
Z + n = n
S m + n = S (m + n)
n Z = n
S n S m = n m
Z S _ = Z
Z * _ = Z
S n * m = n * m + m
abs n = n
signum Z = Z
signum (S n) = S Z
fromInteger n = if n == 0 then Z else S (fromInteger (n1))
|]
#else
singletons [d|
(+) :: Nat -> Nat -> Nat
Z + n = n
S m + n = S (m + n)
() :: Nat -> Nat -> Nat
n Z = n
S n S m = n m
Z S _ = Z
(*) :: Nat -> Nat -> Nat
Z * _ = Z
S n * m = n * m + m
|]
infixl 6 %:-,
infixl 6 %:+, :+
infixl 7 %:*, :*
instance P.Num Nat where
n m = n m
n + m = n + m
n * m = n * m
abs = id
signum Z = Z
signum _ = S Z
fromInteger 0 = Z
fromInteger n | n P.< 0 = error "negative integer"
| otherwise = S $ P.fromInteger (n P.- 1)
#endif
type n :-: m = n :- m
type n :+: m = n :+ m
infixl 6 :-:, :+:
singletons [d|
(**) :: Nat -> Nat -> Nat
n ** Z = S Z
n ** S m = (n ** m) * n
|]
(%+) :: SNat n -> SNat m -> SNat (n :+: m)
(%+) = (%:+)
infixl 6 %+
type n :*: m = n :* m
infixl 7 :*:
(%*) :: SNat n -> SNat m -> SNat (n :*: m)
(%*) = (%:*)
infixl 7 %*
type n :**: m = n :** m
(%**) :: SNat n -> SNat m -> SNat (n :**: m)
(%**) = (%:**)
singletons [d|
zero, one, two, three, four, five, six, seven, eight, nine, ten :: Nat
eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty :: Nat
zero = Z
one = S zero
two = S one
three = S two
four = S three
five = S four
six = S five
seven = S six
eight = S seven
nine = S eight
ten = S nine
eleven = S ten
twelve = S eleven
thirteen = S twelve
fourteen = S thirteen
fifteen = S fourteen
sixteen = S fifteen
seventeen = S sixteen
eighteen = S seventeen
nineteen = S eighteen
twenty = S nineteen
n0, n1, n2, n3, n4, n5, n6, n7, n8, n9 :: Nat
n10, n11, n12, n13, n14, n15, n16, n17 :: Nat
n18, n19, n20 :: Nat
n0 = zero
n1 = one
n2 = two
n3 = three
n4 = four
n5 = five
n6 = six
n7 = seven
n8 = eight
n9 = nine
n10 = ten
n11 = eleven
n12 = twelve
n13 = thirteen
n14 = fourteen
n15 = fifteen
n16 = sixteen
n17 = seventeen
n18 = eighteen
n19 = nineteen
n20 = twenty
|]
singletons [d|
(<<=) :: Nat -> Nat -> Bool
Z <<= _ = True
S _ <<= Z = False
S n <<= S m = n <<= m
|]