Во-первых, было бы неплохо, если бы вы объяснили, что вы хотите. Я беру это по ссылке, что вы хотите, чтобы во время компиляции перевод римских цифр на Num a => a
, но, возможно, я не получил это точно в моем кратком чтении.
Я не понимаю, почему дополнительный синтаксис TH является проблемой, но я думаю, что вы можете сделать это без Template Haskell. Можно было бы использовать квазиквотер, что привело бы к синтаксису вроде:
[r|XXVI|]
Но это все еще не очень чисто.
Другой способ - интерпретатор для типа данных римских цифр:
data Roman = M Roman | D Roman | C Roman | X Roman | V Roman | I Roman | O
romanToInt :: Roman -> Int
romanToInt = ...
-- or use a shorter function name for obvious reasons.
r = romanToInt
{-# rewrite
"Roman M" forall n. romanToInt (M n) -> 1000 + romanToInt n
#-}
-- many more rewrite rules are needed to ensure the simplifier does the work
-- The resulting syntax would have spaces:
val95 = r (V C)
Или, возможно, -O2
от ghc уже оптимизирует вызовы Integer? Я не уверен в этом, но если это так, то вы можете просто использовать тривиальный Integral
экземпляр:
instance Integral Roman where
toInteger (M n) = 1000 + toInteger n
...