給定兩個Symbolsa和b,創建另一個符號的最簡單方法是什么,它等同于b但它的前綴a被剝離,其余的變成小寫和 slugified?
例如,如何實作這種型別族RoutePath "Foo" "Foo_BarQux" == "bar-qux"(烤肉串是可選的)?
type family RoutePath datatype constr where
RoutePath datatype constr = undefined -- TODO
GHC.TypeLits確實提供UnconsSymbol了我可以用來從頭開始實作這種東西,但感覺太低級了。我想知道是否有一個現有的解決方案(也許是一個庫),我可以采用它來使我的庫中的代碼更小更簡單。
對于真實的背景關系,請參閱此 PR,尤其是Constructor2RoutePath型別族。
uj5u.com熱心網友回復:
symbols包裹
我遇到了符號包。它提供了一個ToList (sym :: Symbol) :: [Symbol]型別族,使我能夠將其Symbol作為串列進行處理,但是,我了解到它使編譯變得非常緩慢。這是代碼。
GHC 9.2UnconsSymbol
這讓我別無選擇,只能升級到 GHC 9.2。從好的方面來說,編譯和以前一樣迅速。這是完整的實作:
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
鏈接到重寫。
它并不像我發布這個問題時想象的那么復雜。雖然它不會進行 Kebab 案例轉換,但我想這并不太復雜。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/497528.html
