packages feed

ascii-numbers 1.0.0.0 → 1.1.0.0

raw patch · 5 files changed

+221/−158 lines, 5 filesdep −d10dep ~basedep ~hedgehogdep ~textPVP ok

version bump matches the API change (PVP)

Dependencies removed: d10

Dependency ranges changed: base, hedgehog, text

API changes (from Hackage documentation)

- ASCII.Decimal: D0 :: D10
- ASCII.Decimal: D1 :: D10
- ASCII.Decimal: D2 :: D10
- ASCII.Decimal: D3 :: D10
- ASCII.Decimal: D4 :: D10
- ASCII.Decimal: D5 :: D10
- ASCII.Decimal: D6 :: D10
- ASCII.Decimal: D7 :: D10
- ASCII.Decimal: D8 :: D10
- ASCII.Decimal: D9 :: D10
- ASCII.Decimal: data D10
- ASCII.Decimal: instance ASCII.Decimal.DigitStringSuperset [D10.Safe.Type.D10]
- ASCII.Decimal: instance ASCII.Decimal.DigitSuperset D10.Safe.Type.D10
- ASCII.Hexadecimal: D0 :: D16
- ASCII.Hexadecimal: D1 :: D16
- ASCII.Hexadecimal: D10 :: D16
- ASCII.Hexadecimal: D11 :: D16
- ASCII.Hexadecimal: D12 :: D16
- ASCII.Hexadecimal: D13 :: D16
- ASCII.Hexadecimal: D14 :: D16
- ASCII.Hexadecimal: D15 :: D16
- ASCII.Hexadecimal: D2 :: D16
- ASCII.Hexadecimal: D3 :: D16
- ASCII.Hexadecimal: D4 :: D16
- ASCII.Hexadecimal: D5 :: D16
- ASCII.Hexadecimal: D6 :: D16
- ASCII.Hexadecimal: D7 :: D16
- ASCII.Hexadecimal: D8 :: D16
- ASCII.Hexadecimal: D9 :: D16
- ASCII.Hexadecimal: data D16
- ASCII.Hexadecimal: instance Data.Data.Data ASCII.Hexadecimal.D16
- ASCII.Hexadecimal: instance Data.Hashable.Class.Hashable ASCII.Hexadecimal.D16
- ASCII.Hexadecimal: instance GHC.Classes.Eq ASCII.Hexadecimal.D16
- ASCII.Hexadecimal: instance GHC.Classes.Ord ASCII.Hexadecimal.D16
- ASCII.Hexadecimal: instance GHC.Enum.Bounded ASCII.Hexadecimal.D16
- ASCII.Hexadecimal: instance GHC.Enum.Enum ASCII.Hexadecimal.D16
- ASCII.Hexadecimal: instance GHC.Generics.Generic ASCII.Hexadecimal.D16
- ASCII.Hexadecimal: instance GHC.Show.Show ASCII.Hexadecimal.D16
+ ASCII.Decimal: Digit0 :: Digit
+ ASCII.Decimal: Digit1 :: Digit
+ ASCII.Decimal: Digit2 :: Digit
+ ASCII.Decimal: Digit3 :: Digit
+ ASCII.Decimal: Digit4 :: Digit
+ ASCII.Decimal: Digit5 :: Digit
+ ASCII.Decimal: Digit6 :: Digit
+ ASCII.Decimal: Digit7 :: Digit
+ ASCII.Decimal: Digit8 :: Digit
+ ASCII.Decimal: Digit9 :: Digit
+ ASCII.Decimal: data Digit
+ ASCII.Decimal: instance ASCII.Decimal.DigitStringSuperset [ASCII.Decimal.Digit]
+ ASCII.Decimal: instance ASCII.Decimal.DigitStringSuperset string => ASCII.Lift.Lift [ASCII.Decimal.Digit] string
+ ASCII.Decimal: instance ASCII.Decimal.DigitSuperset ASCII.Decimal.Digit
+ ASCII.Decimal: instance ASCII.Decimal.DigitSuperset char => ASCII.Lift.Lift ASCII.Decimal.Digit char
+ ASCII.Decimal: instance Data.Data.Data ASCII.Decimal.Digit
+ ASCII.Decimal: instance Data.Hashable.Class.Hashable ASCII.Decimal.Digit
+ ASCII.Decimal: instance GHC.Classes.Eq ASCII.Decimal.Digit
+ ASCII.Decimal: instance GHC.Classes.Ord ASCII.Decimal.Digit
+ ASCII.Decimal: instance GHC.Enum.Bounded ASCII.Decimal.Digit
+ ASCII.Decimal: instance GHC.Enum.Enum ASCII.Decimal.Digit
+ ASCII.Decimal: instance GHC.Generics.Generic ASCII.Decimal.Digit
+ ASCII.Decimal: instance GHC.Show.Show ASCII.Decimal.Digit
+ ASCII.Hexadecimal: instance ASCII.Hexadecimal.HexCharSuperset char => ASCII.Lift.Lift ASCII.Hexadecimal.HexChar char
+ ASCII.Hexadecimal: instance ASCII.Hexadecimal.HexStringSuperset string => ASCII.Lift.Lift [ASCII.Hexadecimal.HexChar] string
+ ASCII.Word4: Number0 :: Word4
+ ASCII.Word4: Number1 :: Word4
+ ASCII.Word4: Number10 :: Word4
+ ASCII.Word4: Number11 :: Word4
+ ASCII.Word4: Number12 :: Word4
+ ASCII.Word4: Number13 :: Word4
+ ASCII.Word4: Number14 :: Word4
+ ASCII.Word4: Number15 :: Word4
+ ASCII.Word4: Number2 :: Word4
+ ASCII.Word4: Number3 :: Word4
+ ASCII.Word4: Number4 :: Word4
+ ASCII.Word4: Number5 :: Word4
+ ASCII.Word4: Number6 :: Word4
+ ASCII.Word4: Number7 :: Word4
+ ASCII.Word4: Number8 :: Word4
+ ASCII.Word4: Number9 :: Word4
+ ASCII.Word4: data Word4
+ ASCII.Word4: instance Data.Data.Data ASCII.Word4.Word4
+ ASCII.Word4: instance Data.Hashable.Class.Hashable ASCII.Word4.Word4
+ ASCII.Word4: instance GHC.Classes.Eq ASCII.Word4.Word4
+ ASCII.Word4: instance GHC.Classes.Ord ASCII.Word4.Word4
+ ASCII.Word4: instance GHC.Enum.Bounded ASCII.Word4.Word4
+ ASCII.Word4: instance GHC.Enum.Enum ASCII.Word4.Word4
+ ASCII.Word4: instance GHC.Generics.Generic ASCII.Word4.Word4
+ ASCII.Word4: instance GHC.Show.Show ASCII.Word4.Word4
- ASCII.Decimal: digitInteger :: D10 -> Integer
+ ASCII.Decimal: digitInteger :: Digit -> Integer
- ASCII.Decimal: digitNatural :: D10 -> Natural
+ ASCII.Decimal: digitNatural :: Digit -> Natural
- ASCII.Decimal: fromDigit :: DigitSuperset char => D10 -> char
+ ASCII.Decimal: fromDigit :: DigitSuperset char => Digit -> char
- ASCII.Decimal: fromDigitList :: DigitStringSuperset string => [D10] -> string
+ ASCII.Decimal: fromDigitList :: DigitStringSuperset string => [Digit] -> string
- ASCII.Decimal: integerDigitMaybe :: Integer -> Maybe D10
+ ASCII.Decimal: integerDigitMaybe :: Integer -> Maybe Digit
- ASCII.Decimal: naturalDigitMaybe :: Natural -> Maybe D10
+ ASCII.Decimal: naturalDigitMaybe :: Natural -> Maybe Digit
- ASCII.Decimal: toDigitListMaybe :: DigitStringSuperset string => string -> Maybe [D10]
+ ASCII.Decimal: toDigitListMaybe :: DigitStringSuperset string => string -> Maybe [Digit]
- ASCII.Decimal: toDigitListUnsafe :: DigitStringSuperset string => string -> [D10]
+ ASCII.Decimal: toDigitListUnsafe :: DigitStringSuperset string => string -> [Digit]
- ASCII.Decimal: toDigitMaybe :: DigitSuperset char => char -> Maybe D10
+ ASCII.Decimal: toDigitMaybe :: DigitSuperset char => char -> Maybe Digit
- ASCII.Decimal: toDigitUnsafe :: DigitSuperset char => char -> D10
+ ASCII.Decimal: toDigitUnsafe :: DigitSuperset char => char -> Digit
- ASCII.Hexadecimal: HexDigit :: D10 -> HexCharBreakdown
+ ASCII.Hexadecimal: HexDigit :: Digit -> HexCharBreakdown
- ASCII.Hexadecimal: d16HexChar :: Case -> D16 -> HexChar
+ ASCII.Hexadecimal: d16HexChar :: Case -> Word4 -> HexChar
- ASCII.Hexadecimal: d16HexLetter :: D16 -> Maybe HexLetter
+ ASCII.Hexadecimal: d16HexLetter :: Word4 -> Maybe HexLetter
- ASCII.Hexadecimal: d16Integer :: D16 -> Integer
+ ASCII.Hexadecimal: d16Integer :: Word4 -> Integer
- ASCII.Hexadecimal: d16Natural :: D16 -> Natural
+ ASCII.Hexadecimal: d16Natural :: Word4 -> Natural
- ASCII.Hexadecimal: hexCharD16 :: HexChar -> D16
+ ASCII.Hexadecimal: hexCharD16 :: HexChar -> Word4
- ASCII.Hexadecimal: hexLetterD16 :: HexLetter -> D16
+ ASCII.Hexadecimal: hexLetterD16 :: HexLetter -> Word4
- ASCII.Hexadecimal: integerD16Maybe :: Integer -> Maybe D16
+ ASCII.Hexadecimal: integerD16Maybe :: Integer -> Maybe Word4
- ASCII.Hexadecimal: integerD16Unsafe :: Integer -> D16
+ ASCII.Hexadecimal: integerD16Unsafe :: Integer -> Word4
- ASCII.Hexadecimal: naturalD16Maybe :: Natural -> Maybe D16
+ ASCII.Hexadecimal: naturalD16Maybe :: Natural -> Maybe Word4
- ASCII.Hexadecimal: naturalD16Unsafe :: Natural -> D16
+ ASCII.Hexadecimal: naturalD16Unsafe :: Natural -> Word4

Files

ascii-numbers.cabal view
@@ -1,7 +1,7 @@ cabal-version: 3.0  name: ascii-numbers-version: 1.0.0.0+version: 1.1.0.0 synopsis: ASCII representations of numbers category: Data, Numeric, Text @@ -35,6 +35,7 @@         DerivingStrategies         FlexibleInstances         LambdaCase+        MultiParamTypeClasses         NoImplicitPrelude         StandaloneDeriving @@ -44,7 +45,6 @@       , ascii-superset ^>= 1.0.1       , base >= 4.13 && < 4.17       , bytestring ^>= 0.10 || ^>= 0.11-      , d10 ^>= 1.0.1       , hashable >= 1.3 && < 1.5       , text ^>= 1.2.4 @@ -55,6 +55,7 @@     exposed-modules:         ASCII.Decimal       , ASCII.Hexadecimal+      , ASCII.Word4      other-modules:         DList
library/ASCII/Decimal.hs view
@@ -5,7 +5,7 @@     {- ** Integer -} showInteger, readInteger,     {- ** Integral -} showIntegral, readIntegral, -    {- * The digit type -} D10 (..),+    {- * The digit type -} Digit (..),      {- * Decimal digit superset classes -}     {- ** Of digit -} DigitSuperset (..),@@ -18,24 +18,32 @@     ) where  import qualified ASCII.Char as ASCII-import ASCII.Refinement (ASCII, asciiUnsafe, lift)+import qualified ASCII.Refinement+import ASCII.Lift (Lift (lift))+import ASCII.Refinement (ASCII, asciiUnsafe) import ASCII.Superset (StringSuperset, fromChar, fromCharList, toCharListMaybe,                        toCharMaybe)  import Control.Monad ((<=<), (=<<)) import Data.Bifoldable (bifoldMap) import Data.Bits (Bits, toIntegralSized)-import Data.Bool (Bool, (&&))+import Data.Bool (Bool, (&&), (||))+import Data.Data (Data)+import Data.Eq (Eq) import Data.Function (id, (.)) import Data.Functor (fmap)+import Data.Hashable (Hashable) import Data.List.NonEmpty (NonEmpty, nonEmpty) import Data.Maybe (Maybe (..), fromJust, isJust) import Data.Monoid (mempty) import Data.Ord (Ord (..)) import Data.Word (Word8)+import GHC.Generics (Generic) import Numeric.Natural (Natural)-import Prelude (Integer, Integral, abs, fromEnum, fromInteger, fromIntegral,-                negate, quotRem, toEnum, toInteger, (*), (+), (-))+import Prelude (Bounded (..), Enum (..), Integer, Integral, abs, fromEnum,+                fromInteger, fromIntegral, negate, quotRem, toEnum, toInteger,+                (*), (+), (-))+import Text.Show (Show)  import qualified Data.Bool as Bool import qualified Data.Char as Unicode@@ -52,10 +60,28 @@ import DList (DList) import qualified DList -import D10.Safe (D10 (..))-import qualified D10.Safe as D10+{- | +The subset of ASCII used to represent unsigned decimal numbers: +* 'ASCII.Char.Digit0' to 'ASCII.Char.Digit9'++-}+data Digit+    = Digit0  -- ^ Zero+    | Digit1  -- ^ One+    | Digit2  -- ^ Two+    | Digit3  -- ^ Three+    | Digit4  -- ^ Four+    | Digit5  -- ^ Five+    | Digit6  -- ^ Six+    | Digit7  -- ^ Seven+    | Digit8  -- ^ Eight+    | Digit9  -- ^ Nine+    deriving stock (Bounded, Enum, Eq, Ord, Show, Data, Generic)+    deriving anyclass Hashable++ ---  Show functions  ---  {- |@@ -69,13 +95,13 @@ showNatural :: DigitStringSuperset string => Natural -> string showNatural =     \case-        0 -> fromDigitList [ D0 ]+        0 -> fromDigitList [ Digit0 ]         n -> fromDigitList (naturalList n)   where-    naturalList :: Natural -> [D10]+    naturalList :: Natural -> [Digit]     naturalList = DList.toList . r       where-        r :: Natural -> DList D10+        r :: Natural -> DList Digit         r = \case             0 -> mempty             n ->@@ -136,7 +162,7 @@ readNatural :: DigitStringSuperset string => string -> Maybe Natural readNatural = (Just . readNaturalDigits) <=< nonEmpty <=< toDigitListMaybe   where-    readNaturalDigits :: NonEmpty D10 -> Natural+    readNaturalDigits :: NonEmpty Digit -> Natural     readNaturalDigits = List.foldl' (\total x -> (10 * total) + fromIntegral (fromEnum x)) 0  {- |@@ -163,7 +189,7 @@     readNonNegative :: [ASCII.Char] -> Maybe Integer     readNonNegative = (Just . toInteger . readIntegerDigits) <=< nonEmpty <=< toDigitListMaybe -    readIntegerDigits :: NonEmpty D10 -> Integer+    readIntegerDigits :: NonEmpty Digit -> Integer     readIntegerDigits = List.foldl' (\total x -> (10 * total) + fromIntegral (fromEnum x)) 0  {- |@@ -193,8 +219,8 @@ * @naturalDigitMaybe 12@ = @Nothing@  -}-naturalDigitMaybe :: Natural -> Maybe D10-naturalDigitMaybe = D10.natD10Maybe+naturalDigitMaybe :: Natural -> Maybe Digit+naturalDigitMaybe n = if n > 9 then Nothing else Just (toEnum (fromIntegral n))  {- | @@ -204,30 +230,41 @@ * @integerDigitMaybe 12@ = @Nothing@  -}-integerDigitMaybe :: Integer -> Maybe D10-integerDigitMaybe = D10.integerD10Maybe+integerDigitMaybe :: Integer -> Maybe Digit+integerDigitMaybe n = if (n < 0 || n > 9) then Nothing else Just (toEnum (fromInteger n)) -digitNatural :: D10 -> Natural-digitNatural = D10.d10Nat+digitNatural :: Digit -> Natural+digitNatural = fromIntegral . fromEnum -digitInteger :: D10 -> Integer-digitInteger = D10.d10Integer+digitInteger :: Digit -> Integer+digitInteger = fromIntegral . fromEnum  +---  Lift instances  ---++instance DigitSuperset char => Lift Digit char+  where+    lift = fromDigit++instance DigitStringSuperset string => Lift [Digit] string+  where+    lift = fromDigitList++ ---  Classes  ---  class DigitSuperset char   where -    fromDigit :: D10 -> char+    fromDigit :: Digit -> char      isDigit :: char -> Bool     isDigit = isJust . toDigitMaybe -    toDigitUnsafe :: char -> D10+    toDigitUnsafe :: char -> Digit     toDigitUnsafe = fromJust . toDigitMaybe -    toDigitMaybe :: char -> Maybe D10+    toDigitMaybe :: char -> Maybe Digit     toDigitMaybe x = if isDigit x then Just (toDigitUnsafe x) else Nothing      {-# minimal fromDigit, ((isDigit, toDigitUnsafe) | toDigitMaybe) #-}@@ -235,15 +272,15 @@ class DigitStringSuperset string   where -    fromDigitList :: [D10] -> string+    fromDigitList :: [Digit] -> string      isDigitString :: string -> Bool     isDigitString = isJust . toDigitListMaybe -    toDigitListUnsafe :: string -> [D10]+    toDigitListUnsafe :: string -> [Digit]     toDigitListUnsafe = fromJust . toDigitListMaybe -    toDigitListMaybe :: string -> Maybe [D10]+    toDigitListMaybe :: string -> Maybe [Digit]     toDigitListMaybe x = if isDigitString x then Just (toDigitListUnsafe x) else Nothing      {-# minimal fromDigitList, ((isDigitString, toDigitListUnsafe) | toDigitListMaybe) #-}@@ -251,7 +288,7 @@  ---  DigitSuperset instances  --- -instance DigitSuperset D10+instance DigitSuperset Digit   where     isDigit _ = Bool.True     fromDigit = id@@ -277,15 +314,15 @@  instance DigitSuperset char => DigitSuperset (ASCII char)   where-    isDigit = isDigit . lift+    isDigit = isDigit . ASCII.Refinement.lift     fromDigit = asciiUnsafe . fromDigit-    toDigitUnsafe = toDigitUnsafe . lift-    toDigitMaybe = toDigitMaybe . lift+    toDigitUnsafe = toDigitUnsafe . ASCII.Refinement.lift+    toDigitMaybe = toDigitMaybe . ASCII.Refinement.lift   ---  DigitStringSuperset instances  --- -instance DigitStringSuperset [D10]+instance DigitStringSuperset [Digit]   where     isDigitString _ = Bool.True     fromDigitList = id@@ -340,7 +377,7 @@  instance DigitStringSuperset char => DigitStringSuperset (ASCII char)   where-    isDigitString = isDigitString . lift+    isDigitString = isDigitString . ASCII.Refinement.lift     fromDigitList = asciiUnsafe . fromDigitList-    toDigitListUnsafe = toDigitListUnsafe . lift-    toDigitListMaybe = toDigitListMaybe . lift+    toDigitListUnsafe = toDigitListUnsafe . ASCII.Refinement.lift+    toDigitListMaybe = toDigitListMaybe . ASCII.Refinement.lift
library/ASCII/Hexadecimal.hs view
@@ -5,7 +5,7 @@     {- ** Integer  -} showInteger,  readInteger,     {- ** Integral -} showIntegral, readIntegral, -    {- * Various digit types -} D16 (..), HexChar (..), HexLetter (..), HexCharBreakdown (..),+    {- * Various digit types -} HexChar (..), HexLetter (..), HexCharBreakdown (..),      {- * Monomorphic character conversions -}     {- ** HexLetter ↔ D16              -} hexLetterD16, d16HexLetter,@@ -29,9 +29,12 @@ import ASCII.Case (Case (..)) import qualified ASCII.Char as ASCII import qualified ASCII.Decimal as Dec+import ASCII.Lift (Lift (lift)) import ASCII.Refinement (ASCII, asciiUnsafe, lift) import ASCII.Superset (StringSuperset, fromChar, fromCharList, toCharListMaybe,                        toCharMaybe)+import ASCII.Word4 (Word4)+import qualified ASCII.Word4 as Word4  import Control.Monad (guard, (<=<), (=<<)) import Data.Bifoldable (bifoldMap)@@ -71,27 +74,6 @@  ---  Types  --- --- | A whole number between /0/ and /15/-data D16-    = D0  -- ^ Zero-    | D1  -- ^ One-    | D2  -- ^ Two-    | D3  -- ^ Three-    | D4  -- ^ Four-    | D5  -- ^ Five-    | D6  -- ^ Six-    | D7  -- ^ Seven-    | D8  -- ^ Eight-    | D9  -- ^ Nine-    | D10 -- ^ Ten      (A)-    | D11 -- ^ Eleven   (B)-    | D12 -- ^ Twelve   (C)-    | D13 -- ^ Thirteen (D)-    | D14 -- ^ Fourteen (E)-    | D15 -- ^ Fifteen  (F)-    deriving stock (Bounded, Enum, Eq, Ord, Show, Data, Generic)-    deriving anyclass Hashable- -- | Letters used as hexadecimal digits above 9, without a notion of case. data HexLetter =     LetterA -- ^ 10@@ -119,7 +101,7 @@     deriving stock (Bounded, Enum, Eq, Ord, Show, Data, Generic)     deriving anyclass Hashable -data HexCharBreakdown = HexDigit Dec.D10 | HexLetter Case HexLetter+data HexCharBreakdown = HexDigit Dec.Digit | HexLetter Case HexLetter     deriving stock (Eq, Ord, Show, Data, Generic)     deriving anyclass Hashable @@ -152,17 +134,17 @@         HexLetter UpperCase x  ->  toEnum (fromEnum x + 10)         HexLetter LowerCase x  ->  toEnum (fromEnum x + 16) -d16HexChar :: Case -> D16 -> HexChar+d16HexChar :: Case -> Word4 -> HexChar d16HexChar c =     toEnum     .     case c of         UpperCase -> fromEnum         LowerCase -> \case-            x | x <= D9  ->  fromEnum x-            x            ->  fromEnum x + 6+            x | x <= Word4.Number9  ->  fromEnum x+            x                       ->  fromEnum x + 6 -hexCharD16 :: HexChar -> D16+hexCharD16 :: HexChar -> Word4 hexCharD16 =     \case         x | x < SmallLetterA  ->  toEnum (fromEnum x)@@ -194,13 +176,13 @@          _ -> Nothing -hexLetterD16 :: HexLetter -> D16+hexLetterD16 :: HexLetter -> Word4 hexLetterD16 = toEnum . (\x -> x + 10) . fromEnum -d16HexLetter :: D16 -> Maybe HexLetter+d16HexLetter :: Word4 -> Maybe HexLetter d16HexLetter x =   do-    guard (x >= D10)+    guard (x >= Word4.Number10)     Just (toEnum (fromEnum x - 10))  letterHexChar :: Case -> HexLetter -> HexChar@@ -277,32 +259,44 @@     .     fromEnum -naturalD16Maybe :: Natural -> Maybe D16+naturalD16Maybe :: Natural -> Maybe Word4 naturalD16Maybe =     \case         x | x <= 15  ->  Just (toEnum (fromIntegral x))         _            ->  Nothing -d16Natural :: D16 -> Natural+d16Natural :: Word4 -> Natural d16Natural = fromIntegral . fromEnum -integerD16Maybe :: Integer -> Maybe D16+integerD16Maybe :: Integer -> Maybe Word4 integerD16Maybe =     \case         x | x < 0    ->  Nothing         x | x <= 15  ->  Just (toEnum (fromInteger x))         _            ->  Nothing -d16Integer :: D16 -> Integer+d16Integer :: Word4 -> Integer d16Integer = toInteger . fromEnum -naturalD16Unsafe :: Natural -> D16+naturalD16Unsafe :: Natural -> Word4 naturalD16Unsafe = toEnum . fromIntegral -integerD16Unsafe :: Integer -> D16+integerD16Unsafe :: Integer -> Word4 integerD16Unsafe = toEnum . fromIntegral  +---  Lift instances  ---++instance HexCharSuperset char => Lift HexChar char+  where+    lift = fromHexChar++instance HexStringSuperset string => Lift [HexChar] string+  where+    lift = fromHexCharList+++ ---  Classes  ---  class HexCharSuperset char@@ -355,7 +349,7 @@         0 -> fromHexCharList [ Digit0 ]         n -> fromHexCharList (fmap (d16HexChar c) (naturalList n))   where-    naturalList :: Natural -> [D16]+    naturalList :: Natural -> [Word4]     naturalList = DList.toList . r       where         r = \case@@ -419,7 +413,7 @@ readNatural :: HexStringSuperset string => string -> Maybe Natural readNatural = (Just . readNaturalDigits) <=< nonEmpty <=< (Just . fmap hexCharD16) <=< toHexCharListMaybe   where-    readNaturalDigits :: NonEmpty D16 -> Natural+    readNaturalDigits :: NonEmpty Word4 -> Natural     readNaturalDigits = List.foldl' (\total x -> (16 * total) + d16Natural x) 0  {- |@@ -447,7 +441,7 @@     readNonNegative :: [ASCII.Char] -> Maybe Integer     readNonNegative = (Just . toInteger . readIntegerDigits) <=< nonEmpty <=< (Just . fmap hexCharD16) <=< toHexCharListMaybe -    readIntegerDigits :: NonEmpty D16 -> Integer+    readIntegerDigits :: NonEmpty Word4 -> Integer     readIntegerDigits = List.foldl' (\total x -> (16 * total) + d16Integer x) 0  {- |@@ -490,10 +484,10 @@  instance HexCharSuperset char => HexCharSuperset (ASCII char)   where-    isHexChar = isHexChar . lift+    isHexChar = isHexChar . ASCII.Refinement.lift     fromHexChar = asciiUnsafe . fromHexChar-    toHexCharUnsafe = toHexCharUnsafe . lift-    toHexCharMaybe = toHexCharMaybe . lift+    toHexCharUnsafe = toHexCharUnsafe . ASCII.Refinement.lift+    toHexCharMaybe = toHexCharMaybe . ASCII.Refinement.lift   ---  HexStringSuperset instances  ---@@ -553,7 +547,7 @@  instance HexStringSuperset char => HexStringSuperset (ASCII char)   where-    isHexString = isHexString . lift+    isHexString = isHexString . ASCII.Refinement.lift     fromHexCharList = asciiUnsafe . fromHexCharList-    toHexCharListUnsafe = toHexCharListUnsafe . lift-    toHexCharListMaybe = toHexCharListMaybe . lift+    toHexCharListUnsafe = toHexCharListUnsafe . ASCII.Refinement.lift+    toHexCharListMaybe = toHexCharListMaybe . ASCII.Refinement.lift
+ library/ASCII/Word4.hs view
@@ -0,0 +1,30 @@+module ASCII.Word4 ( Word4 (..) ) where++import Data.Data (Data)+import Data.Eq (Eq)+import Data.Hashable (Hashable)+import Data.Ord (Ord (..))+import GHC.Generics (Generic)+import Prelude (Bounded (..), Enum (..))+import Text.Show (Show)++-- | 4-bit unsigned integer (a whole number between /0/ and /15/)+data Word4+    = Number0  -- ^ Zero+    | Number1  -- ^ One+    | Number2  -- ^ Two+    | Number3  -- ^ Three+    | Number4  -- ^ Four+    | Number5  -- ^ Five+    | Number6  -- ^ Six+    | Number7  -- ^ Seven+    | Number8  -- ^ Eight+    | Number9  -- ^ Nine+    | Number10 -- ^ Ten      (A)+    | Number11 -- ^ Eleven   (B)+    | Number12 -- ^ Twelve   (C)+    | Number13 -- ^ Thirteen (D)+    | Number14 -- ^ Fourteen (E)+    | Number15 -- ^ Fifteen  (F)+    deriving stock (Bounded, Enum, Eq, Ord, Show, Data, Generic)+    deriving anyclass Hashable
test/Main.hs view
@@ -4,6 +4,7 @@ import qualified ASCII.Char as ASCII import qualified ASCII.Decimal as Dec import qualified ASCII.Hexadecimal as Hex+import qualified ASCII.Word4 as Word4  import Control.Applicative (liftA2) import Control.Monad (Monad (..), when)@@ -123,7 +124,7 @@  prop_toDigitListMaybe :: Property prop_toDigitListMaybe = withTests 1 $ property $-    Dec.toDigitListMaybe ("846" :: T.Text) === Just [Dec.D8, Dec.D4, Dec.D6]+    Dec.toDigitListMaybe ("846" :: T.Text) === Just [Dec.Digit8, Dec.Digit4, Dec.Digit6]  prop_toDigitListMaybe_fail :: Property prop_toDigitListMaybe_fail = withTests 1 $ property $@@ -227,7 +228,7 @@  prop_naturalDigitMaybe_5 :: Property prop_naturalDigitMaybe_5 = withTests 1 $ property $-    Dec.naturalDigitMaybe 5 === Just Dec.D5+    Dec.naturalDigitMaybe 5 === Just Dec.Digit5  prop_naturalDigitMaybe_12 :: Property prop_naturalDigitMaybe_12 = withTests 1 $ property $@@ -235,7 +236,7 @@  prop_integerDigitMaybe_5 :: Property prop_integerDigitMaybe_5 = withTests 1 $ property $-    Dec.integerDigitMaybe 5 === Just Dec.D5+    Dec.integerDigitMaybe 5 === Just Dec.Digit5  prop_integerDigitMaybe_12 :: Property prop_integerDigitMaybe_12 = withTests 1 $ property $@@ -251,10 +252,10 @@ prop_D16_enumBounded :: Property prop_D16_enumBounded = withTests 1 $ property $     checkEnumBounded-      [ Hex.D0, Hex.D1, Hex.D2, Hex.D3-      , Hex.D4, Hex.D5, Hex.D6, Hex.D7-      , Hex.D8, Hex.D9, Hex.D10, Hex.D11-      , Hex.D12, Hex.D13, Hex.D14, Hex.D15+      [ Word4.Number0, Word4.Number1, Word4.Number2, Word4.Number3+      , Word4.Number4, Word4.Number5, Word4.Number6, Word4.Number7+      , Word4.Number8, Word4.Number9, Word4.Number10, Word4.Number11+      , Word4.Number12, Word4.Number13, Word4.Number14, Word4.Number15       ]  prop_HexLetter_enumBounded :: Property@@ -278,16 +279,16 @@ prop_HexCharBreakdown_enumBounded :: Property prop_HexCharBreakdown_enumBounded = withTests 1 $ property $     checkEnumBounded-      [ Hex.HexDigit Dec.D0-      , Hex.HexDigit Dec.D1-      , Hex.HexDigit Dec.D2-      , Hex.HexDigit Dec.D3-      , Hex.HexDigit Dec.D4-      , Hex.HexDigit Dec.D5-      , Hex.HexDigit Dec.D6-      , Hex.HexDigit Dec.D7-      , Hex.HexDigit Dec.D8-      , Hex.HexDigit Dec.D9+      [ Hex.HexDigit Dec.Digit0+      , Hex.HexDigit Dec.Digit1+      , Hex.HexDigit Dec.Digit2+      , Hex.HexDigit Dec.Digit3+      , Hex.HexDigit Dec.Digit4+      , Hex.HexDigit Dec.Digit5+      , Hex.HexDigit Dec.Digit6+      , Hex.HexDigit Dec.Digit7+      , Hex.HexDigit Dec.Digit8+      , Hex.HexDigit Dec.Digit9       , Hex.HexLetter UpperCase Hex.LetterA       , Hex.HexLetter UpperCase Hex.LetterB       , Hex.HexLetter UpperCase Hex.LetterC@@ -313,12 +314,12 @@ prop_hexLetterD16 :: Property prop_hexLetterD16 = withTests 1 $ property $     functionEq every Hex.hexLetterD16 $ \case-        Hex.LetterA -> Hex.D10-        Hex.LetterB -> Hex.D11-        Hex.LetterC -> Hex.D12-        Hex.LetterD -> Hex.D13-        Hex.LetterE -> Hex.D14-        Hex.LetterF -> Hex.D15+        Hex.LetterA -> Word4.Number10+        Hex.LetterB -> Word4.Number11+        Hex.LetterC -> Word4.Number12+        Hex.LetterD -> Word4.Number13+        Hex.LetterE -> Word4.Number14+        Hex.LetterF -> Word4.Number15  prop_d16HexLetter :: Property prop_d16HexLetter = withTests 1 $ property $@@ -392,68 +393,68 @@ prop_d16HexChar :: Property prop_d16HexChar = withTests 1 $ property $     functionEq (liftA2 (,) every every) (uncurry Hex.d16HexChar) $ \case-        (_, Hex.D0) -> Hex.Digit0-        (_, Hex.D1) -> Hex.Digit1-        (_, Hex.D2) -> Hex.Digit2-        (_, Hex.D3) -> Hex.Digit3-        (_, Hex.D4) -> Hex.Digit4-        (_, Hex.D5) -> Hex.Digit5-        (_, Hex.D6) -> Hex.Digit6-        (_, Hex.D7) -> Hex.Digit7-        (_, Hex.D8) -> Hex.Digit8-        (_, Hex.D9) -> Hex.Digit9-        (UpperCase, Hex.D10) -> Hex.CapitalLetterA-        (UpperCase, Hex.D11) -> Hex.CapitalLetterB-        (UpperCase, Hex.D12) -> Hex.CapitalLetterC-        (UpperCase, Hex.D13) -> Hex.CapitalLetterD-        (UpperCase, Hex.D14) -> Hex.CapitalLetterE-        (UpperCase, Hex.D15) -> Hex.CapitalLetterF-        (LowerCase, Hex.D10) -> Hex.SmallLetterA-        (LowerCase, Hex.D11) -> Hex.SmallLetterB-        (LowerCase, Hex.D12) -> Hex.SmallLetterC-        (LowerCase, Hex.D13) -> Hex.SmallLetterD-        (LowerCase, Hex.D14) -> Hex.SmallLetterE-        (LowerCase, Hex.D15) -> Hex.SmallLetterF+        (_, Word4.Number0) -> Hex.Digit0+        (_, Word4.Number1) -> Hex.Digit1+        (_, Word4.Number2) -> Hex.Digit2+        (_, Word4.Number3) -> Hex.Digit3+        (_, Word4.Number4) -> Hex.Digit4+        (_, Word4.Number5) -> Hex.Digit5+        (_, Word4.Number6) -> Hex.Digit6+        (_, Word4.Number7) -> Hex.Digit7+        (_, Word4.Number8) -> Hex.Digit8+        (_, Word4.Number9) -> Hex.Digit9+        (UpperCase, Word4.Number10) -> Hex.CapitalLetterA+        (UpperCase, Word4.Number11) -> Hex.CapitalLetterB+        (UpperCase, Word4.Number12) -> Hex.CapitalLetterC+        (UpperCase, Word4.Number13) -> Hex.CapitalLetterD+        (UpperCase, Word4.Number14) -> Hex.CapitalLetterE+        (UpperCase, Word4.Number15) -> Hex.CapitalLetterF+        (LowerCase, Word4.Number10) -> Hex.SmallLetterA+        (LowerCase, Word4.Number11) -> Hex.SmallLetterB+        (LowerCase, Word4.Number12) -> Hex.SmallLetterC+        (LowerCase, Word4.Number13) -> Hex.SmallLetterD+        (LowerCase, Word4.Number14) -> Hex.SmallLetterE+        (LowerCase, Word4.Number15) -> Hex.SmallLetterF  prop_hexCharD16 :: Property prop_hexCharD16 = withTests 1 $ property $     functionEq every Hex.hexCharD16 $ \case-        Hex.Digit0 -> Hex.D0-        Hex.Digit1 -> Hex.D1-        Hex.Digit2 -> Hex.D2-        Hex.Digit3 -> Hex.D3-        Hex.Digit4 -> Hex.D4-        Hex.Digit5 -> Hex.D5-        Hex.Digit6 -> Hex.D6-        Hex.Digit7 -> Hex.D7-        Hex.Digit8 -> Hex.D8-        Hex.Digit9 -> Hex.D9-        Hex.CapitalLetterA -> Hex.D10-        Hex.CapitalLetterB -> Hex.D11-        Hex.CapitalLetterC -> Hex.D12-        Hex.CapitalLetterD -> Hex.D13-        Hex.CapitalLetterE -> Hex.D14-        Hex.CapitalLetterF -> Hex.D15-        Hex.SmallLetterA   -> Hex.D10-        Hex.SmallLetterB   -> Hex.D11-        Hex.SmallLetterC   -> Hex.D12-        Hex.SmallLetterD   -> Hex.D13-        Hex.SmallLetterE   -> Hex.D14-        Hex.SmallLetterF   -> Hex.D15+        Hex.Digit0 -> Word4.Number0+        Hex.Digit1 -> Word4.Number1+        Hex.Digit2 -> Word4.Number2+        Hex.Digit3 -> Word4.Number3+        Hex.Digit4 -> Word4.Number4+        Hex.Digit5 -> Word4.Number5+        Hex.Digit6 -> Word4.Number6+        Hex.Digit7 -> Word4.Number7+        Hex.Digit8 -> Word4.Number8+        Hex.Digit9 -> Word4.Number9+        Hex.CapitalLetterA -> Word4.Number10+        Hex.CapitalLetterB -> Word4.Number11+        Hex.CapitalLetterC -> Word4.Number12+        Hex.CapitalLetterD -> Word4.Number13+        Hex.CapitalLetterE -> Word4.Number14+        Hex.CapitalLetterF -> Word4.Number15+        Hex.SmallLetterA   -> Word4.Number10+        Hex.SmallLetterB   -> Word4.Number11+        Hex.SmallLetterC   -> Word4.Number12+        Hex.SmallLetterD   -> Word4.Number13+        Hex.SmallLetterE   -> Word4.Number14+        Hex.SmallLetterF   -> Word4.Number15  prop_breakDownHexChar :: Property prop_breakDownHexChar = withTests 1 $ property $     functionEq every Hex.breakDownHexChar $ \case-        Hex.Digit0 -> Hex.HexDigit Dec.D0-        Hex.Digit1 -> Hex.HexDigit Dec.D1-        Hex.Digit2 -> Hex.HexDigit Dec.D2-        Hex.Digit3 -> Hex.HexDigit Dec.D3-        Hex.Digit4 -> Hex.HexDigit Dec.D4-        Hex.Digit5 -> Hex.HexDigit Dec.D5-        Hex.Digit6 -> Hex.HexDigit Dec.D6-        Hex.Digit7 -> Hex.HexDigit Dec.D7-        Hex.Digit8 -> Hex.HexDigit Dec.D8-        Hex.Digit9 -> Hex.HexDigit Dec.D9+        Hex.Digit0 -> Hex.HexDigit Dec.Digit0+        Hex.Digit1 -> Hex.HexDigit Dec.Digit1+        Hex.Digit2 -> Hex.HexDigit Dec.Digit2+        Hex.Digit3 -> Hex.HexDigit Dec.Digit3+        Hex.Digit4 -> Hex.HexDigit Dec.Digit4+        Hex.Digit5 -> Hex.HexDigit Dec.Digit5+        Hex.Digit6 -> Hex.HexDigit Dec.Digit6+        Hex.Digit7 -> Hex.HexDigit Dec.Digit7+        Hex.Digit8 -> Hex.HexDigit Dec.Digit8+        Hex.Digit9 -> Hex.HexDigit Dec.Digit9         Hex.CapitalLetterA -> Hex.HexLetter UpperCase Hex.LetterA         Hex.CapitalLetterB -> Hex.HexLetter UpperCase Hex.LetterB         Hex.CapitalLetterC -> Hex.HexLetter UpperCase Hex.LetterC