{-# LANGUAGE AllowAmbiguousTypes #-}
{-# OPTIONS_HADDOCK not-home #-}
module Cleff.Internal.Env
( Env
, Handling
, Handler
, esSend
, empty
, read
, adjust
, overwriteLocal
, overwriteGlobal
, overwriteSelfGlobal
, extend
, update
) where
import Cleff.Internal.Monad
import Cleff.Internal.Stack (Stack)
import qualified Cleff.Internal.Stack as Stack
import Data.Any (fromAny, pattern Any)
import qualified Data.RadixVec as Vec
import Prelude hiding (read)
import Unsafe.Coerce (unsafeCoerce)
newtype InternalHandler e = InternalHandler (∀ es. e (Eff es) ~> Eff es)
data SendSite esSend e = SendSite
{-# UNPACK #-} !(Env esSend)
{-# UNPACK #-} !(HandlerPtr e)
class Handling esSend e es | esSend -> e es where
sendSite :: SendSite esSend e
sendSite = [Char] -> SendSite esSend e
forall a. HasCallStack => [Char] -> a
error
[Char]
"Cleff.Internal.Env.sendSite: Attempting to access the send site without a reflected value. This is perhaps \
\because you are trying to define an instance for the 'Handling' typeclass, which you should not be doing \
\whatsoever. If that or other shenanigans seem unlikely, please report this as a bug."
hdlPtr :: ∀ esSend e es. Handling esSend e es => HandlerPtr e
hdlPtr :: HandlerPtr e
hdlPtr = let SendSite Env esSend
_ HandlerPtr e
ptr = forall k (esSend :: [Effect]) (e :: Effect) (es :: k).
Handling esSend e es =>
SendSite esSend e
forall (e :: Effect) (es :: k).
Handling esSend e es =>
SendSite esSend e
sendSite @esSend in HandlerPtr e
ptr
esSend :: Handling esSend e es => Env esSend
esSend :: Env esSend
esSend = let SendSite Env esSend
env HandlerPtr e
_ = SendSite esSend e
forall k (esSend :: [Effect]) (e :: Effect) (es :: k).
Handling esSend e es =>
SendSite esSend e
sendSite in Env esSend
env
newtype InstHandling esSend e es a = InstHandling (Handling esSend e es => a)
instHandling :: ∀ esSend e es a. (Handling esSend e es => a) -> SendSite esSend e -> a
instHandling :: (Handling esSend e es => a) -> SendSite esSend e -> a
instHandling Handling esSend e es => a
x = InstHandling esSend e es a -> SendSite esSend e -> a
forall a b. a -> b
unsafeCoerce ((Handling esSend e es => a) -> InstHandling esSend e es a
forall k (esSend :: [Effect]) (e :: Effect) (es :: k) a.
(Handling esSend e es => a) -> InstHandling esSend e es a
InstHandling Handling esSend e es => a
x :: InstHandling esSend e es a)
type Handler e es = ∀ esSend. Handling esSend e es => e (Eff esSend) ~> Eff es
mkInternalHandler :: HandlerPtr e -> Env es -> Handler e es -> InternalHandler e
mkInternalHandler :: HandlerPtr e -> Env es -> Handler e es -> InternalHandler e
mkInternalHandler HandlerPtr e
ptr Env es
es Handler e es
handle = (forall (es :: [Effect]). e (Eff es) ~> Eff es)
-> InternalHandler e
forall (e :: Effect).
(forall (es :: [Effect]). e (Eff es) ~> Eff es)
-> InternalHandler e
InternalHandler \e (Eff es) a
e -> (Env es -> IO a) -> Eff es a
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
Eff \Env es
ess ->
Eff es a -> Env es -> IO a
forall (es :: [Effect]) a. Eff es a -> Env es -> IO a
unEff ((Handling es e es => e (Eff es) a -> Eff es a)
-> SendSite es e -> e (Eff es) a -> Eff es a
forall k (esSend :: [Effect]) (e :: Effect) (es :: k) a.
(Handling esSend e es => a) -> SendSite esSend e -> a
instHandling Handling es e es => e (Eff es) a -> Eff es a
Handler e es
handle (Env es -> HandlerPtr e -> SendSite es e
forall (esSend :: [Effect]) (e :: Effect).
Env esSend -> HandlerPtr e -> SendSite esSend e
SendSite Env es
ess HandlerPtr e
ptr) e (Eff es) a
e) (Env es -> Env es -> Env es
forall (es :: [Effect]) (es' :: [Effect]).
Env es' -> Env es -> Env es
update Env es
ess Env es
es)
empty :: Env '[]
empty :: Env '[]
empty = Stack '[] -> RadixVec Any -> Env '[]
forall (es :: [Effect]). Stack es -> RadixVec Any -> Env es
Env Stack '[]
Stack.empty RadixVec Any
forall a. RadixVec a
Vec.empty
read :: ∀ e es. e :> es => Env es -> ∀ es'. e (Eff es') ~> Eff es'
read :: Env es -> forall (es' :: [Effect]). e (Eff es') ~> Eff es'
read (Env Stack es
stack RadixVec Any
heap) = Any -> e (Eff es') a -> Eff es' a
forall a. Any -> a
fromAny (Any -> e (Eff es') a -> Eff es' a)
-> Any -> e (Eff es') a -> Eff es' a
forall a b. (a -> b) -> a -> b
$ Int -> RadixVec Any -> Any
forall a. Int -> RadixVec a -> a
Vec.lookup (HandlerPtr e -> Int
forall (e :: Effect). HandlerPtr e -> Int
unHandlerPtr (Stack es -> HandlerPtr e
forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Stack es -> HandlerPtr e
Stack.index @e Stack es
stack)) RadixVec Any
heap
adjust :: ∀ es' es. (Stack es -> Stack es') -> Env es -> Env es'
adjust :: (Stack es -> Stack es') -> Env es -> Env es'
adjust Stack es -> Stack es'
f = \(Env Stack es
stack RadixVec Any
heap) -> Stack es' -> RadixVec Any -> Env es'
forall (es :: [Effect]). Stack es -> RadixVec Any -> Env es
Env (Stack es -> Stack es'
f Stack es
stack) RadixVec Any
heap
overwriteGlobal :: ∀ e es es'. e :> es => Env es' -> Handler e es' -> Env es -> Env es
overwriteGlobal :: Env es' -> Handler e es' -> Env es -> Env es
overwriteGlobal Env es'
es Handler e es'
hdl (Env Stack es
stack RadixVec Any
heap) = Stack es -> RadixVec Any -> Env es
forall (es :: [Effect]). Stack es -> RadixVec Any -> Env es
Env Stack es
stack (RadixVec Any -> Env es) -> RadixVec Any -> Env es
forall a b. (a -> b) -> a -> b
$
Int -> Any -> RadixVec Any -> RadixVec Any
forall a. Int -> a -> RadixVec a -> RadixVec a
Vec.update Int
m (InternalHandler e -> Any
forall a. a -> Any
Any (InternalHandler e -> Any) -> InternalHandler e -> Any
forall a b. (a -> b) -> a -> b
$ HandlerPtr e -> Env es' -> Handler e es' -> InternalHandler e
forall (e :: Effect) (es :: [Effect]).
HandlerPtr e -> Env es -> Handler e es -> InternalHandler e
mkInternalHandler HandlerPtr e
ptr Env es'
es Handler e es'
hdl) RadixVec Any
heap
where ptr :: HandlerPtr e
ptr@(HandlerPtr Int
m) = Stack es -> HandlerPtr e
forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
Stack es -> HandlerPtr e
Stack.index @e Stack es
stack
overwriteSelfGlobal :: ∀ e es es' esSend. Handling esSend e es => Env es' -> Handler e es' -> Env esSend -> Env esSend
overwriteSelfGlobal :: Env es' -> Handler e es' -> Env esSend -> Env esSend
overwriteSelfGlobal Env es'
es Handler e es'
hdl (Env Stack esSend
stack RadixVec Any
heap) = Stack esSend -> RadixVec Any -> Env esSend
forall (es :: [Effect]). Stack es -> RadixVec Any -> Env es
Env Stack esSend
stack (RadixVec Any -> Env esSend) -> RadixVec Any -> Env esSend
forall a b. (a -> b) -> a -> b
$
Int -> Any -> RadixVec Any -> RadixVec Any
forall a. Int -> a -> RadixVec a -> RadixVec a
Vec.update Int
ix (InternalHandler e -> Any
forall a. a -> Any
Any (InternalHandler e -> Any) -> InternalHandler e -> Any
forall a b. (a -> b) -> a -> b
$ HandlerPtr e -> Env es' -> Handler e es' -> InternalHandler e
forall (e :: Effect) (es :: [Effect]).
HandlerPtr e -> Env es -> Handler e es -> InternalHandler e
mkInternalHandler HandlerPtr e
ptr Env es'
es Handler e es'
hdl) RadixVec Any
heap
where ptr :: HandlerPtr e
ptr@(HandlerPtr Int
ix) = forall k (esSend :: [Effect]) (e :: Effect) (es :: k).
Handling esSend e es =>
HandlerPtr e
forall (e :: Effect) (es :: k).
Handling esSend e es =>
HandlerPtr e
hdlPtr @esSend
overwriteLocal :: ∀ e es es'. e :> es => Env es' -> Handler e es' -> Env es -> Env es
overwriteLocal :: Env es' -> Handler e es' -> Env es -> Env es
overwriteLocal Env es'
es Handler e es'
hdl (Env Stack es
stack RadixVec Any
heap) = Stack es -> RadixVec Any -> Env es
forall (es :: [Effect]). Stack es -> RadixVec Any -> Env es
Env
(HandlerPtr e -> Stack es -> Stack es
forall (e :: Effect) (es :: [Effect]).
(e :> es) =>
HandlerPtr e -> Stack es -> Stack es
Stack.update @e HandlerPtr e
ptr Stack es
stack)
(RadixVec Any -> Any -> RadixVec Any
forall a. RadixVec a -> a -> RadixVec a
Vec.snoc RadixVec Any
heap (Any -> RadixVec Any) -> Any -> RadixVec Any
forall a b. (a -> b) -> a -> b
$ InternalHandler e -> Any
forall a. a -> Any
Any (InternalHandler e -> Any) -> InternalHandler e -> Any
forall a b. (a -> b) -> a -> b
$ HandlerPtr e -> Env es' -> Handler e es' -> InternalHandler e
forall (e :: Effect) (es :: [Effect]).
HandlerPtr e -> Env es -> Handler e es -> InternalHandler e
mkInternalHandler HandlerPtr e
ptr Env es'
es Handler e es'
hdl)
where ptr :: HandlerPtr e
ptr = Int -> HandlerPtr e
forall (e :: Effect). Int -> HandlerPtr e
HandlerPtr (RadixVec Any -> Int
forall a. RadixVec a -> Int
Vec.size RadixVec Any
heap)
extend :: ∀ e es es'. Env es' -> Handler e es' -> Env es -> Env (e : es)
extend :: Env es' -> Handler e es' -> Env es -> Env (e : es)
extend Env es'
es Handler e es'
hdl (Env Stack es
stack RadixVec Any
heap) = Stack (e : es) -> RadixVec Any -> Env (e : es)
forall (es :: [Effect]). Stack es -> RadixVec Any -> Env es
Env
(HandlerPtr e -> Stack es -> Stack (e : es)
forall (e :: Effect) (es :: [Effect]).
HandlerPtr e -> Stack es -> Stack (e : es)
Stack.cons HandlerPtr e
ptr Stack es
stack)
(RadixVec Any -> Any -> RadixVec Any
forall a. RadixVec a -> a -> RadixVec a
Vec.snoc RadixVec Any
heap (Any -> RadixVec Any) -> Any -> RadixVec Any
forall a b. (a -> b) -> a -> b
$ InternalHandler e -> Any
forall a. a -> Any
Any (InternalHandler e -> Any) -> InternalHandler e -> Any
forall a b. (a -> b) -> a -> b
$ HandlerPtr e -> Env es' -> Handler e es' -> InternalHandler e
forall (e :: Effect) (es :: [Effect]).
HandlerPtr e -> Env es -> Handler e es -> InternalHandler e
mkInternalHandler HandlerPtr e
ptr Env es'
es Handler e es'
hdl)
where ptr :: HandlerPtr e
ptr = Int -> HandlerPtr e
forall (e :: Effect). Int -> HandlerPtr e
HandlerPtr (RadixVec Any -> Int
forall a. RadixVec a -> Int
Vec.size RadixVec Any
heap)
update :: ∀ es es'. Env es' -> Env es -> Env es
update :: Env es' -> Env es -> Env es
update (Env Stack es'
_ RadixVec Any
heap) (Env Stack es
stack RadixVec Any
_) = Stack es -> RadixVec Any -> Env es
forall (es :: [Effect]). Stack es -> RadixVec Any -> Env es
Env Stack es
stack RadixVec Any
heap