{-# OPTIONS_GHC -fplugin=GHC.TypeLits.KnownNat.Solver #-}
{-# LANGUAGE GADTs #-}
module Clash.Hedgehog.Sized.Index
( genIndex
, SomeIndex(..)
, genSomeIndex
) where
import GHC.Natural (Natural)
import GHC.TypeNats
import Hedgehog (MonadGen, Range)
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import Clash.Promoted.Nat
import Clash.Sized.Internal.Index
genIndex :: (MonadGen m, KnownNat n) => Range (Index n) -> m (Index n)
genIndex :: Range (Index n) -> m (Index n)
genIndex Range (Index n)
range =
[(Int, m (Index n))] -> m (Index n)
forall (m :: Type -> Type) a. MonadGen m => [(Int, m a)] -> m a
Gen.frequency
[ (Int
60, Range (Index n) -> m (Index n)
forall (m :: Type -> Type) a.
(MonadGen m, Integral a) =>
Range a -> m a
Gen.integral Range (Index n)
range)
, (Int
20, Index n -> m (Index n)
forall (m :: Type -> Type) a. MonadGen m => a -> m a
Gen.constant Index n
forall a. Bounded a => a
minBound)
, (Int
20, Index n -> m (Index n)
forall (m :: Type -> Type) a. MonadGen m => a -> m a
Gen.constant Index n
forall a. Bounded a => a
maxBound)
]
data SomeIndex atLeast where
SomeIndex :: SNat n -> Index (atLeast + n) -> SomeIndex atLeast
genSomeIndex
:: (MonadGen m, KnownNat atLeast)
=> Range Natural
-> m (SomeIndex atLeast)
genSomeIndex :: Range Natural -> m (SomeIndex atLeast)
genSomeIndex Range Natural
rangeIx = do
Natural
numExtra <- Range Natural -> m Natural
forall (m :: Type -> Type) a.
(MonadGen m, Integral a) =>
Range a -> m a
Gen.integral Range Natural
rangeIx
case Natural -> SomeNat
someNatVal Natural
numExtra of
SomeNat Proxy n
proxy -> SNat n -> Index (atLeast + n) -> SomeIndex atLeast
forall (n :: Nat) (atLeast :: Nat).
SNat n -> Index (atLeast + n) -> SomeIndex atLeast
SomeIndex (Proxy n -> SNat n
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> SNat n
snatProxy Proxy n
proxy) (Index (atLeast + n) -> SomeIndex atLeast)
-> m (Index (atLeast + n)) -> m (SomeIndex atLeast)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Range (Index (atLeast + n)) -> m (Index (atLeast + n))
forall (m :: Type -> Type) (n :: Nat).
(MonadGen m, KnownNat n) =>
Range (Index n) -> m (Index n)
genIndex Range (Index (atLeast + n))
forall a. (Bounded a, Integral a) => Range a
Range.linearBounded