{-# LANGUAGE AllowAmbiguousTypes #-} module Literate.Accounting.Unit where import Literate.Prelude import Text.Show (ShowS, showParen, showString) data Unit where UnitName :: Symbol -> Unit (:*:) :: Unit -> Unit -> Unit (:/:) :: Unit -> Unit -> Unit class UnitShowS (u :: Unit) where unitShowS :: Int -> ShowS instance KnownSymbol u => UnitShowS (UnitName u) where unitShowS _prec = showString (symbolVal (Proxy @u)) instance (UnitShowS x, UnitShowS y) => UnitShowS (x :*: y) where unitShowS p = showParen (7 <= p) $ unitShowS @x 7 . showString "\x202F*\x202F" . unitShowS @y 7 instance (UnitShowS x, UnitShowS y) => UnitShowS (x :/: y) where unitShowS p = showParen (7 <= p) $ unitShowS @x 7 . showString "\x202F/\x202F" . unitShowS @y 7 unitShow :: forall u. UnitShowS u => String unitShow = unitShowS @u 0 ""