https://github.com/aiya000/hs-character-cases
A Haskell library for subspecies types of Char, and naming cases.
https://github.com/aiya000/hs-character-cases
haskelll parser-combinators quasiquoter template-haskell
Last synced: 20 days ago
JSON representation
A Haskell library for subspecies types of Char, and naming cases.
- Host: GitHub
- URL: https://github.com/aiya000/hs-character-cases
- Owner: aiya000
- License: mit
- Created: 2020-03-20T11:06:31.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2021-03-18T13:39:58.000Z (about 4 years ago)
- Last Synced: 2025-05-09T00:46:33.912Z (20 days ago)
- Topics: haskelll, parser-combinators, quasiquoter, template-haskell
- Language: Haskell
- Homepage: https://hackage.haskell.org/package/character-cases
- Size: 23.4 KB
- Stars: 8
- Watchers: 2
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# :diamond_shape_with_a_dot_inside: character-cases :diamond_shape_with_a_dot_inside:
[](https://hackage.haskell.org/package/character-cases)
A Haskell library for subspecies types of Char, and naming cases.
- Naming cases (String like)
```haskell
-- | [A-Z][a-zA-Z0-9]*
data Pascal = Pascal UpperChar [AlphaNumChar]
deriving (Show, Eq)-- | [a-z][a-zA-Z0-9]*
data Camel = Camel AlphaChar [AlphaNumChar]
deriving (Eq)-- | [a-zA-Z_][a-zA-Z0-9_]*
data Snake = Snake SnakeHeadChar [SnakeChar]
deriving (Show, Eq)-- | [A-Z_][A-Z0-9_]*
data UpperSnake = UpperSnake UpperSnakeHeadChar [UpperSnakeChar]
deriving (Show, Eq)-- | [a-z]+
data LowerString = LowerString LowerChar [LowerChar]
deriving (Show, Eq)-- | .+
data NonEmpty = NonEmpty Char String
deriving (Show, Eq)
```- Subspecies types (Char like)
```haskell
-- | [A-Z]
data UpperChar = ...
deriving (Show, Eq, Ord)-- | [a-z]
data LowerChar = ...
deriving (Show, Eq, Ord)-- | [0-9]
data DigitChar = ...
deriving (Show, Eq, Ord)-- | [A-Za-z]
data AlphaChar = ...
deriving (Show, Eq, Ord)-- | [A-Za-z0-9]
data AlphaNumChar = ...
deriving (Show, Eq, Ord)
```## Why we use this?
**Make impossible things to impossible** to strict `data` driven programming.
For example, in the first place,
- `List.NonEmpty a` wont be the empty list `[]`
also
- `Pascal` wont be other than `[A-Z][a-zA-Z0-9]*`
- `Camel` wont be other than `[a-z][a-zA-Z0-9]*`
- ...These are useful in
- Abstract Syntax Tree (Identifiers)
- ...**Make impossible things to impossible.**
## Usage
- [character-cases - Hackage](https://hackage.haskell.org/package/character-cases)
- [Data.Char.Cases](https://github.com/aiya000/hs-character-cases/blob/master/src/Data/Char/Cases.hs)
- [Data.String.Cases](https://github.com/aiya000/hs-character-cases/blob/master/src/Data/String/Cases.hs)### `QuasiQuoter`s
That ADT can be used directly, but `QuasiQuoter`s is more useful.
- Naming cases
```haskell
>>> [pascalQ|Pascal|]
Pascal P [AlphaNumAlpha (AlphaLower A_),AlphaNumAlpha (AlphaLower S_),AlphaNumAlpha (AlphaLower C_),AlphaNumAlpha (AlphaLower A_),AlphaNumAlpha (AlphaLower L_)]>>> [nonEmptyQ|x|]
NonEmpty 'x' ""
>>> [nonEmptyQ|foo|]
NonEmpty 'f' "oo"
>>> [nonEmptyQ|Bar|]
NonEmpty 'B' "ar">>> [camelQ|camel|]
"camel"
>>> [camelQ|Pascal|]
"Pascal">>> [snakeQ|foo_bar|]
Snake (SnakeHeadAlpha (AlphaLower F_)) [SnakeAlphaNum (AlphaNumAlpha (AlphaLower O_)),SnakeAlphaNum (AlphaNumAlpha (AlphaLower O_)),SnakeUnderscore,SnakeAlphaNum (AlphaNumAlpha (AlphaLower B_)),SnakeAlphaNum (AlphaNumAlpha (AlphaLower A_)),SnakeAlphaNum (AlphaNumAlpha (AlphaLower R_))]
>>> [snakeQ|__constructor|]
Snake SnakeHeadUnderscore [SnakeUnderscore,SnakeAlphaNum (AlphaNumAlpha (AlphaLower C_)),SnakeAlphaNum (AlphaNumAlpha (AlphaLower O_)),SnakeAlphaNum (AlphaNumAlpha (AlphaLower N_)),SnakeAlphaNum (AlphaNumAlpha (AlphaLower S_)),SnakeAlphaNum (AlphaNumAlpha (AlphaLower T_)),SnakeAlphaNum (AlphaNumAlpha (AlphaLower R_)),SnakeAlphaNum (AlphaNumAlpha (AlphaLower U_)),SnakeAlphaNum (AlphaNumAlpha (AlphaLower C_)),SnakeAlphaNum (AlphaNumAlpha (AlphaLower T_)),SnakeAlphaNum (AlphaNumAlpha (AlphaLower O_)),SnakeAlphaNum (AlphaNumAlpha (AlphaLower R_))]
>>> [snakeQ|FOO_MEE_9|]
Snake (SnakeHeadAlpha (AlphaUpper F)) [SnakeAlphaNum (AlphaNumAlpha (AlphaUpper O)),SnakeAlphaNum (AlphaNumAlpha (AlphaUpper O)),SnakeUnderscore,SnakeAlphaNum (AlphaNumAlpha (AlphaUpper M)),SnakeAlphaNum (AlphaNumAlpha (AlphaUpper E)),SnakeAlphaNum (AlphaNumAlpha (AlphaUpper E)),SnakeUnderscore,SnakeAlphaNum (AlphaNumDigit D9)]>>> [lowerStringQ|imavimmer|]
LowerString I_ [M_,A_,V_,I_,M_,M_,E_,R_]
```- Characters
```haskell
>>> [upperCharQ|X|]
X>>> [lowerCharQ|x|]
X_>>> [digitCharQ|0|]
D0>>> [alphaNumCharQ|X|]
AlphaNumAlpha (AlphaUpper X)>>> [alphaNumCharQ|x|]
AlphaNumAlpha (AlphaLower X_)>>> [alphaNumCharQ|0|]
AlphaNumDigit D0>>> [snakeCharQ|_|]
SnakeUnderscore
```Wrong cases will be rejected on **the compile time**!
```haskell
>>> [upperCharQ|x|]
error:
• ''x'' is not an UpperChar.
• In the quasi-quotation: [upperCharQ|x|]>>> [lowerCharQ|X|]
error:
• ''X'' is not a LowerChar.
• In the quasi-quotation: [lowerCharQ|X|]>>> [alphaNumCharQ|one or more characters|]
error:
• alphaNumCharQ required a Char, but a String is specified: one or more characters
• In the quasi-quotation: [alphaNumCharQ|one or more characters|]
``````haskell
>>> [pascalQ|camel|]
error:
• ''c'' is not an UpperChar.
• In the quasi-quotation: [pascalQ|camel|]>>> [nonEmptyQ||]
error:
• nonEmptyQ required a non empty string, but the empty string is specified.
• In the quasi-quotation: [nonEmptyQ||]>>> [camelQ|snake_case|]
error:
• ''_'' is not an AlphaNumChar.
• In the quasi-quotation: [camelQ|snake_case|]>>> [lowerStringQ|Upper|]
error:
• ''U'' is not a LowerChar.
• In the quasi-quotation: [lowerStringQ|Upper|]
```Please also see doctests of modules.
- [Data.Char.Cases](https://github.com/aiya000/hs-character-cases/blob/master/src/Data/Char/Cases.hs)
- [Data.String.Cases](https://github.com/aiya000/hs-character-cases/blob/master/src/Data/String/Cases.hs)### Parser combinators
And we can use it as parser combinators.
Please see modules and documents.
- [character-cases - Hackage](https://hackage.haskell.org/package/character-cases)