module Polysemy.Db.Interpreter.Random where

import Conc (interpretAtomic)
import qualified System.Random as R

import Polysemy.Db.Effect.Random (Random (Random, RandomR))

interpretRandomAtomicState ::
   a q r .
  R.Random a =>
  R.RandomGen q =>
  Member (AtomicState q) r =>
  InterpreterFor (Random a) r
interpretRandomAtomicState :: forall a q (r :: EffectRow).
(Random a, RandomGen q, Member (AtomicState q) r) =>
InterpreterFor (Random a) r
interpretRandomAtomicState =
  forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
FirstOrder e "interpret" =>
(forall (rInitial :: EffectRow) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret \case
    Random a (Sem rInitial) x
Random ->
      forall s a (r :: EffectRow).
Member (AtomicState s) r =>
(s -> (s, a)) -> Sem r a
atomicState' (forall a b. (a, b) -> (b, a)
swap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a g. (Random a, RandomGen g) => g -> (a, g)
R.random)
    RandomR (a, a)
r ->
      forall s a (r :: EffectRow).
Member (AtomicState s) r =>
(s -> (s, a)) -> Sem r a
atomicState' (forall a b. (a, b) -> (b, a)
swap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
R.randomR (a, a)
r)

interpretRandomAtomic ::
   a q r .
  R.Random a =>
  R.RandomGen q =>
  Member (Embed IO) r =>
  q ->
  InterpreterFor (Random a) r
interpretRandomAtomic :: forall a q (r :: EffectRow).
(Random a, RandomGen q, Member (Embed IO) r) =>
q -> InterpreterFor (Random a) r
interpretRandomAtomic q
q =
  forall a (r :: EffectRow).
Member (Embed IO) r =>
a -> InterpreterFor (AtomicState a) r
interpretAtomic q
q forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a q (r :: EffectRow).
(Random a, RandomGen q, Member (AtomicState q) r) =>
InterpreterFor (Random a) r
interpretRandomAtomicState forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (e2 :: (* -> *) -> * -> *) (e1 :: (* -> *) -> * -> *)
       (r :: EffectRow) a.
Sem (e1 : r) a -> Sem (e1 : e2 : r) a
raiseUnder

interpretRandomState ::
   a q r .
  R.Random a =>
  R.RandomGen q =>
  q ->
  InterpreterFor (Random a) r
interpretRandomState :: forall a q (r :: EffectRow).
(Random a, RandomGen q) =>
q -> InterpreterFor (Random a) r
interpretRandomState q
q =
  forall s (r :: EffectRow) a. s -> Sem (State s : r) a -> Sem r a
evalState q
q forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (r :: EffectRow) a.
Member (State s) r =>
Sem (AtomicState s : r) a -> Sem r a
atomicStateToState forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a q (r :: EffectRow).
(Random a, RandomGen q, Member (AtomicState q) r) =>
InterpreterFor (Random a) r
interpretRandomAtomicState forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (e2 :: (* -> *) -> * -> *) (e3 :: (* -> *) -> * -> *)
       (e1 :: (* -> *) -> * -> *) (r :: EffectRow) a.
Sem (e1 : r) a -> Sem (e1 : e2 : e3 : r) a
raiseUnder2

interpretRandom ::
   a r .
  R.Random a =>
  Member (Embed IO) r =>
  InterpreterFor (Random a) r
interpretRandom :: forall a (r :: EffectRow).
(Random a, Member (Embed IO) r) =>
InterpreterFor (Random a) r
interpretRandom Sem (Random a : r) a
sem = do
  StdGen
q <- forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed forall (m :: * -> *). MonadIO m => m StdGen
R.newStdGen
  forall a q (r :: EffectRow).
(Random a, RandomGen q, Member (Embed IO) r) =>
q -> InterpreterFor (Random a) r
interpretRandomAtomic StdGen
q Sem (Random a : r) a
sem