module Generics.EMGM.Data.Ratio (
RatioS,
conRatio,
repRatio,
frepRatio,
frep2Ratio,
frep3Ratio,
bifrep2Ratio,
) where
import Data.Ratio (Ratio, (%), numerator, denominator)
import Control.Applicative (Alternative, pure)
import Generics.EMGM.Base
import Generics.EMGM.Functions.Collect
import Generics.EMGM.Functions.Everywhere
import Generics.EMGM.Functions.Meta
type RatioS a = a :*: a
epRatio :: (Integral a) => EP (Ratio a) (a :*: a)
epRatio = EP f t
where
f r = numerator r :*: denominator r
t (num :*: det) = num % det
instance (Integral a) => HasEP (Ratio a) (RatioS a) where
epOf _ = epRatio
conRatio :: ConDescr
conRatio = ConDescr "%" 2 False (Infix LeftAssoc 7)
repRatio :: (Integral a, Generic g, Rep g a) => g (Ratio a)
repRatio = rtype epRatio (rcon conRatio (rep `rprod` rep))
frepRatio :: (Integral a, Generic g) => g a -> g (Ratio a)
frepRatio a = rtype epRatio (rcon conRatio (a `rprod` a))
frep2Ratio
:: (Integral a1, Integral a2, Generic2 g)
=> g a1 a2 -> g (Ratio a1) (Ratio a2)
frep2Ratio a = rtype2 epRatio epRatio (rcon2 conRatio (a `rprod2` a))
frep3Ratio
:: (Integral a1, Integral a2, Integral a3, Generic3 g)
=> g a1 a2 a3 -> g (Ratio a1) (Ratio a2) (Ratio a3)
frep3Ratio a = rtype3 epRatio epRatio epRatio (rcon3 conRatio (a `rprod3` a))
bifrep2Ratio
:: (Integral a1, Integral a2, Generic2 g)
=> g a1 a2 -> g (Ratio a1) (Ratio a2)
bifrep2Ratio a = rtype2 epRatio epRatio (rcon2 conRatio (a `rprod2` a))
instance (Integral a, Generic g, Rep g a) => Rep g (Ratio a) where
rep = repRatio
instance (Alternative f) => Rep (Collect f (Ratio a)) (Ratio a) where
rep = Collect pure
instance (Integral a, Rep (Everywhere (Ratio a)) a)
=> Rep (Everywhere (Ratio a)) (Ratio a) where
rep = Everywhere app
where
app f r = f $
selEverywhere rep f (numerator r) % selEverywhere rep f (denominator r)
instance Rep (Everywhere' (Ratio a)) (Ratio a) where
rep = Everywhere' ($)