module Effectful.Zoo.DataLog.Dynamic
  ( DataLog (..),
    runDataLog,
  ) where

import Effectful
import Effectful.Dispatch.Dynamic
import Effectful.Zoo.DataLog.Static qualified as S
import HaskellWorks.Prelude

data DataLog a :: Effect where
  DataLog
    :: a
    -> DataLog a m ()

  Local
    :: (a -> a)
    -> m b
    -> DataLog a m b

type instance DispatchOf (DataLog a) = Dynamic

runDataLog :: ()
  => HasCallStack
  => (HasCallStack => i -> Eff r ())
  -> Eff (DataLog i : r) a
  -> Eff r a
runDataLog :: forall i (r :: [Effect]) a.
HasCallStack =>
(HasCallStack => i -> Eff r ()) -> Eff (DataLog i : r) a -> Eff r a
runDataLog HasCallStack => i -> Eff r ()
run =
  (Eff (DataLog i : r) a -> Eff r a)
-> (forall {a} {localEs :: [Effect]}.
    (HasCallStack, DataLog i :> localEs) =>
    LocalEnv localEs (DataLog i : r)
    -> DataLog i (Eff localEs) a -> Eff (DataLog i : r) a)
-> Eff (DataLog i : r) a
-> Eff r a
forall (e :: Effect) (handlerEs :: [Effect]) a (es :: [Effect]) b.
(HasCallStack, DispatchOf e ~ 'Dynamic) =>
(Eff handlerEs a -> Eff es b)
-> EffectHandler e handlerEs -> Eff (e : es) a -> Eff es b
reinterpret ((HasCallStack => i -> Eff r ()) -> Eff (DataLog i : r) a -> Eff r a
forall i a (r :: [Effect]).
HasCallStack =>
(HasCallStack => i -> Eff r ()) -> Eff (DataLog i : r) a -> Eff r a
S.runDataLog i -> Eff r ()
HasCallStack => i -> Eff r ()
run) ((forall {a} {localEs :: [Effect]}.
  (HasCallStack, DataLog i :> localEs) =>
  LocalEnv localEs (DataLog i : r)
  -> DataLog i (Eff localEs) a -> Eff (DataLog i : r) a)
 -> Eff (DataLog i : r) a -> Eff r a)
-> (forall {a} {localEs :: [Effect]}.
    (HasCallStack, DataLog i :> localEs) =>
    LocalEnv localEs (DataLog i : r)
    -> DataLog i (Eff localEs) a -> Eff (DataLog i : r) a)
-> Eff (DataLog i : r) a
-> Eff r a
forall a b. (a -> b) -> a -> b
$ \LocalEnv localEs (DataLog i : r)
env -> \case
    DataLog i
i -> i -> Eff (DataLog i : r) ()
forall (r :: [Effect]) i.
(HasCallStack, r <: DataLog i) =>
i -> Eff r ()
S.log i
i
    Local i -> i
f Eff localEs a
m -> LocalEnv localEs (DataLog i : r)
-> ((forall {r}. Eff localEs r -> Eff (DataLog i : r) r)
    -> Eff (DataLog i : r) a)
-> Eff (DataLog i : r) a
forall (es :: [Effect]) (handlerEs :: [Effect])
       (localEs :: [Effect]) a.
(HasCallStack, SharedSuffix es handlerEs) =>
LocalEnv localEs handlerEs
-> ((forall r. Eff localEs r -> Eff es r) -> Eff es a) -> Eff es a
localSeqUnlift LocalEnv localEs (DataLog i : r)
env (((forall {r}. Eff localEs r -> Eff (DataLog i : r) r)
  -> Eff (DataLog i : r) a)
 -> Eff (DataLog i : r) a)
-> ((forall {r}. Eff localEs r -> Eff (DataLog i : r) r)
    -> Eff (DataLog i : r) a)
-> Eff (DataLog i : r) a
forall a b. (a -> b) -> a -> b
$ \forall {r}. Eff localEs r -> Eff (DataLog i : r) r
unlift -> (i -> i) -> Eff (DataLog i : r) a -> Eff (DataLog i : r) a
forall (r :: [Effect]) i a.
(HasCallStack, r <: DataLog i) =>
(i -> i) -> Eff r a -> Eff r a
S.local i -> i
f (Eff localEs a -> Eff (DataLog i : r) a
forall {r}. Eff localEs r -> Eff (DataLog i : r) r
unlift Eff localEs a
m)