{-# LANGUAGE DerivingVia #-}
module Bluefin.Internal.GadtEffect where
import Bluefin.Internal
( Eff,
Effects,
Handle,
HandleReader,
OneWayCoercibleHandle (..),
localHandle,
mapHandle,
oneWayCoercibleTrustMe,
useImplIn,
useImplUnder,
(:&),
(:>),
)
import Bluefin.Internal.OneWayCoercible (OneWayCoercible (oneWayCoercibleImpl), OneWayCoercibleD)
import Data.Kind (Type)
type Send :: Effect -> Effects -> Type
newtype Send f e = MkSend (EffectHandler f e)
deriving (HandleD (Send f)
HandleD (Send f) -> Handle (Send f)
forall (h :: Effects -> *). HandleD h -> Handle h
forall (f :: Effect). HandleD (Send f)
$chandleImpl :: forall (f :: Effect). HandleD (Send f)
handleImpl :: HandleD (Send f)
Handle) via OneWayCoercibleHandle (Send f)
type Effect = (Type -> Type) -> Type -> Type
instance (e :> es) => OneWayCoercible (Send f e) (Send f es) where
oneWayCoercibleImpl :: OneWayCoercibleD (Send f e) (Send f es)
oneWayCoercibleImpl =
(forall (e' :: Effects) (es' :: Effects).
(e' :> es') =>
Send f e' -> Send f es')
-> OneWayCoercibleD (Send f e) (Send f es)
forall (e :: Effects) (es :: Effects) (h :: Effects -> *).
(e :> es) =>
(forall (e' :: Effects) (es' :: Effects).
(e' :> es') =>
h e' -> h es')
-> OneWayCoercibleD (h e) (h es)
oneWayCoercibleTrustMe (\(MkSend EffectHandler f e'
g) -> EffectHandler f es' -> Send f es'
forall (f :: Effect) (e :: Effects). EffectHandler f e -> Send f e
MkSend (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)
-> (f (Eff e) r -> Eff (e :& e') r)
-> f (Eff e) r
-> Eff (e :& es') r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f (Eff e) r -> Eff (e :& e') r
EffectHandler f e'
g))
send ::
(e1 :> es) =>
Send f e1 ->
f (Eff es) r ->
Eff es r
send :: forall (e1 :: Effects) (es :: Effects) (f :: Effect) r.
(e1 :> es) =>
Send f e1 -> f (Eff es) r -> Eff es r
send (MkSend EffectHandler f e1
g) = (f (Eff es) r -> Eff (es :& e1) r) -> f (Eff es) r -> Eff es r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn f (Eff es) r -> Eff (es :& e1) r
EffectHandler f e1
g
type EffectHandler f es =
forall e r.
f (Eff e) r ->
Eff (e :& es) r
interpret ::
EffectHandler f es ->
(forall e. Send f e -> Eff (e :& es) r) ->
Eff es r
interpret :: forall (f :: Effect) (es :: Effects) r.
EffectHandler f es
-> (forall (e :: Effects). Send f e -> Eff (e :& es) r) -> Eff es r
interpret EffectHandler f es
g forall (e :: Effects). Send f e -> Eff (e :& es) r
k = (Send f es -> Eff (es :& es) r) -> Send f es -> Eff es r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn Send f es -> Eff (es :& es) r
forall (e :: Effects). Send f e -> Eff (e :& es) r
k (EffectHandler f es -> Send f es
forall (f :: Effect) (e :: Effects). EffectHandler f e -> Send f e
MkSend f (Eff e) r -> Eff (e :& es) r
EffectHandler f es
g)
type GadtEffect :: ((Type -> Type) -> Type -> Type) -> Type -> Effects -> Type
newtype GadtEffect f a e = MkGadtEffect {forall (f :: Effect) a (e :: Effects).
GadtEffect f a e -> f (Eff e) a
unGadtEffect :: f (Eff e) a}
mapGadtEffect ::
(f1 (Eff e1) r1 -> f2 (Eff e2) r2) ->
GadtEffect f1 r1 e1 ->
GadtEffect f2 r2 e2
mapGadtEffect :: forall (f1 :: Effect) (e1 :: Effects) r1 (f2 :: Effect)
(e2 :: Effects) r2.
(f1 (Eff e1) r1 -> f2 (Eff e2) r2)
-> GadtEffect f1 r1 e1 -> GadtEffect f2 r2 e2
mapGadtEffect f1 (Eff e1) r1 -> f2 (Eff e2) r2
f = f2 (Eff e2) r2 -> GadtEffect f2 r2 e2
forall (f :: Effect) a (e :: Effects).
f (Eff e) a -> GadtEffect f a e
MkGadtEffect (f2 (Eff e2) r2 -> GadtEffect f2 r2 e2)
-> (GadtEffect f1 r1 e1 -> f2 (Eff e2) r2)
-> GadtEffect f1 r1 e1
-> GadtEffect f2 r2 e2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f1 (Eff e1) r1 -> f2 (Eff e2) r2
f (f1 (Eff e1) r1 -> f2 (Eff e2) r2)
-> (GadtEffect f1 r1 e1 -> f1 (Eff e1) r1)
-> GadtEffect f1 r1 e1
-> f2 (Eff e2) r2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GadtEffect f1 r1 e1 -> f1 (Eff e1) r1
forall (f :: Effect) a (e :: Effects).
GadtEffect f a e -> f (Eff e) a
unGadtEffect
oneWayCoercibleGadtEffectTrustMe ::
(e :> es) =>
(forall e' es'. (e' :> es') => f (Eff e') r -> f (Eff es') r) ->
OneWayCoercibleD (GadtEffect f r e) (GadtEffect f r es)
oneWayCoercibleGadtEffectTrustMe :: forall (e :: Effects) (es :: Effects) (f :: Effect) r.
(e :> es) =>
(forall (e' :: Effects) (es' :: Effects).
(e' :> es') =>
f (Eff e') r -> f (Eff es') r)
-> OneWayCoercibleD (GadtEffect f r e) (GadtEffect f r es)
oneWayCoercibleGadtEffectTrustMe forall (e' :: Effects) (es' :: Effects).
(e' :> es') =>
f (Eff e') r -> f (Eff es') r
k = (forall (e' :: Effects) (es' :: Effects).
(e' :> es') =>
GadtEffect f r e' -> GadtEffect f r es')
-> OneWayCoercibleD (GadtEffect f r e) (GadtEffect f r es)
forall (e :: Effects) (es :: Effects) (h :: Effects -> *).
(e :> es) =>
(forall (e' :: Effects) (es' :: Effects).
(e' :> es') =>
h e' -> h es')
-> OneWayCoercibleD (h e) (h es)
oneWayCoercibleTrustMe ((f (Eff e') r -> f (Eff es') r)
-> GadtEffect f r e' -> GadtEffect f r es'
forall (f1 :: Effect) (e1 :: Effects) r1 (f2 :: Effect)
(e2 :: Effects) r2.
(f1 (Eff e1) r1 -> f2 (Eff e2) r2)
-> GadtEffect f1 r1 e1 -> GadtEffect f2 r2 e2
mapGadtEffect f (Eff e') r -> f (Eff es') r
forall (e' :: Effects) (es' :: Effects).
(e' :> es') =>
f (Eff e') r -> f (Eff es') r
k)
passthrough ::
(Handle (GadtEffect f r), e1 :> es, e2 :> es) =>
Send f e1 ->
f (Eff e2) r ->
Eff es r
passthrough :: forall (f :: Effect) r (e1 :: Effects) (es :: Effects)
(e2 :: Effects).
(Handle (GadtEffect f r), e1 :> es, e2 :> es) =>
Send f e1 -> f (Eff e2) r -> Eff es r
passthrough Send f e1
fc = Send f e1 -> f (Eff es) r -> Eff es r
forall (e1 :: Effects) (es :: Effects) (f :: Effect) r.
(e1 :> es) =>
Send f e1 -> f (Eff es) r -> Eff es r
send Send f e1
fc (f (Eff es) r -> Eff es r)
-> (f (Eff e2) r -> f (Eff es) r) -> f (Eff e2) r -> Eff es r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GadtEffect f r es -> f (Eff es) r
forall (f :: Effect) a (e :: Effects).
GadtEffect f a e -> f (Eff e) a
unGadtEffect (GadtEffect f r es -> f (Eff es) r)
-> (f (Eff e2) r -> GadtEffect f r es)
-> f (Eff e2) r
-> f (Eff es) r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GadtEffect f r e2 -> GadtEffect f r es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle (GadtEffect f r e2 -> GadtEffect f r es)
-> (f (Eff e2) r -> GadtEffect f r e2)
-> f (Eff e2) r
-> GadtEffect f r es
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f (Eff e2) r -> GadtEffect f r e2
forall (f :: Effect) a (e :: Effects).
f (Eff e) a -> GadtEffect f a e
MkGadtEffect
interpose ::
(e1 :> es) =>
(Send f es -> EffectHandler f es) ->
HandleReader (Send f) e1 ->
Eff es r ->
Eff es r
interpose :: forall (e1 :: Effects) (es :: Effects) (f :: Effect) r.
(e1 :> es) =>
(Send f es -> EffectHandler f es)
-> HandleReader (Send f) e1 -> Eff es r -> Eff es r
interpose Send f es -> EffectHandler f es
h HandleReader (Send f) e1
hr = HandleReader (Send f) e1
-> (Send f es -> Send f es) -> Eff es r -> Eff es r
forall (e :: Effects) (es :: Effects) (h :: Effects -> *) r.
(e :> es, Handle h) =>
HandleReader h e -> (h es -> h es) -> Eff es r -> Eff es r
localHandle HandleReader (Send f) e1
hr (\Send f es
fcOrig -> EffectHandler f es -> Send f es
forall (f :: Effect) (e :: Effects). EffectHandler f e -> Send f e
MkSend (Send f es -> EffectHandler f es
h Send f es
fcOrig))