module Cgm.Data.Super (
Super(..),
up,
superSInc,
narrowIntegral,
module Cgm.Data.Maybe,
module Cgm.Control.InFunctor
) where
import Data.Int
import Data.Word
import Data.Bits
import Control.Applicative
import Cgm.Data.Maybe
import Cgm.Control.InFunctor
class Super a b where
super :: InjectionM' a b
superSInc :: Super a b => a :>> b
superSInc = uncheckedStrictlyIncreasing (apply super)
up :: Super a b => a -> b
up = apply super
instance Super Word8 Word64 where super = integralInjectionMaxOnly
instance Super Word8 Word32 where super = integralInjectionMaxOnly
instance Super Word8 Word16 where super = integralInjectionMaxOnly
instance Super Word16 Word64 where super = integralInjectionMaxOnly
instance Super Word16 Word32 where super = integralInjectionMaxOnly
instance Super Word32 Word64 where super = integralInjectionMaxOnly
instance Super Word8 Word where super = integralInjectionMaxOnly
instance Super Word16 Word where super = integralInjectionMaxOnly
instance Super Word32 Word where super = integralInjectionMaxOnly
instance Super Word Word64 where super = integralInjectionMaxOnly
instance Super Word8 Integer where super = integralInjection
integralInjectionMaxOnly :: forall a b. (Integral a, Integral b, Bounded a) => InjectionM' a b
integralInjectionMaxOnly = uncheckedInjectionM fromIntegral narrowIntegralMaxOnly
integralInjection :: forall a b. (Integral a, Integral b, Bounded a) => InjectionM' a b
integralInjection = uncheckedInjectionM fromIntegral narrowIntegral
narrowIntegral :: forall a b. (Integral a, Integral b, Bounded b) => a -> Maybe b
narrowIntegral = (fromIntegral <$>) . predJust (\a -> fromIntegral (minBound :: b) <= a && a <= fromIntegral (maxBound :: b))
narrowIntegralMaxOnly :: forall a b. (Integral a, Integral b, Bounded b) => a -> Maybe b
narrowIntegralMaxOnly = (fromIntegral <$>) . predJust (<= fromIntegral (maxBound :: b))