{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE DataKinds, TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}

module Control.Moffy.Samples.Event.Random.Internal (
	-- * Store Random Gen
	StoreRandomGen(..), pattern OccStoreRandomGen,
	-- * Load Random Gen
	LoadRandomGen, pattern OccLoadRandomGen,
	-- * Get Random
	RandomEv, getRandom, getRandomR ) where

import Control.Arrow ((>>>))
import Control.Moffy (React, Request(..), await, adjust)
import Data.Type.Set (numbered, pattern Nil, Singleton, (:-))
import Data.OneOrMore (Selectable(..))
import System.Random (Random, StdGen, random, randomR)

---------------------------------------------------------------------------

-- * STORE RANDOM GEN
-- * LOAD RANDOM GEN
-- * RANDOM EV AND GET RANDOM

---------------------------------------------------------------------------
-- STORE RANDOM GEN
---------------------------------------------------------------------------

newtype StoreRandomGen = StoreRandomGenReq StdGen deriving Int -> StoreRandomGen -> ShowS
[StoreRandomGen] -> ShowS
StoreRandomGen -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StoreRandomGen] -> ShowS
$cshowList :: [StoreRandomGen] -> ShowS
show :: StoreRandomGen -> String
$cshow :: StoreRandomGen -> String
showsPrec :: Int -> StoreRandomGen -> ShowS
$cshowsPrec :: Int -> StoreRandomGen -> ShowS
Show
numbered [t| StoreRandomGen |]
instance Selectable StoreRandomGen where StoreRandomGen
l select :: StoreRandomGen -> StoreRandomGen -> StoreRandomGen
`select` StoreRandomGen
_r = StoreRandomGen
l
instance Request StoreRandomGen where
	data Occurred StoreRandomGen = OccStoreRandomGen

storeRandomGen :: StdGen -> React s (Singleton StoreRandomGen) ()
storeRandomGen :: forall s. StdGen -> React s (Singleton StoreRandomGen) ()
storeRandomGen StdGen
g = forall e r s. e -> (Occurred e -> r) -> React s (Singleton e) r
await (StdGen -> StoreRandomGen
StoreRandomGenReq StdGen
g) \Occurred StoreRandomGen
R:OccurredStoreRandomGen
OccStoreRandomGen -> ()

---------------------------------------------------------------------------
-- LOAD RANDOM GEN
---------------------------------------------------------------------------

data LoadRandomGen = LoadRandomGenReq deriving (Int -> LoadRandomGen -> ShowS
[LoadRandomGen] -> ShowS
LoadRandomGen -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LoadRandomGen] -> ShowS
$cshowList :: [LoadRandomGen] -> ShowS
show :: LoadRandomGen -> String
$cshow :: LoadRandomGen -> String
showsPrec :: Int -> LoadRandomGen -> ShowS
$cshowsPrec :: Int -> LoadRandomGen -> ShowS
Show, LoadRandomGen -> LoadRandomGen -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LoadRandomGen -> LoadRandomGen -> Bool
$c/= :: LoadRandomGen -> LoadRandomGen -> Bool
== :: LoadRandomGen -> LoadRandomGen -> Bool
$c== :: LoadRandomGen -> LoadRandomGen -> Bool
Eq, Eq LoadRandomGen
LoadRandomGen -> LoadRandomGen -> Bool
LoadRandomGen -> LoadRandomGen -> Ordering
LoadRandomGen -> LoadRandomGen -> LoadRandomGen
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: LoadRandomGen -> LoadRandomGen -> LoadRandomGen
$cmin :: LoadRandomGen -> LoadRandomGen -> LoadRandomGen
max :: LoadRandomGen -> LoadRandomGen -> LoadRandomGen
$cmax :: LoadRandomGen -> LoadRandomGen -> LoadRandomGen
>= :: LoadRandomGen -> LoadRandomGen -> Bool
$c>= :: LoadRandomGen -> LoadRandomGen -> Bool
> :: LoadRandomGen -> LoadRandomGen -> Bool
$c> :: LoadRandomGen -> LoadRandomGen -> Bool
<= :: LoadRandomGen -> LoadRandomGen -> Bool
$c<= :: LoadRandomGen -> LoadRandomGen -> Bool
< :: LoadRandomGen -> LoadRandomGen -> Bool
$c< :: LoadRandomGen -> LoadRandomGen -> Bool
compare :: LoadRandomGen -> LoadRandomGen -> Ordering
$ccompare :: LoadRandomGen -> LoadRandomGen -> Ordering
Ord)
numbered [t| LoadRandomGen |]
instance Request LoadRandomGen where
	data Occurred LoadRandomGen = OccLoadRandomGen StdGen

loadRandomGen :: React s (Singleton LoadRandomGen) StdGen
loadRandomGen :: forall s. React s (Singleton LoadRandomGen) StdGen
loadRandomGen = forall e r s. e -> (Occurred e -> r) -> React s (Singleton e) r
await LoadRandomGen
LoadRandomGenReq \(OccLoadRandomGen StdGen
g) -> StdGen
g

---------------------------------------------------------------------------
-- RANDOM EV AND GET RANDOM
---------------------------------------------------------------------------

type RandomEv = StoreRandomGen :- LoadRandomGen :- 'Nil

getRandom :: Random a => React s RandomEv a
getRandom :: forall a s. Random a => React s RandomEv a
getRandom = forall a s. (StdGen -> (a, StdGen)) -> React s RandomEv a
modifyRandomGen forall a g. (Random a, RandomGen g) => g -> (a, g)
random

getRandomR :: Random a => (a, a) -> React s RandomEv a
getRandomR :: forall a s. Random a => (a, a) -> React s RandomEv a
getRandomR = forall a s. (StdGen -> (a, StdGen)) -> React s RandomEv a
modifyRandomGen forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR

modifyRandomGen :: (StdGen -> (a, StdGen)) -> React s RandomEv a
modifyRandomGen :: forall a s. (StdGen -> (a, StdGen)) -> React s RandomEv a
modifyRandomGen StdGen -> (a, StdGen)
f = forall (es :: Set (*)) (es' :: Set (*)) s a.
Adjustable es es' =>
React s es a -> React s es' a
adjust forall s. React s (Singleton LoadRandomGen) StdGen
loadRandomGen
	forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (StdGen -> (a, StdGen)
f forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> \(a
r, StdGen
g) -> a
r forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (es :: Set (*)) (es' :: Set (*)) s a.
Adjustable es es' =>
React s es a -> React s es' a
adjust (forall s. StdGen -> React s (Singleton StoreRandomGen) ()
storeRandomGen StdGen
g))