module Text.Numeral.Render
(
render
, Repr(..)
, ScaleRepr
, defaultRepr
, Ctx(..)
, posIndex
, isOutside
)
where
import "base" Data.Bool ( Bool(False, True), otherwise )
import "base" Data.Eq ( Eq )
import "base" Data.Function ( ($) )
import "base" Data.Functor ( (<$>) )
import "base" Data.Maybe ( Maybe(Nothing, Just) )
import "base" Prelude ( (+) )
import "base" Text.Show ( Show )
import "base-unicode-symbols" Data.Eq.Unicode ( (≡) )
import "base-unicode-symbols" Data.Monoid.Unicode ( (⊕) )
import "base-unicode-symbols" Prelude.Unicode ( ℤ )
import "text" Data.Text ( Text )
import "this" Text.Numeral.Exp.Reified ( Exp(..), Side(L, R) )
render ∷ Repr i
→ i
→ Exp i
→ Maybe Text
render (Repr {..}) = go CtxEmpty
where
go _ _ Unknown = reprUnknown
go ctx inf (Lit n) = ($ ctx) <$> reprValue inf n
go ctx inf (Neg x) = do x' ← go (CtxNeg ctx) inf x
rn ← reprNeg
rnc ← reprNegCombine
Just $ rnc (rn x ctx) x' x
go ctx inf (Add x y) = do x' ← go (CtxAdd L y ctx) inf x
y' ← go (CtxAdd R x ctx) inf y
ra ← reprAdd
rac ← reprAddCombine
Just $ rac (ra x y ctx) x' x y' y
go ctx inf (Mul x y) = do x' ← go (CtxMul L y ctx) inf x
y' ← go (CtxMul R x ctx) inf y
rm ← reprMul
rmc ← reprMulCombine
Just $ rmc (rm x y ctx) x' x y' y
go ctx inf (Sub x y) = do x' ← go (CtxSub L y ctx) inf x
y' ← go (CtxSub R x ctx) inf y
rs ← reprSub
rsc ← reprSubCombine
Just $ rsc (rs x y ctx) x' x y' y
go ctx inf (Frac x y) = do x' ← go (CtxFrac L y ctx) inf x
y' ← go (CtxFrac R x ctx) inf y
rf ← reprFrac
rfc ← reprFracCombine
Just $ rfc (rf x y ctx) x' x y' y
go ctx inf (Scale b o r) = reprScale inf b o r ctx
go ctx inf (Dual x) = go (CtxDual ctx) inf x
go ctx inf (Plural x) = go (CtxPlural ctx) inf x
go ctx inf (Inflection f x) = go ctx (f inf) x
data Repr i =
Repr
{
reprUnknown ∷ Maybe Text
, reprValue ∷ i → ℤ → Maybe (Ctx (Exp i) → Text)
, reprNeg ∷ Maybe (Exp i → Ctx (Exp i) → Text)
, reprAdd ∷ Maybe (Exp i → Exp i → Ctx (Exp i) → Text)
, reprMul ∷ Maybe (Exp i → Exp i → Ctx (Exp i) → Text)
, reprSub ∷ Maybe (Exp i → Exp i → Ctx (Exp i) → Text)
, reprFrac ∷ Maybe (Exp i → Exp i → Ctx (Exp i) → Text)
, reprScale ∷ ScaleRepr i
, reprNegCombine ∷ Maybe (Text → Text → Exp i → Text)
, reprAddCombine ∷ Maybe (Text → Text → Exp i → Text → Exp i → Text)
, reprMulCombine ∷ Maybe (Text → Text → Exp i → Text → Exp i → Text)
, reprSubCombine ∷ Maybe (Text → Text → Exp i → Text → Exp i → Text)
, reprFracCombine ∷ Maybe (Text → Text → Exp i → Text → Exp i → Text)
}
type ScaleRepr i = i
→ ℤ
→ ℤ
→ Exp i
→ Ctx (Exp i)
→ Maybe Text
defaultRepr ∷ Repr inf
defaultRepr =
Repr { reprUnknown = Nothing
, reprValue = \_ _ → Nothing
, reprNeg = Nothing
, reprAdd = Nothing
, reprMul = Nothing
, reprSub = Nothing
, reprFrac = Nothing
, reprScale = \_ _ _ _ _ → Nothing
, reprNegCombine = Just $ \n x _ → n ⊕ x
, reprAddCombine = Just $ \a x _ y _ → x ⊕ a ⊕ y
, reprMulCombine = Just $ \m x _ y _ → x ⊕ m ⊕ y
, reprSubCombine = Just $ \s x _ y _ → x ⊕ s ⊕ y
, reprFracCombine = Just $ \f n _ d _ → n ⊕ f ⊕ d
}
data Ctx α
= CtxEmpty
| CtxNeg (Ctx α)
| CtxAdd Side α (Ctx α)
| CtxMul Side α (Ctx α)
| CtxSub Side α (Ctx α)
| CtxFrac Side α (Ctx α)
| CtxScale (Ctx α)
| CtxDual (Ctx α)
| CtxPlural (Ctx α)
deriving (Eq, Show)
posIndex ∷ Ctx α → ℤ
posIndex c = go 0 c
where
go ∷ ℤ → Ctx α → ℤ
go acc CtxEmpty = acc
go acc (CtxNeg nc) = go acc nc
go acc (CtxAdd as _ ac) = go (acc + if as ≡ L then 1 else 1) ac
go acc (CtxMul ms _ mc) = go (acc + if ms ≡ L then 1 else 1) mc
go acc (CtxSub ss _ sc) = go (acc + if ss ≡ L then 1 else 1) sc
go acc (CtxFrac fs _ fc) = go (acc + if fs ≡ L then 1 else 1) fc
go acc (CtxScale sc) = go acc sc
go acc (CtxDual dc) = go acc dc
go acc (CtxPlural pc) = go acc pc
isOutside ∷ Side → Ctx α → Bool
isOutside s c = go c
where
go ∷ Ctx α → Bool
go CtxEmpty = True
go (CtxNeg nc) = go nc
go (CtxAdd as _ ac) | as ≡ s = go ac
| otherwise = False
go (CtxMul ms _ mc) | ms ≡ s = go mc
| otherwise = False
go (CtxSub ss _ sc) | ss ≡ s = go sc
| otherwise = False
go (CtxFrac fs _ fc) | fs ≡ s = go fc
| otherwise = False
go (CtxScale sc) = go sc
go (CtxDual dc) = go dc
go (CtxPlural pc) = go pc