packages feed

ascii-th 1.0.0.4 → 1.0.0.6

raw patch · 7 files changed

+317/−258 lines, 7 filesdep +ascii-thdep +bytestringdep +textdep ~ascii-chardep ~ascii-supersetdep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: ascii-th, bytestring, text

Dependency ranges changed: ascii-char, ascii-superset, base

API changes (from Hackage documentation)

Files

− ASCII/QuasiQuoters.hs
@@ -1,120 +0,0 @@-module ASCII.QuasiQuoters ( char, string ) where--import ASCII.Char                  ( Char )-import ASCII.Superset              ( toCharMaybe, toCharListMaybe )-import ASCII.TemplateHaskell       ( isCharExp, isCharPat, isStringExp, isStringPat )-import Control.Monad               ( (>=>), return )-import Control.Monad.Fail          ( MonadFail, fail )-import Data.Maybe                  ( Maybe (..) )-import Language.Haskell.TH.Quote   ( QuasiQuoter (..) )-import Language.Haskell.TH.Syntax  ( Q, Exp, Pat )--import qualified Data.Char   as Unicode-import qualified Data.String as Unicode--{- $setup-->>> :set -fno-warn-overlapping-patterns->>> :set -XNoQuasiQuotes->>> :set -XNoViewPatterns->>> import qualified ASCII->>> import qualified Data.String->>> import qualified Data.Text->>> import qualified Data.ByteString.Builder->>> import Data.Word (Word8)->>> import ASCII.Char->>> import ASCII.QuasiQuoters---}--{- | Produces an expression or a pattern corresponding to an ASCII character.--The result will have an 'ASCII.Superset.CharSuperset' constraint; since this is polymorphic, use with a type signature to specify the particular you want is recommended.--The quasi-quoted string must consist of a single character that is within the ASCII character set.-->>> :set -XQuasiQuotes-->>> [char|e|] :: ASCII.Char-SmallLetterE-->>> [char|e|] :: Word8-101--Use in a pattern context requires enabling the @ViewPatterns@ language extension.-->>> :set -XViewPatterns-->>> case Tilde of [char|@|] -> 1; [char|~|] -> 2; _ -> 3-2---}--char :: QuasiQuoter-char = expPatQQ requireOneAscii isCharExp isCharPat--{- | Produces an expression or a pattern corresponding to an ASCII string.--The result will have an 'ASCII.Superset.StringSuperset' constraint; since this is polymorphic, use with a type signature to specify the particular you want is recommended.--The quasi-quoted string must consist only of characters are within the ASCII character set.-->>> :set -XQuasiQuotes-->>> [string|Hello!|] :: [ASCII.Char]-[CapitalLetterH,SmallLetterE,SmallLetterL,SmallLetterL,SmallLetterO,ExclamationMark]-->>> [string|Hello!|] :: Data.String.String-"Hello!"-->>> [string|Hello!|] :: Data.Text.Text-"Hello!"-->>> Data.ByteString.Builder.toLazyByteString [string|Hello!|]-"Hello!"---Use in a pattern context requires enabling the @ViewPatterns@ language extension.-->>> :set -XViewPatterns-->>> case [CapitalLetterH, SmallLetterI] of [string|Bye|] -> 1; [string|Hi|] -> 2; _ -> 3-2---}--string :: QuasiQuoter-string = expPatQQ requireAsciiList isStringExp isStringPat--requireOneAscii :: Unicode.String -> Q Char-requireOneAscii = requireOne >=> requireAscii--oneMaybe :: [a] -> Maybe a-oneMaybe xs = case xs of [x] -> Just x; _ -> Nothing--requireOne :: Unicode.String -> Q Unicode.Char-requireOne = oneMaybe || "Must be exactly one character."--requireAscii :: Unicode.Char -> Q Char-requireAscii = toCharMaybe || "Must be an ASCII character."--requireAsciiList :: Unicode.String -> Q [Char]-requireAsciiList = toCharListMaybe || "Must be only ASCII characters."--(||) :: (a -> Maybe b) -> Unicode.String -> a -> Q b-f || msg = \a -> case f a of Just b -> return b; Nothing -> fail msg--expPatQQ :: (Unicode.String -> Q a) -> (a -> Q Exp) -> (a -> Q Pat) -> QuasiQuoter-expPatQQ f a b =-    QuasiQuoter-        { quoteExp  = f >=> a-        , quotePat  = f >=> b-        , quoteType = notType-        , quoteDec  = notDec-        }--notType :: MonadFail m => a -> m b-notType _ = fail "Cannot be used in a type context."--notDec :: MonadFail m => a -> m b-notDec _ = fail "Cannot be used in a declaration context."
− ASCII/TemplateHaskell.hs
@@ -1,135 +0,0 @@-module ASCII.TemplateHaskell (--    {- * Characters          -} charExp,     charPat,-    {- * Character lists     -} charListExp, charListPat,-    {- * Character supersets -} isCharExp,   isCharPat,-    {- * String supersets    -} isStringExp, isStringPat--  ) where--import qualified ASCII.Char       as  ASCII-import qualified ASCII.Superset   as  S--import Data.Data                  ( Data )-import Data.Maybe                 ( Maybe (..) )-import Language.Haskell.TH.Syntax ( Q, Exp, Pat, dataToExpQ, dataToPatQ )--{- $setup-->>> :set -XNoViewPatterns->>> import ASCII.Char (Char (..))->>> import ASCII.Refinement (ASCII)->>> import ASCII.Superset (toCharOrFail)->>> import ASCII.TemplateHaskell (charExp)->>> import Control.Monad ((>>=))->>> import Data.Word (Word8)---}--exp :: Data a => a -> Q Exp-exp = dataToExpQ (\_ -> Nothing)--pat :: Data a => a -> Q Pat-pat = dataToPatQ (\_ -> Nothing)--{- |-->>> $(toCharOrFail 'F' >>= charExp)-CapitalLetterF-->>> $(toCharOrFail '\DEL' >>= charExp)-Delete---}--charExp :: ASCII.Char -> Q Exp-charExp = exp--{- |-->>> :{->>> case SmallLetterS of->>>     $(toCharOrFail 'r' >>= charPat) -> 1->>>     $(toCharOrFail 's' >>= charPat) -> 2->>>     _                               -> 3->>> :}-2--This is the same as:-->>> :{->>> case SmallLetterS of->>>     SmallLetterR -> 1->>>     SmallLetterS -> 2->>>     _            -> 3->>> :}-2---}--charPat :: ASCII.Char -> Q Pat-charPat = pat--{- |-->>> $(charListExp [CapitalLetterH, SmallLetterI])-[CapitalLetterH,SmallLetterI]---}--charListExp :: [ASCII.Char] -> Q Exp-charListExp = exp--{- |-->>> :{->>> case [CapitalLetterH, SmallLetterI] of->>>     $(charListPat [CapitalLetterH, SmallLetterA]) -> 1->>>     $(charListPat [CapitalLetterH, SmallLetterI]) -> 2->>>     _                                             -> 3->>> :}-2---}--charListPat :: [ASCII.Char] -> Q Pat-charListPat = pat--{- |-->>> $(isCharExp CapitalLetterA) :: ASCII.Char-CapitalLetterA-->>> $(isCharExp CapitalLetterA) :: Word8-65-->>> $(isCharExp CapitalLetterA) :: ASCII Word8-asciiUnsafe 65---}--isCharExp :: ASCII.Char -> Q Exp-isCharExp x = [| S.fromChar $(charExp x) |]--{- |-->>> :set -XViewPatterns-->>> :{->>> case (66 :: Word8) of->>>     $(isCharPat CapitalLetterA) -> 1->>>     $(isCharPat CapitalLetterB) -> 2->>>     _                           -> 3->>> :}-2---}--isCharPat :: ASCII.Char -> Q Pat-isCharPat x = [p| (S.toCharMaybe -> Just $(charPat x)) |]--isStringExp :: [ASCII.Char] -> Q Exp-isStringExp xs = [| S.fromCharList $(charListExp xs) |]--isStringPat :: [ASCII.Char] -> Q Pat-isStringPat xs = [p| (S.toCharListMaybe -> Just $(charListPat xs)) |]
ascii-th.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.0  name: ascii-th-version: 1.0.0.4+version: 1.0.0.6 synopsis: Template Haskell support for ASCII 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@@ -33,6 +31,7 @@     default-extensions: QuasiQuotes     default-extensions: ViewPatterns     ghc-options: -Wall+    hs-source-dirs: library      build-depends: ascii-char       ^>= 1.0     build-depends: ascii-superset   ^>= 1.0@@ -42,3 +41,16 @@      exposed-modules: ASCII.TemplateHaskell     exposed-modules: ASCII.QuasiQuoters++test-suite test+    type: exitcode-stdio-1.0+    default-language: Haskell2010+    default-extensions: NoImplicitPrelude+    default-extensions: OverloadedStrings+    default-extensions: QuasiQuotes+    default-extensions: TemplateHaskell+    default-extensions: ViewPatterns+    ghc-options: -Wall -fno-warn-overlapping-patterns+    hs-source-dirs: test+    main-is: test.hs+    build-depends: ascii-char, ascii-superset, ascii-th, base, bytestring, text
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/QuasiQuoters.hs view
@@ -0,0 +1,105 @@+module ASCII.QuasiQuoters ( char, string ) where++import ASCII.Char                  ( Char )+import ASCII.Superset              ( toCharMaybe, toCharListMaybe )+import ASCII.TemplateHaskell       ( isCharExp, isCharPat, isStringExp, isStringPat )+import Control.Monad               ( (>=>), return )+import Control.Monad.Fail          ( MonadFail, fail )+import Data.Maybe                  ( Maybe (..) )+import Language.Haskell.TH.Quote   ( QuasiQuoter (..) )+import Language.Haskell.TH.Syntax  ( Q, Exp, Pat )++import qualified Data.Char   as Unicode+import qualified Data.String as Unicode++{- | Produces an expression or a pattern corresponding to an ASCII character.++The result will have an 'ASCII.Superset.CharSuperset' constraint; since this is polymorphic, use with a type signature to specify the particular you want is recommended.++The quasi-quoted string must consist of a single character that is within the ASCII character set.++>>> :set -XQuasiQuotes++>>> [char|e|] :: ASCII.Char+SmallLetterE++>>> [char|e|] :: Word8+101++Use in a pattern context requires enabling the @ViewPatterns@ language extension.++>>> :set -XViewPatterns++>>> case Tilde of [char|@|] -> 1; [char|~|] -> 2; _ -> 3+2++-}++char :: QuasiQuoter+char = expPatQQ requireOneAscii isCharExp isCharPat++{- | Produces an expression or a pattern corresponding to an ASCII string.++The result will have an 'ASCII.Superset.StringSuperset' constraint; since this is polymorphic, use with a type signature to specify the particular you want is recommended.++The quasi-quoted string must consist only of characters are within the ASCII character set.++>>> :set -XQuasiQuotes++>>> [string|Hello!|] :: [ASCII.Char]+[CapitalLetterH,SmallLetterE,SmallLetterL,SmallLetterL,SmallLetterO,ExclamationMark]++>>> [string|Hello!|] :: Data.String.String+"Hello!"++>>> [string|Hello!|] :: Data.Text.Text+"Hello!"++>>> Data.ByteString.Builder.toLazyByteString [string|Hello!|]+"Hello!"+++Use in a pattern context requires enabling the @ViewPatterns@ language extension.++>>> :set -XViewPatterns++>>> case [CapitalLetterH, SmallLetterI] of [string|Bye|] -> 1; [string|Hi|] -> 2; _ -> 3+2++-}++string :: QuasiQuoter+string = expPatQQ requireAsciiList isStringExp isStringPat++requireOneAscii :: Unicode.String -> Q Char+requireOneAscii = requireOne >=> requireAscii++oneMaybe :: [a] -> Maybe a+oneMaybe xs = case xs of [x] -> Just x; _ -> Nothing++requireOne :: Unicode.String -> Q Unicode.Char+requireOne = oneMaybe || "Must be exactly one character."++requireAscii :: Unicode.Char -> Q Char+requireAscii = toCharMaybe || "Must be an ASCII character."++requireAsciiList :: Unicode.String -> Q [Char]+requireAsciiList = toCharListMaybe || "Must be only ASCII characters."++(||) :: (a -> Maybe b) -> Unicode.String -> a -> Q b+f || msg = \a -> case f a of Just b -> return b; Nothing -> fail msg++expPatQQ :: (Unicode.String -> Q a) -> (a -> Q Exp) -> (a -> Q Pat) -> QuasiQuoter+expPatQQ f a b =+    QuasiQuoter+        { quoteExp  = f >=> a+        , quotePat  = f >=> b+        , quoteType = notType+        , quoteDec  = notDec+        }++notType :: MonadFail m => a -> m b+notType _ = fail "Cannot be used in a type context."++notDec :: MonadFail m => a -> m b+notDec _ = fail "Cannot be used in a declaration context."
+ library/ASCII/TemplateHaskell.hs view
@@ -0,0 +1,123 @@+module ASCII.TemplateHaskell (++    {- * Characters          -} charExp,     charPat,+    {- * Character lists     -} charListExp, charListPat,+    {- * Character supersets -} isCharExp,   isCharPat,+    {- * String supersets    -} isStringExp, isStringPat++  ) where++import qualified ASCII.Char       as  ASCII+import qualified ASCII.Superset   as  S++import Data.Data                  ( Data )+import Data.Maybe                 ( Maybe (..) )+import Language.Haskell.TH.Syntax ( Q, Exp, Pat, dataToExpQ, dataToPatQ )++exp :: Data a => a -> Q Exp+exp = dataToExpQ (\_ -> Nothing)++pat :: Data a => a -> Q Pat+pat = dataToPatQ (\_ -> Nothing)++{- |++>>> $(toCharOrFail 'F' >>= charExp)+CapitalLetterF++>>> $(toCharOrFail '\DEL' >>= charExp)+Delete++-}++charExp :: ASCII.Char -> Q Exp+charExp = exp++{- |++>>> :{+>>> case SmallLetterS of+>>>     $(toCharOrFail 'r' >>= charPat) -> 1+>>>     $(toCharOrFail 's' >>= charPat) -> 2+>>>     _                               -> 3+>>> :}+2++This is the same as:++>>> :{+>>> case SmallLetterS of+>>>     SmallLetterR -> 1+>>>     SmallLetterS -> 2+>>>     _            -> 3+>>> :}+2++-}++charPat :: ASCII.Char -> Q Pat+charPat = pat++{- |++>>> $(charListExp [CapitalLetterH, SmallLetterI])+[CapitalLetterH,SmallLetterI]++-}++charListExp :: [ASCII.Char] -> Q Exp+charListExp = exp++{- |++>>> :{+>>> case [CapitalLetterH, SmallLetterI] of+>>>     $(charListPat [CapitalLetterH, SmallLetterA]) -> 1+>>>     $(charListPat [CapitalLetterH, SmallLetterI]) -> 2+>>>     _                                             -> 3+>>> :}+2++-}++charListPat :: [ASCII.Char] -> Q Pat+charListPat = pat++{- |++>>> $(isCharExp CapitalLetterA) :: ASCII.Char+CapitalLetterA++>>> $(isCharExp CapitalLetterA) :: Word8+65++>>> $(isCharExp CapitalLetterA) :: ASCII Word8+asciiUnsafe 65++-}++isCharExp :: ASCII.Char -> Q Exp+isCharExp x = [| S.fromChar $(charExp x) |]++{- |++>>> :set -XViewPatterns++>>> :{+>>> case (66 :: Word8) of+>>>     $(isCharPat CapitalLetterA) -> 1+>>>     $(isCharPat CapitalLetterB) -> 2+>>>     _                           -> 3+>>> :}+2++-}++isCharPat :: ASCII.Char -> Q Pat+isCharPat x = [p| (S.toCharMaybe -> Just $(charPat x)) |]++isStringExp :: [ASCII.Char] -> Q Exp+isStringExp xs = [| S.fromCharList $(charListExp xs) |]++isStringPat :: [ASCII.Char] -> Q Pat+isStringPat xs = [p| (S.toCharListMaybe -> Just $(charListPat xs)) |]
+ test/test.hs view
@@ -0,0 +1,73 @@+module Main where++import ASCII.QuasiQuoters+import ASCII.TemplateHaskell++import ASCII.Char (Char (..))+import ASCII.Refinement (ASCII, asciiUnsafe)+import ASCII.Superset (toCharOrFail)++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.Semigroup ((<>))+import Data.String (String)+import Data.Text (Text)+import Data.Word (Word8)+import Numeric.Natural (Natural)+import Prelude (Integer)+import System.Exit (die)+import System.IO (IO, putStrLn)+import Text.Show (show)++import qualified Data.ByteString.Builder as BS.Builder++main :: IO ()+main = dieIfFailures $ do+    test 1 $ ([char|e|] :: Char) == SmallLetterE+    test 2 $ ([char|e|] :: Word8) == 101+    test 3 $ (case Tilde of [char|@|] -> 1 :: Integer; [char|~|] -> 2; _ -> 3) == 2+    test 4 $ ([string|Hello!|] :: [Char]) == [CapitalLetterH, SmallLetterE, SmallLetterL, SmallLetterL, SmallLetterO, ExclamationMark]+    test 5 $ ([string|Hello!|] :: String) == "Hello!"+    test 6 $ ([string|Hello!|] :: Text) == "Hello!"+    test 7 $ (BS.Builder.toLazyByteString [string|Hello!|] == "Hello!")+    test 8 $ (case [CapitalLetterH, SmallLetterI] of [string|Bye|] -> 1 :: Integer; [string|Hi|] -> 2; _ -> 3) == 2+    test 9 $ $(toCharOrFail 'F' >>= charExp) == CapitalLetterF+    test 10 $ $(toCharOrFail '\DEL' >>= charExp) == Delete+    test 11 $ case SmallLetterS of { $(toCharOrFail 'r' >>= charPat) -> 1 :: Integer; $(toCharOrFail 's' >>= charPat) -> 2; _ -> 3 } == 2+    test 12 $ $(charListExp [CapitalLetterH, SmallLetterI]) == [CapitalLetterH, SmallLetterI]+    test 13 $ case [CapitalLetterH, SmallLetterI] of { $(charListPat [CapitalLetterH, SmallLetterA]) -> 1 :: Integer; $(charListPat [CapitalLetterH, SmallLetterI]) -> 2; _ -> 3 } == 2+    test 14 $ ($(isCharExp CapitalLetterA) :: Char) == CapitalLetterA+    test 15 $ ($(isCharExp CapitalLetterA) :: Word8) == 65+    test 16 $ ($(isCharExp CapitalLetterA) :: ASCII Word8) == asciiUnsafe 65+    test 17 $ case (66 :: Word8) of { $(isCharPat CapitalLetterA) -> 1 :: Integer; $(isCharPat CapitalLetterB) -> 2; _ -> 3 } == 2++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