ascii-predicates 1.0.1.2 → 1.0.1.3
raw patch · 6 files changed
+420/−369 lines, 6 filesdep ~basedep ~hedgehogPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base, hedgehog
API changes (from Hackage documentation)
Files
- ascii-predicates.cabal +6/−6
- changelog.md +4/−0
- library/ASCII/Lists.hs +35/−31
- library/ASCII/ListsAndPredicates.hs +45/−44
- library/ASCII/Predicates.hs +195/−222
- test/Main.hs +135/−66
ascii-predicates.cabal view
@@ -1,7 +1,7 @@ cabal-version: 3.0 name: ascii-predicates-version: 1.0.1.2+version: 1.0.1.3 synopsis: Various categorizations of ASCII characters category: Data, Text @@ -25,15 +25,15 @@ location: git://github.com/typeclasses/ascii-predicates.git common base- default-language: Haskell2010+ default-language: GHC2021 ghc-options: -Wall default-extensions: NoImplicitPrelude build-depends:- ascii-char ^>= 1.0- , base ^>= 4.14 || ^>= 4.15 || ^>= 4.16 || ^>= 4.17+ , ascii-char ^>= 1.0+ , base ^>= 4.16 || ^>= 4.17 || ^>= 4.18 library import: base@@ -56,5 +56,5 @@ TemplateHaskell build-depends:- ascii-predicates- , hedgehog ^>= 1.0.5 || ^>= 1.1 || ^>= 1.2+ , ascii-predicates+ , hedgehog ^>= 1.1.2 || ^>= 1.2
changelog.md view
@@ -1,3 +1,7 @@+### 1.0.1.3 (2023-06-26)++Raise language to GHC2021+ ### 1.0.1.2 (2023-01-02) Minor Cabal correction (change `extra-doc-files` to `extra-source-files`)
library/ASCII/Lists.hs view
@@ -1,81 +1,85 @@ module ASCII.Lists- (- {- * Lists -}- {- ** Every character -} all,- {- ** Group-related -} printableCharacters, controlCodes,- {- ** Letter-related -} letters, capitalLetters, smallLetters,- {- ** Number-related -} digits, octDigits, hexDigits, numbers,- {- ** Other -} visibleCharacters,- {- * Notes -} {- $notes -}+ ( -- * Lists++ -- ** Every character+ all,++ -- ** Group-related+ printableCharacters,+ controlCodes,++ -- ** Letter-related+ letters,+ capitalLetters,+ smallLetters,++ -- ** Number-related+ digits,+ octDigits,+ hexDigits,+ numbers,++ -- ** Other+ visibleCharacters,++ -- * Notes+ -- $notes )- where+where import ASCII.Char (Char (..)) import Data.List ((++)) import Prelude (Bounded (..), enumFromTo, maxBound, minBound) -- | All 128 ASCII characters, listed in order from 'Null' to 'Delete'.- all :: [Char] all = enumFromTo minBound maxBound -- | Characters in the 'Printable' group: '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', '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', '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'.- printableCharacters :: [Char] printableCharacters = enumFromTo Space Tilde -- | Characters drawable with ink on a page: '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', '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', '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'.- visibleCharacters :: [Char] visibleCharacters = enumFromTo ExclamationMark Tilde -- | Characters in the 'Control' group: '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', 'FileSeparator', 'GroupSeparator', 'RecordSeparator', 'UnitSeparator', 'Delete'.- controlCodes :: [Char] controlCodes = enumFromTo Null UnitSeparator ++ [Delete] -- | Letters: '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', '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'.- letters :: [Char] letters = capitalLetters ++ smallLetters -- | Capital letters: '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'.- capitalLetters :: [Char] capitalLetters = enumFromTo CapitalLetterA CapitalLetterZ -- | Small letters: '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'.- smallLetters :: [Char] smallLetters = enumFromTo SmallLetterA SmallLetterZ -- | Digits: 'Digit0', 'Digit1', 'Digit2', 'Digit3', 'Digit4', 'Digit5', 'Digit6', 'Digit7', 'Digit8', 'Digit9'.- digits :: [Char] digits = enumFromTo Digit0 Digit9 -- | Octal digits: 'Digit0', 'Digit1', 'Digit2', 'Digit3', 'Digit4', 'Digit5', 'Digit6', 'Digit7'.- octDigits :: [Char] octDigits = enumFromTo Digit0 Digit7 --- | Hexidecimal digits: 'Digit0', 'Digit1', 'Digit2', 'Digit3', 'Digit4', 'Digit5', 'Digit6', 'Digit7', 'Digit8', 'Digit9', 'CapitalLetterA', 'CapitalLetterB', 'CapitalLetterC', 'CapitalLetterD', 'CapitalLetterE', 'CapitalLetterF', 'SmallLetterA', 'SmallLetterB', 'SmallLetterC', 'SmallLetterD', 'SmallLetterE', 'SmallLetterF'.-+-- | Hexadecimal digits: 'Digit0', 'Digit1', 'Digit2', 'Digit3', 'Digit4', 'Digit5', 'Digit6', 'Digit7', 'Digit8', 'Digit9', 'CapitalLetterA', 'CapitalLetterB', 'CapitalLetterC', 'CapitalLetterD', 'CapitalLetterE', 'CapitalLetterF', 'SmallLetterA', 'SmallLetterB', 'SmallLetterC', 'SmallLetterD', 'SmallLetterE', 'SmallLetterF'. hexDigits :: [Char] hexDigits = digits ++ enumFromTo CapitalLetterA CapitalLetterF ++ enumFromTo SmallLetterA SmallLetterF -- | Synonym for 'digits'.- numbers :: [Char] numbers = digits -{- $notes--Each list is sorted in ascending order.-->>> lists = [all, printableCharacters, controlCodes, letters, capitalLetters, smallLetters, digits, octDigits, hexDigits, numbers]-->>> Data.List.all (\xs -> Data.List.sort xs == xs) lists-True---}+-- $notes+--+-- Each list is sorted in ascending order.+--+-- >>> lists = [all, printableCharacters, controlCodes, letters, capitalLetters, smallLetters, digits, octDigits, hexDigits, numbers]+--+-- >>> Data.List.all (\xs -> Data.List.sort xs == xs) lists+-- True
library/ASCII/ListsAndPredicates.hs view
@@ -1,50 +1,51 @@ module ASCII.ListsAndPredicates- (- {- * Re-exported modules -} module ASCII.Lists, module ASCII.Predicates- {- * Notes -} {- $notes -}+ ( -- * Re-exported modules+ module ASCII.Lists,+ module ASCII.Predicates,++ -- * Notes+ -- $notes )- where+where import ASCII.Lists import ASCII.Predicates -{- $notes--The two modules re-exported here present the same information in two different forms:-- - As a list of all ASCII characters with some classification;- - As a function that tests whether a particular character belongs to the classification.--Each list contains exactly the characters for which its corresponding predicate is true.-->>> controlCodes == filter isControl all-True-->>> printableCharacters == filter isPrint all-True-->>> letters == filter isLetter all-True-->>> capitalLetters == filter isUpper all-True-->>> smallLetters == filter isLower all-True-->>> digits == filter isDigit all-True-->>> numbers == filter isNumber all-True-->>> octDigits == filter isOctDigit all-True-->>> hexDigits == filter isHexDigit all-True-->>> visibleCharacters == filter isVisible all-True---}+-- $notes+--+-- The two modules re-exported here present the same information in two different forms:+--+-- - As a list of all ASCII characters with some classification;+-- - As a function that tests whether a particular character belongs to the classification.+--+-- Each list contains exactly the characters for which its corresponding predicate is true.+--+-- >>> controlCodes == filter isControl all+-- True+--+-- >>> printableCharacters == filter isPrint all+-- True+--+-- >>> letters == filter isLetter all+-- True+--+-- >>> capitalLetters == filter isUpper all+-- True+--+-- >>> smallLetters == filter isLower all+-- True+--+-- >>> digits == filter isDigit all+-- True+--+-- >>> numbers == filter isNumber all+-- True+--+-- >>> octDigits == filter isOctDigit all+-- True+--+-- >>> hexDigits == filter isHexDigit all+-- True+--+-- >>> visibleCharacters == filter isVisible all+-- True
library/ASCII/Predicates.hs view
@@ -1,284 +1,257 @@ module ASCII.Predicates- (- {- * Group predicates -} isControl, isPrint,- {- * Case predicates -} isLower, isUpper,- {- * Letter predicates -} isLetter, isAlpha,- {- * Number predicates -} isDigit, isOctDigit, isHexDigit, isNumber,- {- * Miscellaneous predicates -} isSpace, isAlphaNum, isMark, isPunctuation, isSymbol, isSeparator, isVisible,- {- * Notes -} {- $notes -}+ ( -- * Group predicates+ isControl,+ isPrint,++ -- * Case predicates+ isLower,+ isUpper,++ -- * Letter predicates+ isLetter,+ isAlpha,++ -- * Number predicates+ isDigit,+ isOctDigit,+ isHexDigit,+ isNumber,++ -- * Miscellaneous predicates+ isSpace,+ isAlphaNum,+ isMark,+ isPunctuation,+ isSymbol,+ isSeparator,+ isVisible,++ -- * Notes+ -- $notes )- where+where import ASCII.Char (Char (..))+import ASCII.Char qualified as Char import Data.Bool (Bool (..), otherwise)+import Data.Bool qualified as Bool import Data.Eq ((==)) import Data.Function ((.))+import Data.List qualified as List import Data.Ord ((<), (<=), (>=)) -import qualified ASCII.Char as Char-import qualified Data.Bool as Bool-import qualified Data.List as List--{- | Returns True for control characters.--This function is analogous to 'Data.Char.isControl' in the "Data.Char" module.---}-+-- | Returns True for control characters.+--+-- This function is analogous to 'Data.Char.isControl' in the "Data.Char" module. isControl :: Char -> Bool isControl x =- case x of- _ | (x < Char.Space) -> True- Char.Delete -> True- _ -> False--{- | Returns True for printable characters.--This function is analogous to 'Data.Char.isPrint' in the "Data.Char" module.---}+ case x of+ _ | (x < Char.Space) -> True+ Char.Delete -> True+ _ -> False +-- | Returns True for printable characters.+--+-- This function is analogous to 'Data.Char.isPrint' in the "Data.Char" module. isPrint :: Char -> Bool isPrint = Bool.not . isControl -{- | Returns True for visible characters.--This includes all print characters except 'Char.Space'.---}-+-- | Returns True for visible characters.+--+-- This includes all print characters except 'Char.Space'. isVisible :: Char -> Bool isVisible x =- case x of- _ | x <= Char.Space -> False- Char.Delete -> False- _ -> True--{- | Returns True for lower-case letters, from 'SmallLetterA' to 'SmallLetterZ'.--This function is analogous to 'Data.Char.isLower' in the "Data.Char" module.---}+ case x of+ _ | x <= Char.Space -> False+ Char.Delete -> False+ _ -> True +-- | Returns True for lower-case letters, from 'SmallLetterA' to 'SmallLetterZ'.+--+-- This function is analogous to 'Data.Char.isLower' in the "Data.Char" module. isLower :: Char -> Bool isLower x = (Bool.&&) (x >= SmallLetterA) (x <= SmallLetterZ) -{- | Returns True for upper-case letters, from 'CapitalLetterA' to 'CapitalLetterZ'.--This function is analogous to 'Data.Char.isUpper' in the "Data.Char" module.---}-+-- | Returns True for upper-case letters, from 'CapitalLetterA' to 'CapitalLetterZ'.+--+-- This function is analogous to 'Data.Char.isUpper' in the "Data.Char" module. isUpper :: Char -> Bool isUpper x = (Bool.&&) (x >= CapitalLetterA) (x <= CapitalLetterZ) -{- | Returns True for letters:--- 'SmallLetterA' to 'SmallLetterZ'-- 'CapitalLetterA' to 'CapitalLetterZ'--This function is analogous to 'Data.Char.isLetter' in the "Data.Char" module.---}-+-- | Returns True for letters:+--+-- - 'SmallLetterA' to 'SmallLetterZ'+-- - 'CapitalLetterA' to 'CapitalLetterZ'+--+-- This function is analogous to 'Data.Char.isLetter' in the "Data.Char" module. isLetter :: Char -> Bool isLetter x = (Bool.||) (isLower x) (isUpper x) -{- | Synonym for 'isLetter'.--This function is analogous to 'Data.Char.isAlpha' in the "Data.Char" module.---}-+-- | Synonym for 'isLetter'.+--+-- This function is analogous to 'Data.Char.isAlpha' in the "Data.Char" module. isAlpha :: Char -> Bool isAlpha = isLetter -{- | Returns True for the characters from 'Digit0' to 'Digit9'.--This function is analogous to 'Data.Char.isDigit' in the "Data.Char" module.---}-+-- | Returns True for the characters from 'Digit0' to 'Digit9'.+--+-- This function is analogous to 'Data.Char.isDigit' in the "Data.Char" module. isDigit :: Char -> Bool isDigit x = (Bool.&&) (x >= Digit0) (x <= Digit9) -{- | Returns True for the characters from 'Digit0' to 'Digit7'.--This function is analogous to 'Data.Char.isOctDigit' in the "Data.Char" module.---}-+-- | Returns True for the characters from 'Digit0' to 'Digit7'.+--+-- This function is analogous to 'Data.Char.isOctDigit' in the "Data.Char" module. isOctDigit :: Char -> Bool isOctDigit x = (Bool.&&) (x >= Digit0) (x <= Digit7) -{- | Returns True for characters in any of the following ranges:--- 'Digit0' to 'Digit9'-- 'CapitalLetterA' to 'CapitalLetterF'-- 'SmallLetterA' to 'SmallLetterF'--This function is analogous to 'Data.Char.isHexDigit' in the "Data.Char" module.---}-+-- | Returns True for characters in any of the following ranges:+--+-- - 'Digit0' to 'Digit9'+-- - 'CapitalLetterA' to 'CapitalLetterF'+-- - 'SmallLetterA' to 'SmallLetterF'+--+-- This function is analogous to 'Data.Char.isHexDigit' in the "Data.Char" module. isHexDigit :: Char -> Bool-isHexDigit x | isDigit x = True- | (Bool.&&) (x >= CapitalLetterA) (x <= CapitalLetterF) = True- | (Bool.&&) (x >= SmallLetterA) (x <= SmallLetterF) = True- | otherwise = False--{- | Synonym for 'isDigit'.--In the "Data.Char" module, 'Data.Char.isDigit' selects only the ASCII digits 0 through 9, and 'Data.Char.isNumber' selects a wider set of characters because the full Unicode character set contains more numeric characters than just the ASCII digits. In this module, these two functions are redundant, but we include this synonym for compatibility with "Data.Char".---}+isHexDigit x+ | isDigit x = True+ | (Bool.&&) (x >= CapitalLetterA) (x <= CapitalLetterF) = True+ | (Bool.&&) (x >= SmallLetterA) (x <= SmallLetterF) = True+ | otherwise = False +-- | Synonym for 'isDigit'.+--+-- In the "Data.Char" module, 'Data.Char.isDigit' selects only the ASCII digits 0 through 9, and 'Data.Char.isNumber' selects a wider set of characters because the full Unicode character set contains more numeric characters than just the ASCII digits. In this module, these two functions are redundant, but we include this synonym for compatibility with "Data.Char". isNumber :: Char -> Bool isNumber = isDigit -{- | Returns True for the following characters:--- 'Space'-- 'HorizontalTab'-- 'LineFeed'-- 'VerticalTab'-- 'FormFeed'-- 'CarriageReturn'--This function is analogous to 'Data.Char.isSpace' in the "Data.Char" module.---}-+-- | Returns True for the following characters:+--+-- - 'Space'+-- - 'HorizontalTab'+-- - 'LineFeed'+-- - 'VerticalTab'+-- - 'FormFeed'+-- - 'CarriageReturn'+--+-- This function is analogous to 'Data.Char.isSpace' in the "Data.Char" module. isSpace :: Char -> Bool isSpace Space = True isSpace x = (Bool.&&) (x >= HorizontalTab) (x <= CarriageReturn) -- | This function is analogous to 'Data.Char.isAlphaNum' in the "Data.Char" module.- isAlphaNum :: Char -> Bool isAlphaNum x = (Bool.||) (isAlpha x) (isDigit x) -- | Selects mark characters, for example accents and the like, which combine with preceding characters. This always returns False because ASCII does not include any mark characters. This function is included only for compatibility with 'Data.Char.isMark' in the "Data.Char" module.- isMark :: Char -> Bool isMark _ = False -{- | Returns True for the following characters:--- 'ExclamationMark'-- 'QuotationMark'-- 'NumberSign'-- 'PercentSign'-- 'Ampersand'-- 'Apostrophe'-- 'LeftParenthesis'-- 'RightParenthesis'-- 'Asterisk'-- 'Comma'-- 'HyphenMinus'-- 'FullStop'-- 'Slash'-- 'Colon'-- 'Semicolon'-- 'QuestionMark'-- 'AtSign'-- 'LeftSquareBracket'-- 'Backslash'-- 'RightSquareBracket'-- 'Underscore'-- 'LeftCurlyBracket'-- 'RightCurlyBracket'--This function is analogous to 'Data.Char.isPunctuation' in the "Data.Char" module.---}-+-- | Returns True for the following characters:+--+-- - 'ExclamationMark'+-- - 'QuotationMark'+-- - 'NumberSign'+-- - 'PercentSign'+-- - 'Ampersand'+-- - 'Apostrophe'+-- - 'LeftParenthesis'+-- - 'RightParenthesis'+-- - 'Asterisk'+-- - 'Comma'+-- - 'HyphenMinus'+-- - 'FullStop'+-- - 'Slash'+-- - 'Colon'+-- - 'Semicolon'+-- - 'QuestionMark'+-- - 'AtSign'+-- - 'LeftSquareBracket'+-- - 'Backslash'+-- - 'RightSquareBracket'+-- - 'Underscore'+-- - 'LeftCurlyBracket'+-- - 'RightCurlyBracket'+--+-- This function is analogous to 'Data.Char.isPunctuation' in the "Data.Char" module. isPunctuation :: Char -> Bool isPunctuation = (`List.elem` [ExclamationMark, QuotationMark, NumberSign, PercentSign, Ampersand, Apostrophe, LeftParenthesis, RightParenthesis, Asterisk, Comma, HyphenMinus, FullStop, Slash, Colon, Semicolon, QuestionMark, AtSign, LeftSquareBracket, Backslash, RightSquareBracket, Underscore, LeftCurlyBracket, RightCurlyBracket]) -{- | Returns True for the following characters:--- 'DollarSign'-- 'PlusSign'-- 'LessThanSign'-- 'EqualsSign'-- 'GreaterThanSign'-- 'Caret'-- 'GraveAccent'-- 'VerticalLine'-- 'Tilde'--This function is analogous to 'Data.Char.isSymbol' in the "Data.Char" module.---}-+-- | Returns True for the following characters:+--+-- - 'DollarSign'+-- - 'PlusSign'+-- - 'LessThanSign'+-- - 'EqualsSign'+-- - 'GreaterThanSign'+-- - 'Caret'+-- - 'GraveAccent'+-- - 'VerticalLine'+-- - 'Tilde'+--+-- This function is analogous to 'Data.Char.isSymbol' in the "Data.Char" module. isSymbol :: Char -> Bool isSymbol = (`List.elem` [DollarSign, PlusSign, LessThanSign, EqualsSign, GreaterThanSign, Caret, GraveAccent, VerticalLine, Tilde]) -{- | Returns True if the character is 'Space'.--This function is analogous to 'Data.Char.isSeparator' in the "Data.Char" module.---}-+-- | Returns True if the character is 'Space'.+--+-- This function is analogous to 'Data.Char.isSeparator' in the "Data.Char" module. isSeparator :: Char -> Bool isSeparator = (== Space) -{- $notes--This module defines drop-in replacements for closely related definitions of the same name in the "Data.Char" module.-->>> import qualified Data.Char->>> import qualified Data.List->>> convert = Data.Char.chr . ASCII.Char.toInt->>> eq f g = Data.List.all (\x -> f x == g (convert x)) ASCII.Char.allCharacters-->>> eq isControl Data.Char.isControl-True-->>> eq isSpace Data.Char.isSpace-True-->>> eq isLower Data.Char.isLower-True-->>> eq isUpper Data.Char.isUpper-True-->>> eq isAlpha Data.Char.isAlpha-True-->>> eq isAlphaNum Data.Char.isAlphaNum-True-->>> eq isPrint Data.Char.isPrint-True-->>> eq isDigit Data.Char.isDigit-True-->>> eq isOctDigit Data.Char.isOctDigit-True-->>> eq isHexDigit Data.Char.isHexDigit-True-->>> eq isLetter Data.Char.isLetter-True-->>> eq isMark Data.Char.isMark-True-->>> eq isNumber Data.Char.isNumber-True-->>> eq isPunctuation Data.Char.isPunctuation-True-->>> eq isSymbol Data.Char.isSymbol-True-->>> eq isSeparator Data.Char.isSeparator-True---}+-- $notes+--+-- This module defines drop-in replacements for closely related definitions of the same name in the "Data.Char" module.+--+-- >>> import qualified Data.Char+-- >>> import qualified Data.List+-- >>> convert = Data.Char.chr . ASCII.Char.toInt+-- >>> eq f g = Data.List.all (\x -> f x == g (convert x)) ASCII.Char.allCharacters+--+-- >>> eq isControl Data.Char.isControl+-- True+--+-- >>> eq isSpace Data.Char.isSpace+-- True+--+-- >>> eq isLower Data.Char.isLower+-- True+--+-- >>> eq isUpper Data.Char.isUpper+-- True+--+-- >>> eq isAlpha Data.Char.isAlpha+-- True+--+-- >>> eq isAlphaNum Data.Char.isAlphaNum+-- True+--+-- >>> eq isPrint Data.Char.isPrint+-- True+--+-- >>> eq isDigit Data.Char.isDigit+-- True+--+-- >>> eq isOctDigit Data.Char.isOctDigit+-- True+--+-- >>> eq isHexDigit Data.Char.isHexDigit+-- True+--+-- >>> eq isLetter Data.Char.isLetter+-- True+--+-- >>> eq isMark Data.Char.isMark+-- True+--+-- >>> eq isNumber Data.Char.isNumber+-- True+--+-- >>> eq isPunctuation Data.Char.isPunctuation+-- True+--+-- >>> eq isSymbol Data.Char.isSymbol+-- True+--+-- >>> eq isSeparator Data.Char.isSeparator+-- True
test/Main.hs view
@@ -1,23 +1,27 @@ module Main (main) where +import ASCII.Char qualified import ASCII.ListsAndPredicates--import qualified ASCII.Char- import Control.Monad (Monad (..), when) import Data.Bool (not)+import Data.Char qualified as Char import Data.Eq (Eq ((==))) import Data.Function (($), (.)) import Data.List (filter)+import Data.List qualified as List+import Hedgehog+ ( MonadTest,+ Property,+ assert,+ checkParallel,+ discover,+ property,+ withTests,+ (===),+ ) import System.Exit (exitFailure) import System.IO (IO) -import qualified Data.Char as Char-import qualified Data.List as List--import Hedgehog (MonadTest, Property, assert, checkParallel, discover, property,- withTests, (===))- main :: IO () main = checkParallel $$(discover) >>= \ok -> when (not ok) exitFailure @@ -26,13 +30,26 @@ -- This test ensures that all of the lists give characters in ascending order. lists :: [[ASCII.Char.Char]]-lists = [ all, printableCharacters, controlCodes, letters,- capitalLetters, smallLetters, digits, octDigits,- hexDigits, numbers, visibleCharacters ]+lists =+ [ all,+ printableCharacters,+ controlCodes,+ letters,+ capitalLetters,+ smallLetters,+ digits,+ octDigits,+ hexDigits,+ numbers,+ visibleCharacters+ ] prop_lists_are_sorted :: Property-prop_lists_are_sorted = withTests 1 $ property $- assert $ List.all (\xs -> List.sort xs == xs) lists+prop_lists_are_sorted =+ withTests 1 $+ property $+ assert $+ List.all (\xs -> List.sort xs == xs) lists --- @@ -44,109 +61,161 @@ convert = Char.chr . ASCII.Char.toInt prop_eq_control :: Property-prop_eq_control = withTests 1 $ property $- eq isControl Char.isControl+prop_eq_control =+ withTests 1 $+ property $+ eq isControl Char.isControl prop_eq_space :: Property-prop_eq_space = withTests 1 $ property $- eq isSpace Char.isSpace+prop_eq_space =+ withTests 1 $+ property $+ eq isSpace Char.isSpace prop_eq_lower :: Property-prop_eq_lower = withTests 1 $ property $- eq isLower Char.isLower+prop_eq_lower =+ withTests 1 $+ property $+ eq isLower Char.isLower prop_eq_upper :: Property-prop_eq_upper = withTests 1 $ property $- eq isUpper Char.isUpper+prop_eq_upper =+ withTests 1 $+ property $+ eq isUpper Char.isUpper prop_eq_alpha :: Property-prop_eq_alpha = withTests 1 $ property $- eq isAlpha Char.isAlpha+prop_eq_alpha =+ withTests 1 $+ property $+ eq isAlpha Char.isAlpha prop_eq_alphaNum :: Property-prop_eq_alphaNum = withTests 1 $ property $- eq isAlphaNum Char.isAlphaNum+prop_eq_alphaNum =+ withTests 1 $+ property $+ eq isAlphaNum Char.isAlphaNum prop_eq_print :: Property-prop_eq_print = withTests 1 $ property $- eq isPrint Char.isPrint+prop_eq_print =+ withTests 1 $+ property $+ eq isPrint Char.isPrint prop_eq_digit :: Property-prop_eq_digit = withTests 1 $ property $- eq isDigit Char.isDigit+prop_eq_digit =+ withTests 1 $+ property $+ eq isDigit Char.isDigit prop_eq_octDigit :: Property-prop_eq_octDigit = withTests 1 $ property $- eq isOctDigit Char.isOctDigit+prop_eq_octDigit =+ withTests 1 $+ property $+ eq isOctDigit Char.isOctDigit prop_eq_hexDigit :: Property-prop_eq_hexDigit = withTests 1 $ property $- eq isHexDigit Char.isHexDigit+prop_eq_hexDigit =+ withTests 1 $+ property $+ eq isHexDigit Char.isHexDigit prop_eq_letter :: Property-prop_eq_letter = withTests 1 $ property $- eq isLetter Char.isLetter+prop_eq_letter =+ withTests 1 $+ property $+ eq isLetter Char.isLetter prop_eq_mark :: Property-prop_eq_mark = withTests 1 $ property $- eq isMark Char.isMark+prop_eq_mark =+ withTests 1 $+ property $+ eq isMark Char.isMark prop_eq_number :: Property-prop_eq_number = withTests 1 $ property $- eq isNumber Char.isNumber+prop_eq_number =+ withTests 1 $+ property $+ eq isNumber Char.isNumber prop_eq_punctuation :: Property-prop_eq_punctuation = withTests 1 $ property $- eq isPunctuation Char.isPunctuation+prop_eq_punctuation =+ withTests 1 $+ property $+ eq isPunctuation Char.isPunctuation prop_eq_symbol :: Property-prop_eq_symbol = withTests 1 $ property $- eq isSymbol Char.isSymbol+prop_eq_symbol =+ withTests 1 $+ property $+ eq isSymbol Char.isSymbol prop_eq_separator :: Property-prop_eq_separator = withTests 1 $ property $- eq isSeparator Char.isSeparator+prop_eq_separator =+ withTests 1 $+ property $+ eq isSeparator Char.isSeparator --- -- These tests ensure that the predicates are coherent with the lists. prop_list_control :: Property-prop_list_control = withTests 1 $ property $- controlCodes === filter isControl all+prop_list_control =+ withTests 1 $+ property $+ controlCodes === filter isControl all prop_list_printable :: Property-prop_list_printable = withTests 1 $ property $- printableCharacters === filter isPrint all+prop_list_printable =+ withTests 1 $+ property $+ printableCharacters === filter isPrint all prop_list_letter :: Property-prop_list_letter = withTests 1 $ property $- letters === filter isLetter all+prop_list_letter =+ withTests 1 $+ property $+ letters === filter isLetter all prop_list_capital :: Property-prop_list_capital = withTests 1 $ property $- capitalLetters === filter isUpper all+prop_list_capital =+ withTests 1 $+ property $+ capitalLetters === filter isUpper all prop_list_small :: Property-prop_list_small = withTests 1 $ property $- smallLetters === filter isLower all+prop_list_small =+ withTests 1 $+ property $+ smallLetters === filter isLower all prop_list_digit :: Property-prop_list_digit = withTests 1 $ property $- digits === filter isDigit all+prop_list_digit =+ withTests 1 $+ property $+ digits === filter isDigit all prop_list_number :: Property-prop_list_number = withTests 1 $ property $- numbers === filter isNumber all+prop_list_number =+ withTests 1 $+ property $+ numbers === filter isNumber all prop_list_oct :: Property-prop_list_oct = withTests 1 $ property $- octDigits === filter isOctDigit all+prop_list_oct =+ withTests 1 $+ property $+ octDigits === filter isOctDigit all prop_list_hex :: Property-prop_list_hex = withTests 1 $ property $- hexDigits === filter isHexDigit all+prop_list_hex =+ withTests 1 $+ property $+ hexDigits === filter isHexDigit all prop_list_visible :: Property-prop_list_visible = withTests 1 $ property $- visibleCharacters === filter isVisible all+prop_list_visible =+ withTests 1 $+ property $+ visibleCharacters === filter isVisible all