{-# LANGUAGE BangPatterns #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} module Internal.Test.QuickCheck.Quid.Representations where import Data.List.NonEmpty ( NonEmpty ) import Data.Proxy ( Proxy (..) ) import Internal.Test.QuickCheck.Quid ( Quid (..) ) import Numeric.Natural ( Natural ) import qualified Data.Foldable as F import qualified Data.List.NonEmpty as NE nonEmptyListToQuid :: forall a. (Bounded a, Enum a) => NonEmpty a -> Quid nonEmptyListToQuid :: forall a. (Bounded a, Enum a) => NonEmpty a -> Quid nonEmptyListToQuid NonEmpty a xs = Natural -> Quid Quid forall a b. (a -> b) -> a -> b $ forall (t :: * -> *) b a. Foldable t => (b -> a -> b) -> b -> t a -> b F.foldl' forall {a}. Enum a => Natural -> a -> Natural f Natural 0 NonEmpty a xs forall a. Num a => a -> a -> a - Natural 1 where f :: Natural -> a -> Natural f !Natural acc !a x = Natural acc forall a. Num a => a -> a -> a * Natural base forall a. Num a => a -> a -> a + Natural 1 forall a. Num a => a -> a -> a + forall a b. (Integral a, Num b) => a -> b fromIntegral (forall a. Enum a => a -> Int fromEnum a x) base :: Natural base = forall a b. (Integral a, Num b) => a -> b fromIntegral @Int @Natural forall a b. (a -> b) -> a -> b $ forall a. (Bounded a, Enum a) => Proxy a -> Int boundedEnumCardinality forall a b. (a -> b) -> a -> b $ forall {k} (t :: k). Proxy t Proxy @a nonEmptyListFromQuid :: forall a. (Bounded a, Enum a) => Quid -> NonEmpty a nonEmptyListFromQuid :: forall a. (Bounded a, Enum a) => Quid -> NonEmpty a nonEmptyListFromQuid (Quid Natural q) = forall a. [a] -> NonEmpty a NE.fromList forall a b. (a -> b) -> a -> b $ [a] -> Natural -> [a] go [] Natural q where go :: [a] -> Natural -> [a] go :: [a] -> Natural -> [a] go ![a] acc !Natural n | Natural n forall a. Ord a => a -> a -> Bool < Natural base = forall a. Enum a => Int -> a toEnum (forall a b. (Integral a, Num b) => a -> b fromIntegral Natural n) forall a. a -> [a] -> [a] : [a] acc | Bool otherwise = [a] -> Natural -> [a] go (forall a. Enum a => Int -> a toEnum (forall a b. (Integral a, Num b) => a -> b fromIntegral (Natural n forall a. Integral a => a -> a -> a `mod` Natural base)) forall a. a -> [a] -> [a] : [a] acc) (Natural n forall a. Integral a => a -> a -> a `div` Natural base forall a. Num a => a -> a -> a - Natural 1) base :: Natural base = forall a b. (Integral a, Num b) => a -> b fromIntegral @Int @Natural forall a b. (a -> b) -> a -> b $ forall a. (Bounded a, Enum a) => Proxy a -> Int boundedEnumCardinality forall a b. (a -> b) -> a -> b $ forall {k} (t :: k). Proxy t Proxy @a boundedEnumCardinality :: forall a. (Bounded a, Enum a) => Proxy a -> Int boundedEnumCardinality :: forall a. (Bounded a, Enum a) => Proxy a -> Int boundedEnumCardinality Proxy a _ = forall a. Enum a => a -> Int fromEnum (forall a. Bounded a => a maxBound @a) forall a. Num a => a -> a -> a - forall a. Enum a => a -> Int fromEnum (forall a. Bounded a => a minBound @a) forall a. Num a => a -> a -> a + Int 1