{-# LANGUAGE ScopedTypeVariables #-}

module HaskellWorks.Hedgehog.Gen
  ( vector
  , storableVector
  , word8x8
  , tuple2
  , tuple3
  , tuple4
  , tuple5
  , tuple6
  , tuple7
  , tuple8
  , tuple9
  ) where

import Data.Bits
import Data.Word
import Foreign.Storable
import Hedgehog

import qualified Data.Vector          as DV
import qualified Data.Vector.Storable as DVS
import qualified Hedgehog.Gen         as G
import qualified Hedgehog.Range       as R

vector :: MonadGen m => Range Int -> m a -> m (DV.Vector a)
vector :: Range Int -> m a -> m (Vector a)
vector Range Int
n m a
g = [a] -> Vector a
forall a. [a] -> Vector a
DV.fromList ([a] -> Vector a) -> m [a] -> m (Vector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Range Int -> m a -> m [a]
forall (m :: * -> *) a. MonadGen m => Range Int -> m a -> m [a]
G.list Range Int
n m a
g

storableVector :: (Storable a, MonadGen m) => Range Int -> m a -> m (DVS.Vector a)
storableVector :: Range Int -> m a -> m (Vector a)
storableVector Range Int
n m a
g = [a] -> Vector a
forall a. Storable a => [a] -> Vector a
DVS.fromList ([a] -> Vector a) -> m [a] -> m (Vector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Range Int -> m a -> m [a]
forall (m :: * -> *) a. MonadGen m => Range Int -> m a -> m [a]
G.list Range Int
n m a
g

word8x8 :: MonadGen m => m Word8 -> m Word64
word8x8 :: m Word8 -> m Word64
word8x8 m Word8
gen = do
  Word64
a :: Word64 <- Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word64) -> m Word8 -> m Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word8
gen
  Word64
b :: Word64 <- Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word64) -> m Word8 -> m Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word8
gen
  Word64
c :: Word64 <- Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word64) -> m Word8 -> m Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word8
gen
  Word64
d :: Word64 <- Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word64) -> m Word8 -> m Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word8
gen
  Word64
e :: Word64 <- Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word64) -> m Word8 -> m Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word8
gen
  Word64
f :: Word64 <- Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word64) -> m Word8 -> m Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word8
gen
  Word64
g :: Word64 <- Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word64) -> m Word8 -> m Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word8
gen
  Word64
h :: Word64 <- Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word64) -> m Word8 -> m Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word8
gen
  Word64 -> m Word64
forall (m :: * -> *) a. Monad m => a -> m a
return (Word64 -> m Word64) -> Word64 -> m Word64
forall a b. (a -> b) -> a -> b
$  (Word64
a Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
56) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
            (Word64
b Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
48) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
            (Word64
c Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
40) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
            (Word64
d Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
32) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
            (Word64
e Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
24) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
            (Word64
f Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
16) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
            (Word64
g Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL`  Int
8) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
            (Word64
h Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL`  Int
0)

tuple2 :: MonadGen m => m a -> m (a, a)
tuple2 :: m a -> m (a, a)
tuple2 m a
gen = (,) (a -> a -> (a, a)) -> m a -> m (a -> (a, a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
gen m (a -> (a, a)) -> m a -> m (a, a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen

tuple3 :: MonadGen m => m a -> m (a, a, a)
tuple3 :: m a -> m (a, a, a)
tuple3 m a
gen = (,,) (a -> a -> a -> (a, a, a)) -> m a -> m (a -> a -> (a, a, a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
gen m (a -> a -> (a, a, a)) -> m a -> m (a -> (a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> (a, a, a)) -> m a -> m (a, a, a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen

tuple4 :: MonadGen m => m a -> m (a, a, a, a)
tuple4 :: m a -> m (a, a, a, a)
tuple4 m a
gen = (,,,) (a -> a -> a -> a -> (a, a, a, a))
-> m a -> m (a -> a -> a -> (a, a, a, a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
gen m (a -> a -> a -> (a, a, a, a))
-> m a -> m (a -> a -> (a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> (a, a, a, a)) -> m a -> m (a -> (a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> (a, a, a, a)) -> m a -> m (a, a, a, a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen

tuple5 :: MonadGen m => m a -> m (a, a, a, a, a)
tuple5 :: m a -> m (a, a, a, a, a)
tuple5 m a
gen = (,,,,) (a -> a -> a -> a -> a -> (a, a, a, a, a))
-> m a -> m (a -> a -> a -> a -> (a, a, a, a, a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
gen m (a -> a -> a -> a -> (a, a, a, a, a))
-> m a -> m (a -> a -> a -> (a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> (a, a, a, a, a))
-> m a -> m (a -> a -> (a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> (a, a, a, a, a)) -> m a -> m (a -> (a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> (a, a, a, a, a)) -> m a -> m (a, a, a, a, a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen

tuple6 :: MonadGen m => m a -> m (a, a, a, a, a, a)
tuple6 :: m a -> m (a, a, a, a, a, a)
tuple6 m a
gen = (,,,,,) (a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a))
-> m a -> m (a -> a -> a -> a -> a -> (a, a, a, a, a, a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
gen m (a -> a -> a -> a -> a -> (a, a, a, a, a, a))
-> m a -> m (a -> a -> a -> a -> (a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> a -> (a, a, a, a, a, a))
-> m a -> m (a -> a -> a -> (a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> (a, a, a, a, a, a))
-> m a -> m (a -> a -> (a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> (a, a, a, a, a, a))
-> m a -> m (a -> (a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> (a, a, a, a, a, a)) -> m a -> m (a, a, a, a, a, a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen

tuple7 :: MonadGen m => m a -> m (a, a, a, a, a, a, a)
tuple7 :: m a -> m (a, a, a, a, a, a, a)
tuple7 m a
gen = (,,,,,,) (a -> a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a))
-> m a -> m (a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
gen m (a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a))
-> m a -> m (a -> a -> a -> a -> a -> (a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> a -> a -> (a, a, a, a, a, a, a))
-> m a -> m (a -> a -> a -> a -> (a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> a -> (a, a, a, a, a, a, a))
-> m a -> m (a -> a -> a -> (a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> (a, a, a, a, a, a, a))
-> m a -> m (a -> a -> (a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> (a, a, a, a, a, a, a))
-> m a -> m (a -> (a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> (a, a, a, a, a, a, a)) -> m a -> m (a, a, a, a, a, a, a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen

tuple8 :: MonadGen m => m a -> m (a, a, a, a, a, a, a, a)
tuple8 :: m a -> m (a, a, a, a, a, a, a, a)
tuple8 m a
gen = (,,,,,,,) (a -> a -> a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a))
-> m a
-> m (a -> a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
gen m (a -> a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a))
-> m a
-> m (a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a))
-> m a -> m (a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a))
-> m a -> m (a -> a -> a -> a -> (a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> a -> (a, a, a, a, a, a, a, a))
-> m a -> m (a -> a -> a -> (a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> (a, a, a, a, a, a, a, a))
-> m a -> m (a -> a -> (a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> (a, a, a, a, a, a, a, a))
-> m a -> m (a -> (a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> (a, a, a, a, a, a, a, a))
-> m a -> m (a, a, a, a, a, a, a, a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen

tuple9 :: MonadGen m => m a -> m (a, a, a, a, a, a, a, a, a)
tuple9 :: m a -> m (a, a, a, a, a, a, a, a, a)
tuple9 m a
gen = (,,,,,,,,) (a
 -> a
 -> a
 -> a
 -> a
 -> a
 -> a
 -> a
 -> a
 -> (a, a, a, a, a, a, a, a, a))
-> m a
-> m (a
      -> a -> a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
gen m (a
   -> a -> a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a, a))
-> m a
-> m (a
      -> a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a, a))
-> m a
-> m (a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a, a))
-> m a -> m (a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> a -> a -> (a, a, a, a, a, a, a, a, a))
-> m a -> m (a -> a -> a -> a -> (a, a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> a -> (a, a, a, a, a, a, a, a, a))
-> m a -> m (a -> a -> a -> (a, a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> a -> (a, a, a, a, a, a, a, a, a))
-> m a -> m (a -> a -> (a, a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> a -> (a, a, a, a, a, a, a, a, a))
-> m a -> m (a -> (a, a, a, a, a, a, a, a, a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen m (a -> (a, a, a, a, a, a, a, a, a))
-> m a -> m (a, a, a, a, a, a, a, a, a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a
gen