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)) |]