{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE QuantifiedConstraints #-}

module Bluefin.Internal.DslBuilderEffects where

import Bluefin.Internal
import Bluefin.Internal.OneWayCoercible
  ( OneWayCoercible,
    oneWayCoercible,
    oneWayCoercibleImpl,
  )

newtype DslBuilderEffects h es r
  = MkDslBuilderEffects {forall (h :: Effects -> *) (es :: Effects) r.
DslBuilderEffects h es r
-> forall (e :: Effects). h e -> Eff (e :& es) r
unMkDslBuilderEffects :: forall e. h e -> Eff (e :& es) r}

useImplDslBuilderEffects :: (e :> es) => DslBuilderEffects h e r -> DslBuilderEffects h es r
useImplDslBuilderEffects :: forall (e :: Effects) (es :: Effects) (h :: Effects -> *) r.
(e :> es) =>
DslBuilderEffects h e r -> DslBuilderEffects h es r
useImplDslBuilderEffects (MkDslBuilderEffects forall (e :: Effects). h e -> Eff (e :& e) r
f) = (forall (e :: Effects). h e -> Eff (e :& es) r)
-> DslBuilderEffects h es r
forall (h :: Effects -> *) (es :: Effects) r.
(forall (e :: Effects). h e -> Eff (e :& es) r)
-> DslBuilderEffects h es r
MkDslBuilderEffects (Eff (e :& e) r -> Eff (e :& es) r
forall (e :: Effects) (es :: Effects) (e1 :: Effects) r.
(e :> es) =>
Eff (e1 :& e) r -> Eff (e1 :& es) r
useImplUnder (Eff (e :& e) r -> Eff (e :& es) r)
-> (h e -> Eff (e :& e) r) -> h e -> Eff (e :& es) r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. h e -> Eff (e :& e) r
forall (e :: Effects). h e -> Eff (e :& e) r
f)

runDslBuilderEffects :: h es -> DslBuilderEffects h es r -> Eff es r
runDslBuilderEffects :: forall (h :: Effects -> *) (es :: Effects) r.
h es -> DslBuilderEffects h es r -> Eff es r
runDslBuilderEffects h es
h DslBuilderEffects h es r
f = Eff (es :& es) r -> Eff es r
forall (e :: Effects) r. Eff (e :& e) r -> Eff e r
makeOp (DslBuilderEffects h es r
-> forall (e :: Effects). h e -> Eff (e :& es) r
forall (h :: Effects -> *) (es :: Effects) r.
DslBuilderEffects h es r
-> forall (e :: Effects). h e -> Eff (e :& es) r
unMkDslBuilderEffects DslBuilderEffects h es r
f h es
h)

dslBuilderEffects :: (forall e. h e -> Eff (e :& es) r) -> DslBuilderEffects h es r
dslBuilderEffects :: forall (h :: Effects -> *) (es :: Effects) r.
(forall (e :: Effects). h e -> Eff (e :& es) r)
-> DslBuilderEffects h es r
dslBuilderEffects = (forall (e :: Effects). h e -> Eff (e :& es) r)
-> DslBuilderEffects h es r
forall (h :: Effects -> *) (es :: Effects) r.
(forall (e :: Effects). h e -> Eff (e :& es) r)
-> DslBuilderEffects h es r
MkDslBuilderEffects

instance
  (e :> es) =>
  OneWayCoercible (DslBuilderEffects h e r) (DslBuilderEffects h es r)
  where
  oneWayCoercibleImpl :: OneWayCoercibleD
  (DslBuilderEffects h e r) (DslBuilderEffects h es r)
oneWayCoercibleImpl = OneWayCoercibleD
  (DslBuilderEffects h e r) (DslBuilderEffects h es r)
forall {k} (a :: k) (b :: k). Coercible a b => OneWayCoercibleD a b
oneWayCoercible

instance (Handle h) => Functor (DslBuilderEffects h es) where
  fmap :: forall a b.
(a -> b) -> DslBuilderEffects h es a -> DslBuilderEffects h es b
fmap a -> b
f DslBuilderEffects h es a
g =
    (forall (e :: Effects). h e -> Eff (e :& es) b)
-> DslBuilderEffects h es b
forall (h :: Effects -> *) (es :: Effects) r.
(forall (e :: Effects). h e -> Eff (e :& es) r)
-> DslBuilderEffects h es r
dslBuilderEffects ((forall (e :: Effects). h e -> Eff (e :& es) b)
 -> DslBuilderEffects h es b)
-> (forall (e :: Effects). h e -> Eff (e :& es) b)
-> DslBuilderEffects h es b
forall a b. (a -> b) -> a -> b
$ \h e
h ->
      (a -> b) -> Eff (e :& es) a -> Eff (e :& es) b
forall a b. (a -> b) -> Eff (e :& es) a -> Eff (e :& es) b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (h (e :& es) -> DslBuilderEffects h (e :& es) a -> Eff (e :& es) a
forall (h :: Effects -> *) (es :: Effects) r.
h es -> DslBuilderEffects h es r -> Eff es r
runDslBuilderEffects (h e -> h (e :& es)
forall (e :: Effects) (es :: Effects). (e :> es) => h e -> h es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle h e
h) (DslBuilderEffects h es a -> DslBuilderEffects h (e :& es) a
forall (e :: Effects) (es :: Effects) (h :: Effects -> *) r.
(e :> es) =>
DslBuilderEffects h e r -> DslBuilderEffects h es r
useImplDslBuilderEffects DslBuilderEffects h es a
g))

instance (Handle h) => Applicative (DslBuilderEffects h es) where
  pure :: forall a. a -> DslBuilderEffects h es a
pure a
x = (forall (e :: Effects). h e -> Eff (e :& es) a)
-> DslBuilderEffects h es a
forall (h :: Effects -> *) (es :: Effects) r.
(forall (e :: Effects). h e -> Eff (e :& es) r)
-> DslBuilderEffects h es r
dslBuilderEffects (Eff (e :& es) a -> h e -> Eff (e :& es) a
forall a. a -> h e -> a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> Eff (e :& es) a
forall a. a -> Eff (e :& es) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x))
  DslBuilderEffects h es (a -> b)
f <*> :: forall a b.
DslBuilderEffects h es (a -> b)
-> DslBuilderEffects h es a -> DslBuilderEffects h es b
<*> DslBuilderEffects h es a
x = (forall (e :: Effects). h e -> Eff (e :& es) b)
-> DslBuilderEffects h es b
forall (h :: Effects -> *) (es :: Effects) r.
(forall (e :: Effects). h e -> Eff (e :& es) r)
-> DslBuilderEffects h es r
dslBuilderEffects ((forall (e :: Effects). h e -> Eff (e :& es) b)
 -> DslBuilderEffects h es b)
-> (forall (e :: Effects). h e -> Eff (e :& es) b)
-> DslBuilderEffects h es b
forall a b. (a -> b) -> a -> b
$ \h e
h ->
    h (e :& es)
-> DslBuilderEffects h (e :& es) (a -> b) -> Eff (e :& es) (a -> b)
forall (h :: Effects -> *) (es :: Effects) r.
h es -> DslBuilderEffects h es r -> Eff es r
runDslBuilderEffects (h e -> h (e :& es)
forall (e :: Effects) (es :: Effects). (e :> es) => h e -> h es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle h e
h) (DslBuilderEffects h es (a -> b)
-> DslBuilderEffects h (e :& es) (a -> b)
forall (e :: Effects) (es :: Effects) (h :: Effects -> *) r.
(e :> es) =>
DslBuilderEffects h e r -> DslBuilderEffects h es r
useImplDslBuilderEffects DslBuilderEffects h es (a -> b)
f)
      Eff (e :& es) (a -> b) -> Eff (e :& es) a -> Eff (e :& es) b
forall a b.
Eff (e :& es) (a -> b) -> Eff (e :& es) a -> Eff (e :& es) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> h (e :& es) -> DslBuilderEffects h (e :& es) a -> Eff (e :& es) a
forall (h :: Effects -> *) (es :: Effects) r.
h es -> DslBuilderEffects h es r -> Eff es r
runDslBuilderEffects (h e -> h (e :& es)
forall (e :: Effects) (es :: Effects). (e :> es) => h e -> h es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle h e
h) (DslBuilderEffects h es a -> DslBuilderEffects h (e :& es) a
forall (e :: Effects) (es :: Effects) (h :: Effects -> *) r.
(e :> es) =>
DslBuilderEffects h e r -> DslBuilderEffects h es r
useImplDslBuilderEffects DslBuilderEffects h es a
x)

instance (Handle h) => Monad (DslBuilderEffects h es) where
  DslBuilderEffects h es a
m >>= :: forall a b.
DslBuilderEffects h es a
-> (a -> DslBuilderEffects h es b) -> DslBuilderEffects h es b
>>= a -> DslBuilderEffects h es b
f = (forall (e :: Effects). h e -> Eff (e :& es) b)
-> DslBuilderEffects h es b
forall (h :: Effects -> *) (es :: Effects) r.
(forall (e :: Effects). h e -> Eff (e :& es) r)
-> DslBuilderEffects h es r
dslBuilderEffects ((forall (e :: Effects). h e -> Eff (e :& es) b)
 -> DslBuilderEffects h es b)
-> (forall (e :: Effects). h e -> Eff (e :& es) b)
-> DslBuilderEffects h es b
forall a b. (a -> b) -> a -> b
$ \h e
h -> do
    a
r <- h (e :& es) -> DslBuilderEffects h (e :& es) a -> Eff (e :& es) a
forall (h :: Effects -> *) (es :: Effects) r.
h es -> DslBuilderEffects h es r -> Eff es r
runDslBuilderEffects (h e -> h (e :& es)
forall (e :: Effects) (es :: Effects). (e :> es) => h e -> h es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle h e
h) (DslBuilderEffects h es a -> DslBuilderEffects h (e :& es) a
forall (e :: Effects) (es :: Effects) (h :: Effects -> *) r.
(e :> es) =>
DslBuilderEffects h e r -> DslBuilderEffects h es r
useImplDslBuilderEffects DslBuilderEffects h es a
m)
    h (e :& es) -> DslBuilderEffects h (e :& es) b -> Eff (e :& es) b
forall (h :: Effects -> *) (es :: Effects) r.
h es -> DslBuilderEffects h es r -> Eff es r
runDslBuilderEffects (h e -> h (e :& es)
forall (e :: Effects) (es :: Effects). (e :> es) => h e -> h es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle h e
h) (DslBuilderEffects h es b -> DslBuilderEffects h (e :& es) b
forall (e :: Effects) (es :: Effects) (h :: Effects -> *) r.
(e :> es) =>
DslBuilderEffects h e r -> DslBuilderEffects h es r
useImplDslBuilderEffects (a -> DslBuilderEffects h es b
f a
r))