packages feed

ascii-char 1.0.0.17 → 1.0.1.0

raw patch · 4 files changed

+231/−76 lines, 4 filesdep ~basedep ~hashabledep ~hspecPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, hashable, hspec

API changes (from Hackage documentation)

+ ASCII.Char: fromWord8Maybe :: Word8 -> Maybe Char
+ ASCII.Char: fromWord8Unsafe :: Word8 -> Char
+ ASCII.Char: toWord8 :: Char -> Word8

Files

ascii-char.cabal view
@@ -1,7 +1,7 @@ cabal-version: 3.0  name: ascii-char-version: 1.0.0.17+version: 1.0.1.0 synopsis: A Char type representing an ASCII character category: Data, Text @@ -18,7 +18,7 @@ homepage: https://github.com/typeclasses/ascii-char bug-reports: https://github.com/typeclasses/ascii-char/issues -extra-doc-files: *.md+extra-source-files: *.md  source-repository head     type: git@@ -36,7 +36,6 @@  library     import: base-    ghc-options: -fno-warn-unused-imports     hs-source-dirs: library      default-extensions:
changelog.md view
@@ -1,8 +1,8 @@-### 1.0.0.17 (2022-12-30)+### 1.0.1.0 (2023-01-05) -Fix error in cabal file (change `extra-source-files` to `extra-doc-files`)+Add `Word8` conversions: `toWord8`, `fromWord8Maybe`, `fromWord8Unsafe` -### 1.0.0.16 (2022-12-27)+### 1.0.0.16 (2022-10-04)  Test suite now uses `hspec` 
library/ASCII/Char.hs view
@@ -1,95 +1,178 @@-{- |--The 'Char' type has 128 nullary constructors, listed in order according to each character's 7-bit numeric code.---}-+{-| The 'Char' type has 128 nullary constructors, listed in+    order according to each character's 7-bit numeric code. -} module ASCII.Char   (     {- * The @Char@ type -} Char (..),-    {- * Conversions with @Int@ -} toInt, fromIntMaybe, fromIntUnsafe,-    {- * Enumeration -} allCharacters+    {- * @Int@ -} toInt, fromIntMaybe, fromIntUnsafe,+    {- * @Word8@ -} toWord8, fromWord8Maybe, fromWord8Unsafe,+    {- * Enumeration -} allCharacters,     {- * Notes -} {- $notes -}   )   where  import Data.Bool (otherwise) import Data.Data (Data)-import Data.Eq (Eq, (/=), (==))+import Data.Eq (Eq) import Data.Hashable (Hashable) import Data.Int (Int) import Data.Maybe (Maybe (..)) import Data.Ord (Ord, (<), (>))+import Data.Word (Word8) import GHC.Generics (Generic)-import Prelude (Bounded, Enum, enumFromTo, fromEnum, maxBound, minBound, toEnum)+import Prelude (Bounded, Enum, enumFromTo, fromEnum, fromIntegral, maxBound, minBound, toEnum) import Text.Show (Show) -import qualified Data.Char as C---- | A character in the ASCII character set.+-- | A character in the ASCII character set  data Char =-      Null | StartOfHeading | StartOfText | EndOfText | EndOfTransmission | Enquiry | Acknowledgement | Bell | Backspace | HorizontalTab | LineFeed | VerticalTab | FormFeed | CarriageReturn | ShiftOut | ShiftIn | DataLinkEscape+      Null | StartOfHeading | StartOfText | EndOfText | EndOfTransmission | Enquiry+    | Acknowledgement | Bell | Backspace | HorizontalTab | LineFeed | VerticalTab+    | FormFeed | CarriageReturn | ShiftOut | ShiftIn | DataLinkEscape      | DeviceControl1 | DeviceControl2 | DeviceControl3 | DeviceControl4 -    | NegativeAcknowledgement | SynchronousIdle | EndOfTransmissionBlock | Cancel | EndOfMedium | Substitute | Escape+    | NegativeAcknowledgement | SynchronousIdle | EndOfTransmissionBlock+    | Cancel | EndOfMedium | Substitute | Escape      | FileSeparator | GroupSeparator | RecordSeparator | UnitSeparator -    | Space | ExclamationMark | QuotationMark | NumberSign | DollarSign | PercentSign | Ampersand | Apostrophe | LeftParenthesis | RightParenthesis | Asterisk | PlusSign | Comma | HyphenMinus | FullStop | Slash+    | Space+    | ExclamationMark  -- ^ !+    | QuotationMark    -- ^ "+    | NumberSign       -- ^ #+    | DollarSign       -- ^ $+    | PercentSign      -- ^ %+    | Ampersand        -- ^ &+    | Apostrophe       -- ^ #+    | LeftParenthesis  -- ^ (+    | RightParenthesis -- ^ )+    | Asterisk         -- ^ \*+    | PlusSign         -- ^ ++    | Comma            -- ^ ,+    | HyphenMinus      -- ^ \-+    | FullStop         -- ^ .+    | Slash            -- ^ /      | Digit0 | Digit1 | Digit2 | Digit3 | Digit4 | Digit5 | Digit6 | Digit7 | Digit8 | Digit9 -    | Colon | Semicolon | LessThanSign | EqualsSign | GreaterThanSign | QuestionMark | AtSign+    | Colon            -- ^ :+    | Semicolon        -- ^ ;+    | LessThanSign     -- ^ \<+    | EqualsSign       -- ^ =+    | GreaterThanSign  -- ^ \>+    | QuestionMark     -- ^ ?+    | AtSign           -- ^ \@ -    | CapitalLetterA | CapitalLetterB | CapitalLetterC | CapitalLetterD | CapitalLetterE | CapitalLetterF | CapitalLetterG | CapitalLetterH | CapitalLetterI | CapitalLetterJ | CapitalLetterK | CapitalLetterL | CapitalLetterM | CapitalLetterN | CapitalLetterO | CapitalLetterP | CapitalLetterQ | CapitalLetterR | CapitalLetterS | CapitalLetterT | CapitalLetterU | CapitalLetterV | CapitalLetterW | CapitalLetterX | CapitalLetterY | CapitalLetterZ+    | CapitalLetterA | CapitalLetterB | CapitalLetterC | CapitalLetterD | CapitalLetterE+    | CapitalLetterF | CapitalLetterG | CapitalLetterH | CapitalLetterI | CapitalLetterJ+    | CapitalLetterK | CapitalLetterL | CapitalLetterM | CapitalLetterN | CapitalLetterO+    | CapitalLetterP | CapitalLetterQ | CapitalLetterR | CapitalLetterS | CapitalLetterT+    | CapitalLetterU | CapitalLetterV | CapitalLetterW | CapitalLetterX | CapitalLetterY+    | CapitalLetterZ -    | LeftSquareBracket | Backslash | RightSquareBracket | Caret | Underscore | GraveAccent+    | LeftSquareBracket  -- ^ \[+    | Backslash          -- ^ \\+    | RightSquareBracket -- ^ \]+    | Caret              -- ^ \^+    | Underscore         -- ^ _+    | GraveAccent        -- ^ \` -    | SmallLetterA | SmallLetterB | SmallLetterC | SmallLetterD | SmallLetterE | SmallLetterF | SmallLetterG | SmallLetterH | SmallLetterI | SmallLetterJ | SmallLetterK | SmallLetterL | SmallLetterM | SmallLetterN | SmallLetterO | SmallLetterP | SmallLetterQ | SmallLetterR | SmallLetterS | SmallLetterT | SmallLetterU | SmallLetterV | SmallLetterW | SmallLetterX | SmallLetterY | SmallLetterZ+    | SmallLetterA | SmallLetterB | SmallLetterC | SmallLetterD | SmallLetterE+    | SmallLetterF | SmallLetterG | SmallLetterH | SmallLetterI | SmallLetterJ+    | SmallLetterK | SmallLetterL | SmallLetterM | SmallLetterN | SmallLetterO+    | SmallLetterP | SmallLetterQ | SmallLetterR | SmallLetterS | SmallLetterT+    | SmallLetterU | SmallLetterV | SmallLetterW | SmallLetterX | SmallLetterY+    | SmallLetterZ -    | LeftCurlyBracket | VerticalLine | RightCurlyBracket | Tilde | Delete+    | LeftCurlyBracket   -- ^ \{+    | VerticalLine       -- ^ \|+    | RightCurlyBracket  -- ^ \}+    | Tilde              -- ^ \~+    | Delete --- | ASCII characters can be compared for equality using '(==)'. Comparisons are case-sensitive; @'SmallLetterA' '/=' 'CapitalLetterA'@.+{-| ASCII characters can be compared for equality using '(==)'.+Comparisons are case-sensitive; @'SmallLetterA' '/=' 'CapitalLetterA'@. -} deriving stock instance Eq Char --- | ASCII characters are ordered; for example, the letter /A/ is "less than" ('<') the letter /B/ because it appears earlier in the list. The ordering of ASCII characters is the same as the ordering of the corresponding Unicode 'C.Char's.+{-| ASCII characters are ordered; for example, the letter /A/ is "less than"+('<') the letter /B/ because it appears earlier in the list. The ordering of+ASCII characters is the same as the ordering of the corresponding Unicode+'Data.Char.Char's. -}+ deriving stock instance Ord Char --- | The 'Enum' instance allows us to use range syntax, for example @['SmallLetterA' .. 'SmallLetterZ']@ is a list all lower-case letters from /a/ to /z/. Instead of 'toEnum' and 'fromEnum', consider using 'toInt' and 'fromIntMaybe'.+{-| The 'Enum' instance allows us to use range syntax, for example+@['SmallLetterA' .. 'SmallLetterZ']@ is a list all lower-case letters from /a/+to /z/. Instead of 'toEnum' and 'fromEnum', consider using 'toInt' and+'fromIntMaybe'. -} deriving stock instance Enum Char --- | The least character is 'Null', and the greatest character is 'Delete'. You can write @(['minBound' .. 'maxBound'] :: [ASCII.'Char'])@ to get a list of all the ASCII characters.+{-| The least character is 'Null', and the greatest character is 'Delete'. You+can write @(['minBound' .. 'maxBound'] :: [ASCII.'Char'])@ to get a list of all+the ASCII characters. -} deriving stock instance Bounded Char --- | 'show' produces the name of a constructor. For example, the character @e@ is shown as “@SmallLetterE@”. See "ASCII.Char" for the complete list of constructor names.+{-| 'show' produces the name of a constructor. For example, the character @e@ is+shown as “@SmallLetterE@”. See "ASCII.Char" for the complete list of constructor+names. -} deriving stock instance Show Char --- | The 'Data' instance allows ASCII characters to be used with generic programming in the “SYB” style. (See the <https://hackage.haskell.org/package/syb syb> package and the 2003 paper <https://www.microsoft.com/en-us/research/wp-content/uploads/2003/01/hmap.pdf Scrap Your Boilerplate> by Ralf Lämmel and Simon Peyton Jones.)+{-| The 'Data' instance allows ASCII characters to be used with generic+programming in the “SYB” style. (See the+<https://hackage.haskell.org/package/syb syb> package and the 2003 paper+<https://www.microsoft.com/en-us/research/wp-content/uploads/2003/01/hmap.pdf Scrap Your Boilerplate>+by Ralf Lämmel and Simon Peyton Jones.) -} deriving stock instance Data Char --- | The 'Generic' instance allows ASCII characters to be used with generic programming in the “generic deriving” style. (See the <https://hackage.haskell.org/package/generic-data generic-data> package and the 2010 paper <http://dreixel.net/research/pdf/gdmh.pdf A generic deriving mechanism for Haskell> by José Pedro Magalhães, Atze Dijkstra, Johan Jeuring, and Andres Löh.)+{-| The 'Generic' instance allows ASCII characters to be used with generic+programming in the “generic deriving” style. (See the+<https://hackage.haskell.org/package/generic-data generic-data> package and the 2010 paper+<http://dreixel.net/research/pdf/gdmh.pdf A generic deriving mechanism for Haskell>+by José Pedro Magalhães, Atze Dijkstra, Johan Jeuring, and Andres Löh.) -} deriving stock instance Generic Char --- | The 'Hashable' instance lets us collect ASCII characters in hash-based sets, and it lets us use ASCII characters as keys in hash-based maps. (See the @unordered-containers@ package.)+{-| The 'Hashable' instance lets us collect ASCII characters in hash-based sets,+and it lets us use ASCII characters as keys in hash-based maps. (See the+@unordered-containers@ package.) -} deriving anyclass instance Hashable Char -{- | Converts an ASCII character to its corresponding numeric value between 0 and 127.+{-| Converts an ASCII character to its corresponding numeric value between 0 and 127 ->>> map toInt [Null, CapitalLetterA, SmallLetterA, Delete]-[0,65,97,127]+@+toInt Null == 0+toInt CapitalLetterA == 6+toInt SmallLetterA == 97+toInt Delete == 127+@  -}  toInt :: Char -> Int toInt = Prelude.fromEnum -{- | Returns 'Just' the ASCII character corresponding to a numeric value between 0 and 127, or 'Nothing' for numbers outside this range.+{-| Converts an ASCII character to its corresponding byte between 0 and 127 ->>> map fromIntMaybe [-1, 0, 65, 127, 128]-[Nothing,Just Null,Just CapitalLetterA,Just Delete,Nothing]+@+toWord8 Null == 0+toWord8 CapitalLetterA == 6+toWord8 SmallLetterA == 97+toWord8 Delete == 127+@+-}+toWord8 :: Char -> Word8+toWord8 x = Prelude.fromIntegral (Prelude.fromEnum x) +{-| Returns 'Just' the ASCII character corresponding to a numeric value between+    0 and 127, or 'Nothing' for numbers outside this range++@+fromIntMaybe (-1) == Nothing+fromIntMaybe 0 == Just Null+fromIntMaybe 65 == Just CapitalLetterA+fromIntMaybe 127 == Just Delete+fromIntMaybe 128 == Nothing+@+ -}  fromIntMaybe :: Int -> Maybe Char@@ -97,18 +180,55 @@                | x > 127   = Nothing                | otherwise = Just (fromIntUnsafe x) -{- | The inverse of 'toInt'.+{-| Returns 'Just' the ASCII character corresponding to a byte between+    0 and 127, or 'Nothing' for bytes above this range -This is marked as /unsafe/ because it is undefined for numbers below 0 or above 127. The safe variant of this function is 'fromIntMaybe'.+@+fromWord8Maybe 0 == Just Null+fromWord8Maybe 65 == Just CapitalLetterA+fromWord8Maybe 127 == Just Delete+fromWord8Maybe 128 == Nothing+@ ->>> map fromIntUnsafe [65, 66, 67]-[CapitalLetterA,CapitalLetterB,CapitalLetterC]+-}+fromWord8Maybe :: Word8 -> Maybe Char+fromWord8Maybe x | x > 127   = Nothing+                 | otherwise = Just (fromWord8Unsafe x) +{-| The inverse of 'toInt'++This is marked as /unsafe/ because it is undefined for numbers below 0+or above 127. The safe variant of this function is 'fromIntMaybe'.++@+fromIntUnsafe (-1) == undefined+fromIntUnsafe 65 == CapitalLetterA+fromIntUnsafe 66 == CapitalLetterB+fromIntUnsafe 67 == CapitalLetterC+fromIntUnsafe 128 == undefined+@+ -}  fromIntUnsafe :: Int -> Char fromIntUnsafe = Prelude.toEnum +{-| The inverse of 'toWord8'++This is marked as /unsafe/ because it is undefined bytes above 127.+The safe variant of this function is 'fromWord8Maybe'.++@+fromWord8Unsafe 65 == CapitalLetterA+fromWord8Unsafe 66 == CapitalLetterB+fromWord8Unsafe 67 == CapitalLetterC+fromWord8Unsafe 128 == undefined+@++-}+fromWord8Unsafe :: Word8 -> Char+fromWord8Unsafe x = fromIntUnsafe (Prelude.fromIntegral x)+ allCharacters :: [Char] allCharacters = Prelude.enumFromTo Prelude.minBound Prelude.maxBound @@ -116,17 +236,20 @@  There are 128 characters in total. ->>> length allCharacters-128+@+length allCharacters == 128+@  Null is the first character. ->>> minBound :: Char-Null+@+minBound == Null+@  Delete is the last character. ->>> maxBound :: Char-Delete+@+maxBound == Delete+@  -}
test/Main.hs view
@@ -3,39 +3,72 @@ import ASCII.Char  import Data.Function (($))-import Data.List (length)+import Data.List (length, sort) import Data.Maybe (Maybe (..)) import Prelude (maxBound, minBound) import System.IO (IO)-import Test.Hspec (hspec, it, shouldBe)+import Test.Hspec (describe, hspec, it, shouldBe)  main :: IO () main = hspec $ do -    it "toInt" $ do-        let f = toInt-        f Null `shouldBe` 0-        f CapitalLetterA `shouldBe` 65-        f SmallLetterA `shouldBe` 97-        f Delete `shouldBe` 127+    describe "toInt" $ do+        let c ~> n = toInt c `shouldBe` n -    it "fromIntMaybe" $ do-        let f = fromIntMaybe-        f (-1) `shouldBe` Nothing-        f 0 `shouldBe` Just Null-        f 65 `shouldBe` Just CapitalLetterA-        f 127 `shouldBe` Just Delete-        f 128 `shouldBe` Nothing+        it "Null   → 0"   $ Null           ~> 0+        it "A      → 65"  $ CapitalLetterA ~> 65+        it "a      → 97"  $ SmallLetterA   ~> 97+        it "Delete → 127" $ Delete         ~> 127 -    it "fromIntUnsafe" $ do-        let f = fromIntUnsafe-        f 65 `shouldBe` CapitalLetterA-        f 66 `shouldBe` CapitalLetterB-        f 67 `shouldBe` CapitalLetterC+    describe "toWord8" $ do+        let c ~> n = toWord8 c `shouldBe` n -    it "allCharacters" $ do-        length allCharacters `shouldBe` 128+        it "Null   → 0"   $ Null           ~> 0+        it "A      → 65"  $ CapitalLetterA ~> 65+        it "a      → 97"  $ SmallLetterA   ~> 97+        it "Delete → 127" $ Delete         ~> 127 -    it "Bounded" $ do-        minBound `shouldBe` Null-        maxBound `shouldBe` Delete+    describe "fromIntMaybe" $ do+        let n ~> c = fromIntMaybe n `shouldBe` c++        it "-1  → Nothing" $ (-1) ~> Nothing+        it "0   → Null"    $ 0    ~> Just Null+        it "65  → A"       $ 65   ~> Just CapitalLetterA+        it "127 → Delete"  $ 127  ~> Just Delete+        it "128 → Nothing" $ 128  ~> Nothing++    describe "fromWord8Maybe" $ do+        let n ~> c = fromWord8Maybe n `shouldBe` c++        it "0   → Null"    $ 0    ~> Just Null+        it "65  → A"       $ 65   ~> Just CapitalLetterA+        it "127 → Delete"  $ 127  ~> Just Delete+        it "128 → Nothing" $ 128  ~> Nothing++    describe "fromIntUnsafe" $ do+        let n ~> c = fromIntUnsafe n `shouldBe` c++        it "0  → Null"    $ 0  ~> Null+        it "65 → A"       $ 65 ~> CapitalLetterA+        it "66 → B"       $ 66 ~> CapitalLetterB+        it "67 → C"       $ 67 ~> CapitalLetterC+        it "127 → Delete" $ 127  ~> Delete++    describe "fromWord8Unsafe" $ do+        let n ~> c = fromWord8Unsafe n `shouldBe` c++        it "0  → Null"    $ 0  ~> Null+        it "65 → A"       $ 65 ~> CapitalLetterA+        it "66 → B"       $ 66 ~> CapitalLetterB+        it "67 → C"       $ 67 ~> CapitalLetterC+        it "127 → Delete" $ 127  ~> Delete++    describe "allCharacters" $ do+        let x = allCharacters++        it "has 128 items" $ length x `shouldBe` 128+        it "is sorted"     $ sort x `shouldBe` x++    describe "Bounded" $ do+        it "min bound is Null"   $ minBound `shouldBe` Null+        it "max bound is Delete" $ maxBound `shouldBe` Delete