symparsec-2.0.0: src/Symparsec/Parser/Natural/Digits.hs
{- | Parse digits from type-level 'Char's.
A 'Nothing' indicates the given 'Char' was not a valid digit for the given base.
raehik copied this directly from his own Symparsec library.
-}
module Symparsec.Parser.Natural.Digits where
import GHC.TypeLits
import DeFun.Core
import Singleraeh.Equality ( testEqElse )
import Singleraeh.Maybe
import Unsafe.Coerce ( unsafeCoerce )
type SParseDigit parseDigit = Lam SChar (SMaybe SNat) parseDigit
class SingParseDigit parseDigit where
singParseDigit :: SParseDigit parseDigit
-- | Parse a binary digit (0 or 1).
type family ParseDigitBin (ch :: Char) :: Maybe Natural where
ParseDigitBin '0' = Just 0
ParseDigitBin '1' = Just 1
ParseDigitBin _ = Nothing
type ParseDigitBinSym :: Char ~> Maybe Natural
data ParseDigitBinSym ch
type instance App ParseDigitBinSym ch = ParseDigitBin ch
sParseDigitBinSym :: SParseDigit ParseDigitBinSym
sParseDigitBinSym = Lam $ \ch ->
testEqElse ch (SChar @'0') (SJust (SNat @0))
$ testEqElse ch (SChar @'1') (SJust (SNat @1))
$ unsafeCoerce SNothing
instance SingParseDigit ParseDigitBinSym where
singParseDigit = sParseDigitBinSym
-- | Parse an octal digit (0-7).
type family ParseDigitOct (ch :: Char) :: Maybe Natural where
ParseDigitOct '0' = Just 0
ParseDigitOct '1' = Just 1
ParseDigitOct '2' = Just 2
ParseDigitOct '3' = Just 3
ParseDigitOct '4' = Just 4
ParseDigitOct '5' = Just 5
ParseDigitOct '6' = Just 6
ParseDigitOct '7' = Just 7
ParseDigitOct _ = Nothing
type ParseDigitOctSym :: Char ~> Maybe Natural
data ParseDigitOctSym ch
type instance App ParseDigitOctSym ch = ParseDigitOct ch
sParseDigitOctSym :: SParseDigit ParseDigitOctSym
sParseDigitOctSym = Lam $ \ch ->
testEqElse ch (SChar @'0') (SJust (SNat @0))
$ testEqElse ch (SChar @'1') (SJust (SNat @1))
$ testEqElse ch (SChar @'2') (SJust (SNat @2))
$ testEqElse ch (SChar @'3') (SJust (SNat @3))
$ testEqElse ch (SChar @'4') (SJust (SNat @4))
$ testEqElse ch (SChar @'5') (SJust (SNat @5))
$ testEqElse ch (SChar @'6') (SJust (SNat @6))
$ testEqElse ch (SChar @'7') (SJust (SNat @7))
$ unsafeCoerce SNothing
instance SingParseDigit ParseDigitOctSym where
singParseDigit = sParseDigitOctSym
-- | Parse a decimal digit (0-9).
type family ParseDigitDec (ch :: Char) :: Maybe Natural where
ParseDigitDec '0' = Just 0
ParseDigitDec '1' = Just 1
ParseDigitDec '2' = Just 2
ParseDigitDec '3' = Just 3
ParseDigitDec '4' = Just 4
ParseDigitDec '5' = Just 5
ParseDigitDec '6' = Just 6
ParseDigitDec '7' = Just 7
ParseDigitDec '8' = Just 8
ParseDigitDec '9' = Just 9
ParseDigitDec _ = Nothing
type ParseDigitDecSym :: Char ~> Maybe Natural
data ParseDigitDecSym ch
type instance App ParseDigitDecSym ch = ParseDigitDec ch
sParseDigitDecSym :: SParseDigit ParseDigitDecSym
sParseDigitDecSym = Lam $ \ch ->
testEqElse ch (SChar @'0') (SJust (SNat @0))
$ testEqElse ch (SChar @'1') (SJust (SNat @1))
$ testEqElse ch (SChar @'2') (SJust (SNat @2))
$ testEqElse ch (SChar @'3') (SJust (SNat @3))
$ testEqElse ch (SChar @'4') (SJust (SNat @4))
$ testEqElse ch (SChar @'5') (SJust (SNat @5))
$ testEqElse ch (SChar @'6') (SJust (SNat @6))
$ testEqElse ch (SChar @'7') (SJust (SNat @7))
$ testEqElse ch (SChar @'8') (SJust (SNat @8))
$ testEqElse ch (SChar @'9') (SJust (SNat @9))
$ unsafeCoerce SNothing
instance SingParseDigit ParseDigitDecSym where
singParseDigit = sParseDigitDecSym
-- | Parse a hexadecimal digit (0-9A-Fa-f).
--
-- Both upper and lower case are permitted.
type family ParseDigitHex (ch :: Char) :: Maybe Natural where
ParseDigitHex '0' = Just 0
ParseDigitHex '1' = Just 1
ParseDigitHex '2' = Just 2
ParseDigitHex '3' = Just 3
ParseDigitHex '4' = Just 4
ParseDigitHex '5' = Just 5
ParseDigitHex '6' = Just 6
ParseDigitHex '7' = Just 7
ParseDigitHex '8' = Just 8
ParseDigitHex '9' = Just 9
ParseDigitHex 'a' = Just 10
ParseDigitHex 'A' = Just 10
ParseDigitHex 'b' = Just 11
ParseDigitHex 'B' = Just 11
ParseDigitHex 'c' = Just 12
ParseDigitHex 'C' = Just 12
ParseDigitHex 'd' = Just 13
ParseDigitHex 'D' = Just 13
ParseDigitHex 'e' = Just 14
ParseDigitHex 'E' = Just 14
ParseDigitHex 'f' = Just 15
ParseDigitHex 'F' = Just 15
ParseDigitHex _ = Nothing
type ParseDigitHexSym :: Char ~> Maybe Natural
data ParseDigitHexSym ch
type instance App ParseDigitHexSym ch = ParseDigitHex ch
sParseDigitHexSym :: SParseDigit ParseDigitHexSym
sParseDigitHexSym = Lam $ \ch ->
testEqElse ch (SChar @'0') (SJust (SNat @0))
$ testEqElse ch (SChar @'1') (SJust (SNat @1))
$ testEqElse ch (SChar @'2') (SJust (SNat @2))
$ testEqElse ch (SChar @'3') (SJust (SNat @3))
$ testEqElse ch (SChar @'4') (SJust (SNat @4))
$ testEqElse ch (SChar @'5') (SJust (SNat @5))
$ testEqElse ch (SChar @'6') (SJust (SNat @6))
$ testEqElse ch (SChar @'7') (SJust (SNat @7))
$ testEqElse ch (SChar @'8') (SJust (SNat @8))
$ testEqElse ch (SChar @'9') (SJust (SNat @9))
$ testEqElse ch (SChar @'a') (SJust (SNat @10))
$ testEqElse ch (SChar @'A') (SJust (SNat @10))
$ testEqElse ch (SChar @'b') (SJust (SNat @11))
$ testEqElse ch (SChar @'B') (SJust (SNat @11))
$ testEqElse ch (SChar @'c') (SJust (SNat @12))
$ testEqElse ch (SChar @'C') (SJust (SNat @12))
$ testEqElse ch (SChar @'d') (SJust (SNat @13))
$ testEqElse ch (SChar @'D') (SJust (SNat @13))
$ testEqElse ch (SChar @'e') (SJust (SNat @14))
$ testEqElse ch (SChar @'E') (SJust (SNat @14))
$ testEqElse ch (SChar @'f') (SJust (SNat @15))
$ testEqElse ch (SChar @'F') (SJust (SNat @15))
$ unsafeCoerce SNothing
instance SingParseDigit ParseDigitHexSym where
singParseDigit = sParseDigitHexSym