module Prelude.Coarbitrary where

import Test.QuickCheck
import Prelude hiding (maybe, either)
import Barecheck.Util

maybe :: (a -> Gen b -> Gen b) -> Maybe a -> Gen b -> Gen b
maybe f m = case m of
  Nothing -> varInt 0
  Just x -> varInt 1 . f x

either
  :: (a -> Gen c -> Gen c)
  -> (b -> Gen c -> Gen c)
  -> Either a b
  -> Gen c
  -> Gen c
either fa fb ei = case ei of
  Left a -> varInt 0 . fa a
  Right b -> varInt 1 . fb b

list
  :: (a -> Gen b -> Gen b)
  -> [a]
  -> Gen b
  -> Gen b
list f xs = case xs of
  [] -> varInt 0
  a:as -> varInt 1 . f a . list f as

tuple2
  :: (a -> Gen r -> Gen r)
  -> (b -> Gen r -> Gen r)
  -> (a, b)
  -> Gen r
  -> Gen r
tuple2 fa fb (a, b) = fa a . fb b

tuple3
  :: (a -> Gen r -> Gen r)
  -> (b -> Gen r -> Gen r)
  -> (c -> Gen r -> Gen r)
  -> (a, b, c)
  -> Gen r
  -> Gen r
tuple3 fa fb fc (a, b, c) = fa a . fb b . fc c

tuple4
  :: (a -> Gen r -> Gen r)
  -> (b -> Gen r -> Gen r)
  -> (c -> Gen r -> Gen r)
  -> (d -> Gen r -> Gen r)
  -> (a, b, c, d)
  -> Gen r
  -> Gen r
tuple4 fa fb fc fd (a, b, c, d) = fa a . fb b . fc c . fd d

tuple5
  :: (a -> Gen r -> Gen r)
  -> (b -> Gen r -> Gen r)
  -> (c -> Gen r -> Gen r)
  -> (d -> Gen r -> Gen r)
  -> (e -> Gen r -> Gen r)
  -> (a, b, c, d, e)
  -> Gen r
  -> Gen r
tuple5 fa fb fc fd fe (a, b, c, d, e) = fa a . fb b . fc c . fd d . fe e