{-# 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 (Natural -> Quid) -> Natural -> Quid forall a b. (a -> b) -> a -> b $ (Natural -> a -> Natural) -> Natural -> NonEmpty a -> Natural forall b a. (b -> a -> b) -> b -> NonEmpty a -> b forall (t :: * -> *) b a. Foldable t => (b -> a -> b) -> b -> t a -> b F.foldl' Natural -> a -> Natural forall {a}. Enum a => Natural -> a -> Natural f Natural 0 NonEmpty a xs Natural -> Natural -> Natural forall a. Num a => a -> a -> a - Natural 1 where f :: Natural -> a -> Natural f !Natural acc !a x = Natural acc Natural -> Natural -> Natural forall a. Num a => a -> a -> a * Natural base Natural -> Natural -> Natural forall a. Num a => a -> a -> a + Natural 1 Natural -> Natural -> Natural forall a. Num a => a -> a -> a + Int -> Natural forall a b. (Integral a, Num b) => a -> b fromIntegral (a -> Int forall a. Enum a => a -> Int fromEnum a x) base :: Natural base = forall a b. (Integral a, Num b) => a -> b fromIntegral @Int @Natural (Int -> Natural) -> Int -> Natural forall a b. (a -> b) -> a -> b $ Proxy a -> Int forall a. (Bounded a, Enum a) => Proxy a -> Int boundedEnumCardinality (Proxy a -> Int) -> Proxy a -> Int forall a b. (a -> b) -> a -> b $ forall t. Proxy t 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) = [a] -> NonEmpty a forall a. HasCallStack => [a] -> NonEmpty a NE.fromList ([a] -> NonEmpty a) -> [a] -> NonEmpty a 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 Natural -> Natural -> Bool forall a. Ord a => a -> a -> Bool < Natural base = Int -> a forall a. Enum a => Int -> a toEnum (Natural -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral Natural n) a -> [a] -> [a] forall a. a -> [a] -> [a] : [a] acc | Bool otherwise = [a] -> Natural -> [a] go (Int -> a forall a. Enum a => Int -> a toEnum (Natural -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral (Natural n Natural -> Natural -> Natural forall a. Integral a => a -> a -> a `mod` Natural base)) a -> [a] -> [a] forall a. a -> [a] -> [a] : [a] acc) (Natural n Natural -> Natural -> Natural forall a. Integral a => a -> a -> a `div` Natural base Natural -> Natural -> Natural forall a. Num a => a -> a -> a - Natural 1) base :: Natural base = forall a b. (Integral a, Num b) => a -> b fromIntegral @Int @Natural (Int -> Natural) -> Int -> Natural forall a b. (a -> b) -> a -> b $ Proxy a -> Int forall a. (Bounded a, Enum a) => Proxy a -> Int boundedEnumCardinality (Proxy a -> Int) -> Proxy a -> Int forall a b. (a -> b) -> a -> b $ forall t. Proxy t 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 _ = a -> Int forall a. Enum a => a -> Int fromEnum (forall a. Bounded a => a maxBound @a) Int -> Int -> Int forall a. Num a => a -> a -> a - a -> Int forall a. Enum a => a -> Int fromEnum (forall a. Bounded a => a minBound @a) Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1