i-0.1: hs/I/Word8.hs
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
{-# OPTIONS_HADDOCK not-home #-}
module I.Word8 () where
import Control.Monad
import Data.Constraint
import Data.Maybe
import Data.Proxy
import Data.Word
import Data.Type.Ord
import Foreign.C.Types
import GHC.TypeLits qualified as L
import KindInteger (type (/=))
import Prelude hiding (min, max, div)
import I.Internal
--------------------------------------------------------------------------------
-- | This is so that GHC doesn't complain about the unused modules,
-- which we import here so that `genmodules.sh` doesn't have to add it
-- to the generated modules.
_ignore :: (CSize, Word)
_ignore = (0, 0)
--------------------------------------------------------------------------------
type instance MinL Word8 = MinT Word8
type instance MaxR Word8 = MaxT Word8
instance forall l r.
( IntervalCtx Word8 l r
) => Interval Word8 l r where
type IntervalCtx Word8 l r =
( L.KnownNat l
, L.KnownNat r
, MinT Word8 <= l
, l <= r
, r <= MaxT Word8 )
type MinI Word8 l r = l
type MaxI Word8 l r = r
inhabitant = min
from = \x -> unsafest x <$ guard (l <= x && x <= r)
where l = fromInteger (L.natVal (Proxy @l)) :: Word8
r = fromInteger (L.natVal (Proxy @r)) :: Word8
(unwrap -> a) `plus'` (unwrap -> b) = do
guard (b <= maxBound - a)
from (a + b)
(unwrap -> a) `mult'` (unwrap -> b) = do
guard (b == 0 || a <= maxBound `quot` b)
from (a * b)
(unwrap -> a) `minus'` (unwrap -> b) = do
guard (b <= a)
from (a - b)
(unwrap -> a) `div'` (unwrap -> b) = do
guard (b /= 0)
let (q, m) = divMod a b
guard (m == 0)
from q
instance (Interval Word8 l r) => Clamp Word8 l r
instance (Interval Word8 ld rd, Interval Word8 lu ru, lu <= ld, rd <= ru)
=> Up Word8 ld rd lu ru
instance forall l r t.
( Interval Word8 l r, KnownCtx Word8 l r t
) => Known Word8 l r t where
type KnownCtx Word8 l r t = (L.KnownNat t, l <= t, t <= r)
known' = unsafe . fromInteger . L.natVal
instance forall l r. (Interval Word8 l r) => With Word8 l r where
with x g = fromMaybe (error "I.with: impossible") $ do
L.SomeNat (pt :: Proxy t) <- L.someNatVal (toInteger (unwrap x))
Dict <- leNatural @l @t
Dict <- leNatural @t @r
pure (g pt)
instance (Interval Word8 l r, l /= r) => Discrete Word8 l r where
pred' i = unsafe (unwrap i - 1) <$ guard (min < i)
succ' i = unsafe (unwrap i + 1) <$ guard (i < max)
instance (Interval Word8 0 r) => Zero Word8 0 r where
zero = unsafe 0
instance (Interval Word8 l r, l <= 1, 1 <= r) => One Word8 l r where
one = unsafe 1
instance forall l r. (Interval Word8 l r) => Shove Word8 l r where
shove = \x -> unsafe $ fromInteger (mod (toInteger x) (r - l + 1) + l)
where l = toInteger (unwrap (min @Word8 @l @r))
r = toInteger (unwrap (max @Word8 @l @r))