ascii-caseless (empty) → 0.0.0.0
raw patch · 6 files changed
+366/−0 lines, 6 filesdep +ascii-casedep +ascii-caselessdep +ascii-char
Dependencies added: ascii-case, ascii-caseless, ascii-char, base, hashable, hspec
Files
- ascii-caseless.cabal +69/−0
- changelog.md +1/−0
- library/ASCII/Caseless.hs +101/−0
- license.txt +13/−0
- readme.md +2/−0
- test/Main.hs +180/−0
+ ascii-caseless.cabal view
@@ -0,0 +1,69 @@+cabal-version: 3.0++name: ascii-caseless+version: 0.0.0.0+synopsis: ASCII character without an upper/lower case distinction+category: Data, Text++description:+ This package defines a @Char@ type that has+ 102 constructors: 128 ASCII characters minus 26 letters.++license: Apache-2.0+license-file: license.txt++author: Chris Martin+maintainer: Chris Martin, Julie Moronuki++homepage: https://github.com/typeclasses/ascii-caseless+bug-Reports: https://github.com/typeclasses/ascii-caseless/issues++extra-source-files: *.md++source-repository head+ type: git+ location: git://github.com/typeclasses/ascii-caseless.git++common base+ default-language: Haskell2010+ ghc-options: -Wall++ default-extensions:+ NoImplicitPrelude++ build-depends:+ ascii-case ^>= 1.0.1+ , ascii-char ^>= 1.0+ , base ^>= 4.14 || ^>= 4.15 || ^>= 4.16 || ^>= 4.17++library+ import: base+ ghc-options: -fno-warn-unused-imports+ hs-source-dirs: library++ default-extensions:+ DeriveAnyClass+ DeriveDataTypeable+ DeriveGeneric+ DerivingStrategies+ StandaloneDeriving++ build-depends:+ hashable ^>= 1.3.5 || ^>= 1.4++ exposed-modules:+ ASCII.Caseless++test-suite test-ascii-caseless+ import: base+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Main.hs++ default-extensions:+ OverloadedStrings+ QuasiQuotes++ build-depends:+ ascii-caseless+ , hspec ^>= 2.8.5 || ^>= 2.9 || ^>= 2.10
+ changelog.md view
@@ -0,0 +1,1 @@+0.0.0.0 - Initial release
+ library/ASCII/Caseless.hs view
@@ -0,0 +1,101 @@+module ASCII.Caseless+ (+ {- * The @Char@ type -} CaselessChar (..),+ {- * Enumeration -} allCharacters,+ {- * Conversion -} disregardCase, toCase, assumeCaseUnsafe,+ )+ where++import ASCII.Case (Case (..))++import Data.Bool (otherwise)+import Data.Data (Data)+import Data.Eq (Eq, (/=), (==))+import Data.Hashable (Hashable)+import Data.Int (Int)+import Data.Maybe (Maybe (..))+import Data.Ord (Ord, (<), (>), (<=))+import GHC.Generics (Generic)+import Prelude (Bounded, Enum, enumFromTo, fromEnum, maxBound, minBound, toEnum, (-), (+))+import Text.Show (Show)++import qualified Data.Char as C+import qualified Data.Bool as Bool+import qualified Prelude as Enum (Enum (..))+import qualified ASCII.Char as ASCII++-- | A character in the ASCII character set, without an upper/lower case distinction for letters++data CaselessChar =+ 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++ | 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++ | LetterA | LetterB | LetterC | LetterD | LetterE | LetterF | LetterG | LetterH | LetterI | LetterJ | LetterK | LetterL | LetterM | LetterN | LetterO | LetterP | LetterQ | LetterR | LetterS | LetterT | LetterU | LetterV | LetterW | LetterX | LetterY | LetterZ++ | LeftSquareBracket | Backslash | RightSquareBracket | Caret | Underscore | GraveAccent++ | LeftCurlyBracket | VerticalLine | RightCurlyBracket | Tilde | Delete++-- | ASCII characters can be compared for equality using '(==)'.+deriving stock instance Eq CaselessChar++-- | Caseless 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 caseless ASCII characters is roughly the same as the ordering of the corresponding Unicode 'C.Char's, with caseless letters appearing in the place of case-sensitive capital letters.+deriving stock instance Ord CaselessChar++-- | The 'Enum' instance allows us to use range syntax, for example @['LetterA' .. 'LetterZ']@ is a list all letters from /a/ to /z/.+deriving stock instance Enum CaselessChar++-- | You can write @(['minBound' .. 'maxBound'] :: ['CaselessChar'])@ to get a list of all the caseless ASCII characters.+deriving stock instance Bounded CaselessChar++-- | 'show' produces the name of a constructor. For example, the character @e@ is shown as “@LetterE@”. See "ASCII.Caseless" for the complete list of constructor names.+deriving stock instance Show CaselessChar++-- | The 'Data' instance allows caseless 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 CaselessChar++-- | The 'Generic' instance allows caseless 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 CaselessChar++-- | The 'Hashable' instance lets us collect caseless ASCII characters in hash-based sets, and it lets us use caseless ASCII characters as keys in hash-based maps. (See the @unordered-containers@ package.)+deriving anyclass instance Hashable CaselessChar++-- | There are 102 characters in total.+allCharacters :: [CaselessChar]+allCharacters = Prelude.enumFromTo Prelude.minBound Prelude.maxBound++disregardCase :: ASCII.Char -> CaselessChar+disregardCase x+ | x <= ASCII.GraveAccent = Enum.toEnum (Enum.fromEnum x)+ | x <= ASCII.SmallLetterZ = Enum.toEnum (Enum.fromEnum x - 32)+ | Bool.otherwise = Enum.toEnum (Enum.fromEnum x - 26)++-- | Like 'disregardCase', but defined only where the character is either a letter in the given case or a non-letter+--+-- For upper case, this is slightly more efficient than 'disregardCase'.+assumeCaseUnsafe :: Case -> ASCII.Char -> CaselessChar+assumeCaseUnsafe LowerCase x = disregardCase x+assumeCaseUnsafe UpperCase x+ | x <= ASCII.GraveAccent = Enum.toEnum (Enum.fromEnum x)+ | Bool.otherwise = Enum.toEnum (Enum.fromEnum x - 26)++toCase :: Case -> CaselessChar -> ASCII.Char+toCase UpperCase x+ | x <= GraveAccent = Enum.toEnum (Enum.fromEnum x)+ | Bool.otherwise = Enum.toEnum (Enum.fromEnum x + 26)+toCase LowerCase x+ | x <= AtSign = Enum.toEnum (Enum.fromEnum x)+ | x <= LetterZ = Enum.toEnum (Enum.fromEnum x + 32)+ | x <= GraveAccent = Enum.toEnum (Enum.fromEnum x)+ | Bool.otherwise = Enum.toEnum (Enum.fromEnum x + 26)
+ license.txt view
@@ -0,0 +1,13 @@+Copyright 2022 Mission Valley Software LLC++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++ http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.
+ readme.md view
@@ -0,0 +1,2 @@+This package defines `CaselessChar`, representing a character in the ASCII+character set, but without an upper/lower case distinction for letters.
+ test/Main.hs view
@@ -0,0 +1,180 @@+module Main (main) where++import ASCII.Caseless+import ASCII.Case (Case (..))++import Data.Eq (Eq ((==)))+import Data.Foldable (for_)+import Data.Function (($))+import Data.List (length)+import Data.String (String)+import System.IO (IO)+import Test.Hspec (hspec, describe, it, shouldBe)++import qualified ASCII.Char as CaseSensitive+import qualified ASCII.Caseless as Caseless++main :: IO ()+main = hspec $ do++ describe "caseless characters" $ do+ it "how many" $ length allCharacters == 102++ describe "disregardCase" $ do+ for_ [nonLetters, capitalLetters, smallLetters] $ \(name, pairs) ->+ it name $ for_ pairs $ \(a, b) -> disregardCase b `shouldBe` a++ describe "testAssumeCaseUnsafe" $ do+ describe "UpperCase" $ do+ for_ [nonLetters, capitalLetters] $ \(name, pairs) ->+ it name $ for_ pairs $ \(a, b) -> assumeCaseUnsafe UpperCase b `shouldBe` a+ describe "LowerCase" $ do+ for_ [nonLetters, smallLetters] $ \(name, pairs) ->+ it name $ for_ pairs $ \(a, b) -> assumeCaseUnsafe LowerCase b `shouldBe` a++ describe "toCase" $ do+ describe "UpperCase" $ do+ for_ [nonLetters, capitalLetters] $ \(name, pairs) ->+ it name $ for_ pairs $ \(a, b) -> toCase UpperCase a `shouldBe` b+ describe "LowerCase" $ do+ for_ [nonLetters, smallLetters] $ \(name, pairs) ->+ it name $ for_ pairs $ \(a, b) -> toCase LowerCase a `shouldBe` b++nonLetters, smallLetters, capitalLetters :: (String, [(CaselessChar, CaseSensitive.Char)])++smallLetters = (,) "small letters"+ [ (,) Caseless.LetterA CaseSensitive.SmallLetterA+ , (,) Caseless.LetterB CaseSensitive.SmallLetterB+ , (,) Caseless.LetterC CaseSensitive.SmallLetterC+ , (,) Caseless.LetterD CaseSensitive.SmallLetterD+ , (,) Caseless.LetterE CaseSensitive.SmallLetterE+ , (,) Caseless.LetterF CaseSensitive.SmallLetterF+ , (,) Caseless.LetterG CaseSensitive.SmallLetterG+ , (,) Caseless.LetterH CaseSensitive.SmallLetterH+ , (,) Caseless.LetterI CaseSensitive.SmallLetterI+ , (,) Caseless.LetterJ CaseSensitive.SmallLetterJ+ , (,) Caseless.LetterK CaseSensitive.SmallLetterK+ , (,) Caseless.LetterL CaseSensitive.SmallLetterL+ , (,) Caseless.LetterM CaseSensitive.SmallLetterM+ , (,) Caseless.LetterN CaseSensitive.SmallLetterN+ , (,) Caseless.LetterO CaseSensitive.SmallLetterO+ , (,) Caseless.LetterP CaseSensitive.SmallLetterP+ , (,) Caseless.LetterQ CaseSensitive.SmallLetterQ+ , (,) Caseless.LetterR CaseSensitive.SmallLetterR+ , (,) Caseless.LetterS CaseSensitive.SmallLetterS+ , (,) Caseless.LetterT CaseSensitive.SmallLetterT+ , (,) Caseless.LetterU CaseSensitive.SmallLetterU+ , (,) Caseless.LetterV CaseSensitive.SmallLetterV+ , (,) Caseless.LetterW CaseSensitive.SmallLetterW+ , (,) Caseless.LetterX CaseSensitive.SmallLetterX+ , (,) Caseless.LetterY CaseSensitive.SmallLetterY+ , (,) Caseless.LetterZ CaseSensitive.SmallLetterZ+ ]++capitalLetters = (,) "capital letters"+ [ (,) Caseless.LetterA CaseSensitive.CapitalLetterA+ , (,) Caseless.LetterB CaseSensitive.CapitalLetterB+ , (,) Caseless.LetterC CaseSensitive.CapitalLetterC+ , (,) Caseless.LetterD CaseSensitive.CapitalLetterD+ , (,) Caseless.LetterE CaseSensitive.CapitalLetterE+ , (,) Caseless.LetterF CaseSensitive.CapitalLetterF+ , (,) Caseless.LetterG CaseSensitive.CapitalLetterG+ , (,) Caseless.LetterH CaseSensitive.CapitalLetterH+ , (,) Caseless.LetterI CaseSensitive.CapitalLetterI+ , (,) Caseless.LetterJ CaseSensitive.CapitalLetterJ+ , (,) Caseless.LetterK CaseSensitive.CapitalLetterK+ , (,) Caseless.LetterL CaseSensitive.CapitalLetterL+ , (,) Caseless.LetterM CaseSensitive.CapitalLetterM+ , (,) Caseless.LetterN CaseSensitive.CapitalLetterN+ , (,) Caseless.LetterO CaseSensitive.CapitalLetterO+ , (,) Caseless.LetterP CaseSensitive.CapitalLetterP+ , (,) Caseless.LetterQ CaseSensitive.CapitalLetterQ+ , (,) Caseless.LetterR CaseSensitive.CapitalLetterR+ , (,) Caseless.LetterS CaseSensitive.CapitalLetterS+ , (,) Caseless.LetterT CaseSensitive.CapitalLetterT+ , (,) Caseless.LetterU CaseSensitive.CapitalLetterU+ , (,) Caseless.LetterV CaseSensitive.CapitalLetterV+ , (,) Caseless.LetterW CaseSensitive.CapitalLetterW+ , (,) Caseless.LetterX CaseSensitive.CapitalLetterX+ , (,) Caseless.LetterY CaseSensitive.CapitalLetterY+ , (,) Caseless.LetterZ CaseSensitive.CapitalLetterZ+ ]++nonLetters = (,) "non-letters"+ [ (,) Caseless.Null CaseSensitive.Null+ , (,) Caseless.StartOfHeading CaseSensitive.StartOfHeading+ , (,) Caseless.StartOfText CaseSensitive.StartOfText+ , (,) Caseless.EndOfText CaseSensitive.EndOfText+ , (,) Caseless.EndOfTransmission CaseSensitive.EndOfTransmission+ , (,) Caseless.Enquiry CaseSensitive.Enquiry+ , (,) Caseless.Acknowledgement CaseSensitive.Acknowledgement+ , (,) Caseless.Bell CaseSensitive.Bell+ , (,) Caseless.Backspace CaseSensitive.Backspace+ , (,) Caseless.HorizontalTab CaseSensitive.HorizontalTab+ , (,) Caseless.LineFeed CaseSensitive.LineFeed+ , (,) Caseless.VerticalTab CaseSensitive.VerticalTab+ , (,) Caseless.FormFeed CaseSensitive.FormFeed+ , (,) Caseless.CarriageReturn CaseSensitive.CarriageReturn+ , (,) Caseless.ShiftOut CaseSensitive.ShiftOut+ , (,) Caseless.ShiftIn CaseSensitive.ShiftIn+ , (,) Caseless.DataLinkEscape CaseSensitive.DataLinkEscape+ , (,) Caseless.DeviceControl1 CaseSensitive.DeviceControl1+ , (,) Caseless.DeviceControl2 CaseSensitive.DeviceControl2+ , (,) Caseless.DeviceControl3 CaseSensitive.DeviceControl3+ , (,) Caseless.DeviceControl4 CaseSensitive.DeviceControl4+ , (,) Caseless.NegativeAcknowledgement CaseSensitive.NegativeAcknowledgement+ , (,) Caseless.SynchronousIdle CaseSensitive.SynchronousIdle+ , (,) Caseless.EndOfTransmissionBlock CaseSensitive.EndOfTransmissionBlock+ , (,) Caseless.Cancel CaseSensitive.Cancel+ , (,) Caseless.EndOfMedium CaseSensitive.EndOfMedium+ , (,) Caseless.Substitute CaseSensitive.Substitute+ , (,) Caseless.Escape CaseSensitive.Escape+ , (,) Caseless.FileSeparator CaseSensitive.FileSeparator+ , (,) Caseless.GroupSeparator CaseSensitive.GroupSeparator+ , (,) Caseless.RecordSeparator CaseSensitive.RecordSeparator+ , (,) Caseless.UnitSeparator CaseSensitive.UnitSeparator+ , (,) Caseless.Space CaseSensitive.Space+ , (,) Caseless.ExclamationMark CaseSensitive.ExclamationMark+ , (,) Caseless.QuotationMark CaseSensitive.QuotationMark+ , (,) Caseless.NumberSign CaseSensitive.NumberSign+ , (,) Caseless.DollarSign CaseSensitive.DollarSign+ , (,) Caseless.PercentSign CaseSensitive.PercentSign+ , (,) Caseless.Ampersand CaseSensitive.Ampersand+ , (,) Caseless.Apostrophe CaseSensitive.Apostrophe+ , (,) Caseless.LeftParenthesis CaseSensitive.LeftParenthesis+ , (,) Caseless.RightParenthesis CaseSensitive.RightParenthesis+ , (,) Caseless.Asterisk CaseSensitive.Asterisk+ , (,) Caseless.PlusSign CaseSensitive.PlusSign+ , (,) Caseless.Comma CaseSensitive.Comma+ , (,) Caseless.HyphenMinus CaseSensitive.HyphenMinus+ , (,) Caseless.FullStop CaseSensitive.FullStop+ , (,) Caseless.Slash CaseSensitive.Slash+ , (,) Caseless.Digit0 CaseSensitive.Digit0+ , (,) Caseless.Digit1 CaseSensitive.Digit1+ , (,) Caseless.Digit2 CaseSensitive.Digit2+ , (,) Caseless.Digit3 CaseSensitive.Digit3+ , (,) Caseless.Digit4 CaseSensitive.Digit4+ , (,) Caseless.Digit5 CaseSensitive.Digit5+ , (,) Caseless.Digit6 CaseSensitive.Digit6+ , (,) Caseless.Digit7 CaseSensitive.Digit7+ , (,) Caseless.Digit8 CaseSensitive.Digit8+ , (,) Caseless.Digit9 CaseSensitive.Digit9+ , (,) Caseless.Colon CaseSensitive.Colon+ , (,) Caseless.Semicolon CaseSensitive.Semicolon+ , (,) Caseless.LessThanSign CaseSensitive.LessThanSign+ , (,) Caseless.EqualsSign CaseSensitive.EqualsSign+ , (,) Caseless.GreaterThanSign CaseSensitive.GreaterThanSign+ , (,) Caseless.QuestionMark CaseSensitive.QuestionMark+ , (,) Caseless.AtSign CaseSensitive.AtSign+ , (,) Caseless.LeftSquareBracket CaseSensitive.LeftSquareBracket+ , (,) Caseless.Backslash CaseSensitive.Backslash+ , (,) Caseless.RightSquareBracket CaseSensitive.RightSquareBracket+ , (,) Caseless.Caret CaseSensitive.Caret+ , (,) Caseless.Underscore CaseSensitive.Underscore+ , (,) Caseless.GraveAccent CaseSensitive.GraveAccent+ , (,) Caseless.LeftCurlyBracket CaseSensitive.LeftCurlyBracket+ , (,) Caseless.VerticalLine CaseSensitive.VerticalLine+ , (,) Caseless.RightCurlyBracket CaseSensitive.RightCurlyBracket+ , (,) Caseless.Tilde CaseSensitive.Tilde+ , (,) Caseless.Delete CaseSensitive.Delete+ ]