{-# LANGUAGE PatternSynonyms #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}

module Control.Moffy.Samples.Handle.Random (
	-- * Type
	RandomEv, RandomState(..),
	-- * Handle
	handleRandom ) where

import Control.Moffy.Samples.Event.Random.Internal (
	RandomEv, StoreRandomGen(..), pattern OccStoreRandomGen,
	LoadRandomGen, pattern OccLoadRandomGen )
import Control.Moffy.Handle (HandleSt', mergeSt)
import Data.Type.Set (Singleton)
import Data.OneOrMore as Oom (pattern Singleton)
import System.Random (StdGen)

import Data.OneOrMoreApp as Ooma (pattern Singleton)

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

-- * RANDOM STATE
-- * HANDLE

---------------------------------------------------------------------------
-- RANDOM STATE
---------------------------------------------------------------------------

class RandomState s where
	getRandomGen :: s -> StdGen; putRandomGen :: s -> StdGen -> s

instance RandomState StdGen where getRandomGen :: StdGen -> StdGen
getRandomGen = forall a. a -> a
id; putRandomGen :: StdGen -> StdGen -> StdGen
putRandomGen = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. a -> b -> a
const

---------------------------------------------------------------------------
-- HANDLE
---------------------------------------------------------------------------

handleRandom :: (RandomState s, Monad m) => HandleSt' s m RandomEv
handleRandom :: forall s (m :: * -> *).
(RandomState s, Monad m) =>
HandleSt' s m RandomEv
handleRandom = forall s (m :: * -> *).
(RandomState s, Applicative m) =>
HandleSt' s m (Singleton StoreRandomGen)
handleStoreRandomGen forall (m :: * -> *) (es :: Set (*)) (es' :: Set (*)) st.
(Monad m, ExpandableHandle es (es :+: es'),
 ExpandableHandle es' (es :+: es'),
 MergeableOccurred es es' (es :+: es')) =>
HandleSt' st m es
-> HandleSt' st m es' -> HandleSt' st m (es :+: es')
`mergeSt` forall s (m :: * -> *).
(RandomState s, Applicative m) =>
HandleSt' s m (Singleton LoadRandomGen)
handleLoadRandomGen

handleStoreRandomGen :: (RandomState s, Applicative m) =>
	HandleSt' s m (Singleton StoreRandomGen)
handleStoreRandomGen :: forall s (m :: * -> *).
(RandomState s, Applicative m) =>
HandleSt' s m (Singleton StoreRandomGen)
handleStoreRandomGen (Oom.Singleton (StoreRandomGenReq StdGen
g)) s
s =
	forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a (f :: * -> *). a -> OneOrMoreApp ('SetApp f (Singleton a))
Ooma.Singleton Occurred StoreRandomGen
OccStoreRandomGen, s
s forall s. RandomState s => s -> StdGen -> s
`putRandomGen` StdGen
g)

handleLoadRandomGen :: (RandomState s, Applicative m) =>
	HandleSt' s m (Singleton LoadRandomGen)
handleLoadRandomGen :: forall s (m :: * -> *).
(RandomState s, Applicative m) =>
HandleSt' s m (Singleton LoadRandomGen)
handleLoadRandomGen EvReqs (Singleton LoadRandomGen)
_rqs s
s =
	forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (f :: * -> *). a -> OneOrMoreApp ('SetApp f (Singleton a))
Ooma.Singleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. StdGen -> Occurred LoadRandomGen
OccLoadRandomGen forall a b. (a -> b) -> a -> b
$ forall s. RandomState s => s -> StdGen
getRandomGen s
s, s
s)