{-# LANGUAGE UndecidableInstances #-} module GHC.TypeLits.Extra.Symbol ( StripPrefix, ToLower, ) where import GHC.TypeLits (ConsSymbol, Symbol, UnconsSymbol) -- | Strip `prefix` from `symbol`. Return `symbol` as-is if the prefix doesn't match. type family StripPrefix (prefix :: Symbol) (symbol :: Symbol) :: Symbol where StripPrefix prefix symbol = FromMaybe symbol (StripPrefix' (UnconsSymbol prefix) (UnconsSymbol symbol)) -- | Strip `prefix` from `symbol`. Return Nothing if the prefix doesn't match. type family StripPrefix' (prefix :: Maybe (Char, Symbol)) (symbol :: Maybe (Char, Symbol)) :: Maybe Symbol where StripPrefix' 'Nothing 'Nothing = 'Just "" StripPrefix' 'Nothing ( 'Just '(x, xs)) = 'Just (ConsSymbol x xs) StripPrefix' _p 'Nothing = 'Nothing StripPrefix' ( 'Just '(p, ps)) ( 'Just '(p, ss)) = StripPrefix' (UnconsSymbol ps) (UnconsSymbol ss) StripPrefix' ( 'Just '(p, ps)) ( 'Just '(_, ss)) = 'Nothing type family ToLower (sym :: Symbol) :: Symbol where ToLower sym = ToLower' (UnconsSymbol sym) type family ToLower' (pair :: Maybe (Char, Symbol)) :: Symbol where ToLower' 'Nothing = "" ToLower' ( 'Just '(c, cs)) = ConsSymbol (ToLowerC c) (ToLower' (UnconsSymbol cs)) type family ToLowerC (c :: Char) :: Char where ToLowerC 'A' = 'a' ToLowerC 'B' = 'b' ToLowerC 'C' = 'c' ToLowerC 'D' = 'd' ToLowerC 'E' = 'e' ToLowerC 'F' = 'f' ToLowerC 'G' = 'g' ToLowerC 'H' = 'h' ToLowerC 'I' = 'i' ToLowerC 'J' = 'j' ToLowerC 'K' = 'k' ToLowerC 'L' = 'l' ToLowerC 'M' = 'm' ToLowerC 'N' = 'n' ToLowerC 'O' = 'o' ToLowerC 'P' = 'p' ToLowerC 'Q' = 'q' ToLowerC 'R' = 'r' ToLowerC 'S' = 's' ToLowerC 'T' = 't' ToLowerC 'U' = 'u' ToLowerC 'V' = 'v' ToLowerC 'W' = 'w' ToLowerC 'X' = 'x' ToLowerC 'Y' = 'y' ToLowerC 'Z' = 'z' ToLowerC a = a type family FromMaybe (def :: a) (maybe :: Maybe a) :: a where FromMaybe def 'Nothing = def FromMaybe def ( 'Just a) = a