{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE RecursiveDo #-}
{-# LANGUAGE TypeFamilies #-}

module Aztecs.ECS.Schedule.Dynamic.Reader
  ( DynamicReaderSchedule,
    DynamicReaderScheduleT (..),
  )
where

import Aztecs.ECS.Access
import Control.Arrow
import Control.Category
import Control.Monad.Fix
import Prelude hiding (all, any, id, lookup, reads, (.))

type DynamicReaderSchedule m = DynamicReaderScheduleT (AccessT m)

newtype DynamicReaderScheduleT m i o = DynamicReaderSchedule {forall (m :: * -> *) i o.
DynamicReaderScheduleT m i o
-> i -> m (o, DynamicReaderScheduleT m i o)
runScheduleDyn :: i -> m (o, DynamicReaderScheduleT m i o)}
  deriving ((forall a b.
 (a -> b)
 -> DynamicReaderScheduleT m i a -> DynamicReaderScheduleT m i b)
-> (forall a b.
    a -> DynamicReaderScheduleT m i b -> DynamicReaderScheduleT m i a)
-> Functor (DynamicReaderScheduleT m i)
forall a b.
a -> DynamicReaderScheduleT m i b -> DynamicReaderScheduleT m i a
forall a b.
(a -> b)
-> DynamicReaderScheduleT m i a -> DynamicReaderScheduleT m i b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (m :: * -> *) i a b.
Functor m =>
a -> DynamicReaderScheduleT m i b -> DynamicReaderScheduleT m i a
forall (m :: * -> *) i a b.
Functor m =>
(a -> b)
-> DynamicReaderScheduleT m i a -> DynamicReaderScheduleT m i b
$cfmap :: forall (m :: * -> *) i a b.
Functor m =>
(a -> b)
-> DynamicReaderScheduleT m i a -> DynamicReaderScheduleT m i b
fmap :: forall a b.
(a -> b)
-> DynamicReaderScheduleT m i a -> DynamicReaderScheduleT m i b
$c<$ :: forall (m :: * -> *) i a b.
Functor m =>
a -> DynamicReaderScheduleT m i b -> DynamicReaderScheduleT m i a
<$ :: forall a b.
a -> DynamicReaderScheduleT m i b -> DynamicReaderScheduleT m i a
Functor)

instance (Monad m) => Category (DynamicReaderScheduleT m) where
  id :: forall a. DynamicReaderScheduleT m a a
id = (a -> m (a, DynamicReaderScheduleT m a a))
-> DynamicReaderScheduleT m a a
forall (m :: * -> *) i o.
(i -> m (o, DynamicReaderScheduleT m i o))
-> DynamicReaderScheduleT m i o
DynamicReaderSchedule ((a -> m (a, DynamicReaderScheduleT m a a))
 -> DynamicReaderScheduleT m a a)
-> (a -> m (a, DynamicReaderScheduleT m a a))
-> DynamicReaderScheduleT m a a
forall a b. (a -> b) -> a -> b
$ \a
i -> (a, DynamicReaderScheduleT m a a)
-> m (a, DynamicReaderScheduleT m a a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
i, DynamicReaderScheduleT m a a
forall a. DynamicReaderScheduleT m a a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id)
  DynamicReaderSchedule b -> m (c, DynamicReaderScheduleT m b c)
f . :: forall b c a.
DynamicReaderScheduleT m b c
-> DynamicReaderScheduleT m a b -> DynamicReaderScheduleT m a c
. DynamicReaderSchedule a -> m (b, DynamicReaderScheduleT m a b)
g = (a -> m (c, DynamicReaderScheduleT m a c))
-> DynamicReaderScheduleT m a c
forall (m :: * -> *) i o.
(i -> m (o, DynamicReaderScheduleT m i o))
-> DynamicReaderScheduleT m i o
DynamicReaderSchedule ((a -> m (c, DynamicReaderScheduleT m a c))
 -> DynamicReaderScheduleT m a c)
-> (a -> m (c, DynamicReaderScheduleT m a c))
-> DynamicReaderScheduleT m a c
forall a b. (a -> b) -> a -> b
$ \a
i -> do
    (b
b, DynamicReaderScheduleT m a b
g') <- a -> m (b, DynamicReaderScheduleT m a b)
g a
i
    (c
c, DynamicReaderScheduleT m b c
f') <- b -> m (c, DynamicReaderScheduleT m b c)
f b
b
    (c, DynamicReaderScheduleT m a c)
-> m (c, DynamicReaderScheduleT m a c)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (c
c, DynamicReaderScheduleT m b c
f' DynamicReaderScheduleT m b c
-> DynamicReaderScheduleT m a b -> DynamicReaderScheduleT m a c
forall b c a.
DynamicReaderScheduleT m b c
-> DynamicReaderScheduleT m a b -> DynamicReaderScheduleT m a c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. DynamicReaderScheduleT m a b
g')

instance (Monad m) => Arrow (DynamicReaderScheduleT m) where
  arr :: forall b c. (b -> c) -> DynamicReaderScheduleT m b c
arr b -> c
f = (b -> m (c, DynamicReaderScheduleT m b c))
-> DynamicReaderScheduleT m b c
forall (m :: * -> *) i o.
(i -> m (o, DynamicReaderScheduleT m i o))
-> DynamicReaderScheduleT m i o
DynamicReaderSchedule ((b -> m (c, DynamicReaderScheduleT m b c))
 -> DynamicReaderScheduleT m b c)
-> (b -> m (c, DynamicReaderScheduleT m b c))
-> DynamicReaderScheduleT m b c
forall a b. (a -> b) -> a -> b
$ \b
i -> (c, DynamicReaderScheduleT m b c)
-> m (c, DynamicReaderScheduleT m b c)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b -> c
f b
i, (b -> c) -> DynamicReaderScheduleT m b c
forall b c. (b -> c) -> DynamicReaderScheduleT m b c
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr b -> c
f)
  first :: forall b c d.
DynamicReaderScheduleT m b c
-> DynamicReaderScheduleT m (b, d) (c, d)
first (DynamicReaderSchedule b -> m (c, DynamicReaderScheduleT m b c)
f) = ((b, d) -> m ((c, d), DynamicReaderScheduleT m (b, d) (c, d)))
-> DynamicReaderScheduleT m (b, d) (c, d)
forall (m :: * -> *) i o.
(i -> m (o, DynamicReaderScheduleT m i o))
-> DynamicReaderScheduleT m i o
DynamicReaderSchedule (((b, d) -> m ((c, d), DynamicReaderScheduleT m (b, d) (c, d)))
 -> DynamicReaderScheduleT m (b, d) (c, d))
-> ((b, d) -> m ((c, d), DynamicReaderScheduleT m (b, d) (c, d)))
-> DynamicReaderScheduleT m (b, d) (c, d)
forall a b. (a -> b) -> a -> b
$ \(b
b, d
d) -> do
    (c
c, DynamicReaderScheduleT m b c
f') <- b -> m (c, DynamicReaderScheduleT m b c)
f b
b
    ((c, d), DynamicReaderScheduleT m (b, d) (c, d))
-> m ((c, d), DynamicReaderScheduleT m (b, d) (c, d))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ((c
c, d
d), DynamicReaderScheduleT m b c
-> DynamicReaderScheduleT m (b, d) (c, d)
forall b c d.
DynamicReaderScheduleT m b c
-> DynamicReaderScheduleT m (b, d) (c, d)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first DynamicReaderScheduleT m b c
f')

instance (Monad m) => ArrowChoice (DynamicReaderScheduleT m) where
  left :: forall b c d.
DynamicReaderScheduleT m b c
-> DynamicReaderScheduleT m (Either b d) (Either c d)
left (DynamicReaderSchedule b -> m (c, DynamicReaderScheduleT m b c)
f) = (Either b d
 -> m (Either c d,
       DynamicReaderScheduleT m (Either b d) (Either c d)))
-> DynamicReaderScheduleT m (Either b d) (Either c d)
forall (m :: * -> *) i o.
(i -> m (o, DynamicReaderScheduleT m i o))
-> DynamicReaderScheduleT m i o
DynamicReaderSchedule ((Either b d
  -> m (Either c d,
        DynamicReaderScheduleT m (Either b d) (Either c d)))
 -> DynamicReaderScheduleT m (Either b d) (Either c d))
-> (Either b d
    -> m (Either c d,
          DynamicReaderScheduleT m (Either b d) (Either c d)))
-> DynamicReaderScheduleT m (Either b d) (Either c d)
forall a b. (a -> b) -> a -> b
$ \Either b d
i -> case Either b d
i of
    Left b
b -> do
      (c
c, DynamicReaderScheduleT m b c
f') <- b -> m (c, DynamicReaderScheduleT m b c)
f b
b
      (Either c d, DynamicReaderScheduleT m (Either b d) (Either c d))
-> m (Either c d,
      DynamicReaderScheduleT m (Either b d) (Either c d))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (c -> Either c d
forall a b. a -> Either a b
Left c
c, DynamicReaderScheduleT m b c
-> DynamicReaderScheduleT m (Either b d) (Either c d)
forall b c d.
DynamicReaderScheduleT m b c
-> DynamicReaderScheduleT m (Either b d) (Either c d)
forall (a :: * -> * -> *) b c d.
ArrowChoice a =>
a b c -> a (Either b d) (Either c d)
left DynamicReaderScheduleT m b c
f')
    Right d
d -> (Either c d, DynamicReaderScheduleT m (Either b d) (Either c d))
-> m (Either c d,
      DynamicReaderScheduleT m (Either b d) (Either c d))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (d -> Either c d
forall a b. b -> Either a b
Right d
d, DynamicReaderScheduleT m b c
-> DynamicReaderScheduleT m (Either b d) (Either c d)
forall b c d.
DynamicReaderScheduleT m b c
-> DynamicReaderScheduleT m (Either b d) (Either c d)
forall (a :: * -> * -> *) b c d.
ArrowChoice a =>
a b c -> a (Either b d) (Either c d)
left ((b -> m (c, DynamicReaderScheduleT m b c))
-> DynamicReaderScheduleT m b c
forall (m :: * -> *) i o.
(i -> m (o, DynamicReaderScheduleT m i o))
-> DynamicReaderScheduleT m i o
DynamicReaderSchedule b -> m (c, DynamicReaderScheduleT m b c)
f))

instance (MonadFix m) => ArrowLoop (DynamicReaderScheduleT m) where
  loop :: forall b d c.
DynamicReaderScheduleT m (b, d) (c, d)
-> DynamicReaderScheduleT m b c
loop (DynamicReaderSchedule (b, d) -> m ((c, d), DynamicReaderScheduleT m (b, d) (c, d))
f) = (b -> m (c, DynamicReaderScheduleT m b c))
-> DynamicReaderScheduleT m b c
forall (m :: * -> *) i o.
(i -> m (o, DynamicReaderScheduleT m i o))
-> DynamicReaderScheduleT m i o
DynamicReaderSchedule ((b -> m (c, DynamicReaderScheduleT m b c))
 -> DynamicReaderScheduleT m b c)
-> (b -> m (c, DynamicReaderScheduleT m b c))
-> DynamicReaderScheduleT m b c
forall a b. (a -> b) -> a -> b
$ \b
b -> do
    rec ((c
c, d
d), DynamicReaderScheduleT m (b, d) (c, d)
f') <- (b, d) -> m ((c, d), DynamicReaderScheduleT m (b, d) (c, d))
f (b
b, d
d)
    (c, DynamicReaderScheduleT m b c)
-> m (c, DynamicReaderScheduleT m b c)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (c
c, DynamicReaderScheduleT m (b, d) (c, d)
-> DynamicReaderScheduleT m b c
forall b d c.
DynamicReaderScheduleT m (b, d) (c, d)
-> DynamicReaderScheduleT m b c
forall (a :: * -> * -> *) b d c.
ArrowLoop a =>
a (b, d) (c, d) -> a b c
loop DynamicReaderScheduleT m (b, d) (c, d)
f')