module Polysemy.Check.Arbitrary where

import Generics.Kind
import Polysemy
import Polysemy.Check.Arbitrary.AnyEff
import Polysemy.Check.Arbitrary.Generic
import Test.QuickCheck


------------------------------------------------------------------------------
-- | Generate any action for effect @e@.
arbitraryAction
    :: forall e r
     . ArbitraryAction (TypesOf e) e r
    => Gen (SomeAction e r)
       -- ^
arbitraryAction :: Gen (SomeAction e r)
arbitraryAction = [Gen (SomeAction e r)] -> Gen (SomeAction e r)
forall a. [Gen a] -> Gen a
oneof ([Gen (SomeAction e r)] -> Gen (SomeAction e r))
-> [Gen (SomeAction e r)] -> Gen (SomeAction e r)
forall a b. (a -> b) -> a -> b
$ ArbitraryAction (TypesOf e) e r => [Gen (SomeAction e r)]
forall (as :: [*]) (e :: Effect) (r :: EffectRow).
ArbitraryAction as e r =>
[Gen (SomeAction e r)]
genSomeAction @(TypesOf e) @e @r


------------------------------------------------------------------------------
-- | Generate any action for effect @e@ that produces type @a@.
arbitraryActionOfType
    :: forall e a r
     . (GenericK e, GArbitraryK e (RepK e) r a)
    => Gen (e (Sem r) a)
       -- ^
arbitraryActionOfType :: Gen (e (Sem r) a)
arbitraryActionOfType = (GenericK e, GArbitraryK e (RepK e) r a) => Gen (e (Sem r) a)
forall (e :: Effect) (r :: EffectRow) a.
(GenericK e, GArbitraryK e (RepK e) r a) =>
Gen (e (Sem r) a)
genEff @e @r @a


------------------------------------------------------------------------------
-- | Generate any action from any effect in @effs@.
arbitraryActionFromRow
    :: forall (effs :: EffectRow) r
     . ArbitraryEff effs r
    => Gen (SomeEff r)
       -- ^
arbitraryActionFromRow :: Gen (SomeEff r)
arbitraryActionFromRow = [Gen (SomeEff r)] -> Gen (SomeEff r)
forall a. [Gen a] -> Gen a
oneof ([Gen (SomeEff r)] -> Gen (SomeEff r))
-> [Gen (SomeEff r)] -> Gen (SomeEff r)
forall a b. (a -> b) -> a -> b
$ ArbitraryEff effs r => [Gen (SomeEff r)]
forall (es :: EffectRow) (r :: EffectRow).
ArbitraryEff es r =>
[Gen (SomeEff r)]
genSomeEff @effs @r


------------------------------------------------------------------------------
-- | Generate any action from any effect in @effs@ that produces type @a@.
arbitraryActionFromRowOfType
    :: forall (effs :: EffectRow) r a
     . ArbitraryEffOfType a effs r
    => Gen (SomeEffOfType r a)
       -- ^
arbitraryActionFromRowOfType :: Gen (SomeEffOfType r a)
arbitraryActionFromRowOfType = [Gen (SomeEffOfType r a)] -> Gen (SomeEffOfType r a)
forall a. [Gen a] -> Gen a
oneof ([Gen (SomeEffOfType r a)] -> Gen (SomeEffOfType r a))
-> [Gen (SomeEffOfType r a)] -> Gen (SomeEffOfType r a)
forall a b. (a -> b) -> a -> b
$ ArbitraryEffOfType a effs r => [Gen (SomeEffOfType r a)]
forall a (es :: EffectRow) (r :: EffectRow).
ArbitraryEffOfType a es r =>
[Gen (SomeEffOfType r a)]
genSomeEffOfType @a @effs @r