packages feed

ascii-case 1.0.0.4 → 1.0.0.6

raw patch · 5 files changed

+175/−116 lines, 5 filesdep +ascii-casedep ~ascii-chardep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: ascii-case

Dependency ranges changed: ascii-char, base

API changes (from Hackage documentation)

Files

− ASCII/Case.hs
@@ -1,113 +0,0 @@-{- |--/Case/ is a property of letters. /A-Z/ are /upper case/ letters, and /a-z/ are /lower case/ letters. No other ASCII characters have case.---}--module ASCII.Case ( Case (..), letterCase, isCase, toCase ) where--import ASCII.Char    ( Char (..) )-import Data.Bool     ( Bool, otherwise )-import Data.Data     ( Data )-import Data.Eq       ( Eq )-import Data.Function ( (.), ($) )-import Data.Hashable ( Hashable )-import Data.Ord      ( Ord, (<=), (>=) )-import GHC.Generics  ( Generic )-import Prelude       ( Enum, Bounded, Int, (+), (-) )-import Text.Show     ( Show )-import Data.Maybe    ( Maybe (..) )--import qualified ASCII.Char as Char-import qualified Data.Bool  as Bool--{- $setup-->>> import Prelude---}--data Case =-    UpperCase -- ^ The letters from 'CapitalLetterA' to 'CapitalLetterZ'.-  | LowerCase -- ^ The letters from 'SmallLetterA' to 'SmallLetterZ'.--deriving stock instance Eq Case--deriving stock instance Ord Case--deriving stock instance Enum Case--deriving stock instance Bounded Case--deriving stock instance Show Case--deriving stock instance Data Case--deriving stock instance Generic Case--deriving anyclass instance Hashable Case--{- | Determines whether a character is a letter, and if so, whether it is upper or lower case.-->>> map letterCase [CapitalLetterR, SmallLetterR, DollarSign]-[Just UpperCase,Just LowerCase,Nothing]---}--letterCase :: Char -> Maybe Case-letterCase x | isCase UpperCase x = Just UpperCase-             | isCase LowerCase x = Just LowerCase-             | otherwise          = Nothing--{- | Determines whether a character is a letter of a particular case.-->>> map (isCase UpperCase) [CapitalLetterR,SmallLetterR,DollarSign]-[True,False,False]---}--isCase :: Case -> Char -> Bool-isCase c x = (Bool.&&) ( x >= a ) ( x <= z ) where (a, z) = az c--az :: Case -> (Char, Char)-az UpperCase = (CapitalLetterA, CapitalLetterZ)-az LowerCase = (SmallLetterA, SmallLetterZ)--{- | Maps a letter character to its upper/lower case equivalent.-->>> toCase UpperCase SmallLetterX-CapitalLetterX-->>> toCase LowerCase CapitalLetterF-SmallLetterF--Characters that are already in the requested case are unmodified by this transformation.-->>> toCase UpperCase CapitalLetterA-CapitalLetterA--Characters that are not letters, such as exclamation mark, are unmodified by this transformation.-->>> toCase UpperCase ExclamationMark-ExclamationMark---}--toCase :: Case -> Char -> Char-toCase c x = if isCase (opposite c) x then changeCaseUnsafe c x else x---- | Change a letter to the given case, assuming that the input character is a letter of the opposite case.--changeCaseUnsafe :: Case -> Char -> Char-changeCaseUnsafe c = charAsIntUnsafe (changeCaseInt c)--changeCaseInt :: Case -> Int -> Int-changeCaseInt LowerCase i = i + 32-changeCaseInt UpperCase i = i - 32--opposite :: Case -> Case-opposite UpperCase = LowerCase-opposite LowerCase = UpperCase--charAsIntUnsafe :: (Int -> Int) -> (Char -> Char)-charAsIntUnsafe f = Char.fromIntUnsafe . f . Char.toInt
ascii-case.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.0  name: ascii-case-version: 1.0.0.4+version: 1.0.0.6 synopsis: ASCII letter case category: Data, Text @@ -18,8 +18,6 @@  build-type: Simple -tested-with: GHC == 9.0.1, GHC == 8.10.1, GHC == 8.8.1, GHC == 8.6.5, GHC == 8.4.3- extra-source-files: changelog.txt  source-repository head@@ -35,6 +33,7 @@     default-extensions: DeriveDataTypeable     default-extensions: DeriveGeneric     ghc-options: -Wall+    hs-source-dirs: library      build-depends: ascii-char ^>= 1.0 @@ -42,3 +41,14 @@     build-depends: hashable   >= 1.2  && < 1.4      exposed-modules: ASCII.Case++test-suite test+    type: exitcode-stdio-1.0+    default-language: Haskell2010+    default-extensions: NoImplicitPrelude+    default-extensions: OverloadedStrings+    default-extensions: QuasiQuotes+    ghc-options: -Wall+    hs-source-dirs: test+    main-is: test.hs+    build-depends: ascii-case, ascii-char, base
changelog.txt view
@@ -1,3 +1,4 @@ 1.0.0.0 - 2020-05-05 - Initial release 1.0.0.2 - 2020-05-18 - Support GHC 8.10 1.0.0.4 - 2021-02-10 - Support GHC 9.0+1.0.0.6 - 2021-09-26 - Add a test suite
+ library/ASCII/Case.hs view
@@ -0,0 +1,107 @@+{- |++/Case/ is a property of letters. /A-Z/ are /upper case/ letters, and /a-z/ are /lower case/ letters. No other ASCII characters have case.++-}++module ASCII.Case ( Case (..), letterCase, isCase, toCase ) where++import ASCII.Char    ( Char (..) )+import Data.Bool     ( Bool, otherwise )+import Data.Data     ( Data )+import Data.Eq       ( Eq )+import Data.Function ( (.) )+import Data.Hashable ( Hashable )+import Data.Ord      ( Ord, (<=), (>=) )+import GHC.Generics  ( Generic )+import Prelude       ( Enum, Bounded, Int, (+), (-) )+import Text.Show     ( Show )+import Data.Maybe    ( Maybe (..) )++import qualified ASCII.Char as Char+import qualified Data.Bool  as Bool++data Case =+    UpperCase -- ^ The letters from 'CapitalLetterA' to 'CapitalLetterZ'.+  | LowerCase -- ^ The letters from 'SmallLetterA' to 'SmallLetterZ'.++deriving stock instance Eq Case++deriving stock instance Ord Case++deriving stock instance Enum Case++deriving stock instance Bounded Case++deriving stock instance Show Case++deriving stock instance Data Case++deriving stock instance Generic Case++deriving anyclass instance Hashable Case++{- | Determines whether a character is a letter, and if so, whether it is upper or lower case.++>>> map letterCase [CapitalLetterR, SmallLetterR, DollarSign]+[Just UpperCase,Just LowerCase,Nothing]++-}++letterCase :: Char -> Maybe Case+letterCase x | isCase UpperCase x = Just UpperCase+             | isCase LowerCase x = Just LowerCase+             | otherwise          = Nothing++{- | Determines whether a character is a letter of a particular case.++>>> map (isCase UpperCase) [CapitalLetterR,SmallLetterR,DollarSign]+[True,False,False]++-}++isCase :: Case -> Char -> Bool+isCase c x = (Bool.&&) ( x >= a ) ( x <= z ) where (a, z) = az c++az :: Case -> (Char, Char)+az UpperCase = (CapitalLetterA, CapitalLetterZ)+az LowerCase = (SmallLetterA, SmallLetterZ)++{- | Maps a letter character to its upper/lower case equivalent.++>>> toCase UpperCase SmallLetterX+CapitalLetterX++>>> toCase LowerCase CapitalLetterF+SmallLetterF++Characters that are already in the requested case are unmodified by this transformation.++>>> toCase UpperCase CapitalLetterA+CapitalLetterA++Characters that are not letters, such as exclamation mark, are unmodified by this transformation.++>>> toCase UpperCase ExclamationMark+ExclamationMark++-}++toCase :: Case -> Char -> Char+toCase c x = if isCase (opposite c) x then changeCaseUnsafe c x else x++-- | Change a letter to the given case, assuming that the input character is a letter of the opposite case.++changeCaseUnsafe :: Case -> Char -> Char+changeCaseUnsafe c = charAsIntUnsafe (changeCaseInt c)++changeCaseInt :: Case -> Int -> Int+changeCaseInt LowerCase i = i + 32+changeCaseInt UpperCase i = i - 32++opposite :: Case -> Case+opposite UpperCase = LowerCase+opposite LowerCase = UpperCase++charAsIntUnsafe :: (Int -> Int) -> (Char -> Char)+charAsIntUnsafe f = Char.fromIntUnsafe . f . Char.toInt
+ test/test.hs view
@@ -0,0 +1,54 @@+module Main where++import ASCII.Case++import ASCII.Char (Char (..))++import Control.Applicative (Applicative (..))+import Control.Monad (Monad (..))+import Data.Bool (Bool (..))+import Data.Eq (Eq ((==)))+import Data.Function ((.), ($))+import Data.Functor (Functor (..))+import Data.List (intercalate, map, null)+import Data.Maybe (Maybe (..))+import Data.Semigroup ((<>))+import Numeric.Natural (Natural)+import System.Exit (die)+import System.IO (IO, putStrLn)+import Text.Show (show)++main :: IO ()+main = dieIfFailures $ do+    test 1 $ map letterCase [CapitalLetterR, SmallLetterR, DollarSign] == [Just UpperCase, Just LowerCase,Nothing]+    test 2 $ map (isCase UpperCase) [CapitalLetterR, SmallLetterR, DollarSign] == [True, False, False]+    test 3 $ toCase UpperCase SmallLetterX == CapitalLetterX+    test 4 $ toCase LowerCase CapitalLetterF == SmallLetterF+    test 5 $ toCase UpperCase CapitalLetterA == CapitalLetterA+    test 6 $ toCase UpperCase ExclamationMark == ExclamationMark++dieIfFailures :: Failures a -> IO a+dieIfFailures (Failures fs x) =+    if null fs+        then do putStrLn "💯"; return x+        else die $ intercalate " " (map (("🔥" <> ) . show) fs)++type TestNumber = Natural++test :: TestNumber -> Bool -> Failures ()+test n t = Failures (if t then [] else [n]) ()++data Failures a = Failures [TestNumber] a++instance Functor Failures+  where+    fmap f (Failures a x) = Failures a (f x)++instance Applicative Failures+  where+    pure x = Failures [] x+    Failures a f <*> Failures b x = Failures (a <> b) (f x)++instance Monad Failures+  where+    Failures a x >>= f = let Failures b y = f x in Failures (a <> b) y