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

module Bluefin.Internal.CloneableHandle
  ( module Bluefin.Internal.CloneableHandle,
    MonadUnliftIO (withRunInIO),
    MonadIO (liftIO),
    Generic1,
  )
where

import Bluefin.Internal hiding (b, race, w)
import Bluefin.Internal.OneWayCoercible
  ( OneWayCoercible (..),
    unsafeOneWayCoercible,
  )
import Control.Monad.IO.Unlift (MonadIO (liftIO), MonadUnliftIO (withRunInIO))
import Data.Coerce (coerce)
import GHC.Generics
  ( Generic1 (..),
    M1 (M1),
    Rec1 (Rec1),
    (:*:) ((:*:)),
  )
import GHC.TypeLits (ErrorMessage (Text), TypeError)

withEffToIOCloneHandle ::
  (e1 :> es, CloneableHandle h) =>
  IOE e1 ->
  -- | Handle accessible in the continuation
  h es ->
  -- | Continuation with the unlifting function in scope.
  ((forall r. (forall e. IOE e -> h e -> Eff e r) -> IO r) -> IO a) ->
  Eff es a
withEffToIOCloneHandle :: forall (e1 :: Effects) (es :: Effects) (h :: Effects -> *) a.
(e1 :> es, CloneableHandle h) =>
IOE e1
-> h es
-> ((forall r.
     (forall (e :: Effects). IOE e -> h e -> Eff e r) -> IO r)
    -> IO a)
-> Eff es a
withEffToIOCloneHandle IOE e1
io h es
h (forall r.
 (forall (e :: Effects). IOE e -> h e -> Eff e r) -> IO r)
-> IO a
k = do
  IOE e1 -> ((forall {r}. Eff es r -> IO r) -> IO a) -> Eff es a
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
withEffToIO_ IOE e1
io (((forall {r}. Eff es r -> IO r) -> IO a) -> Eff es a)
-> ((forall {r}. Eff es r -> IO r) -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \forall {r}. Eff es r -> IO r
runInIO -> do
    (forall r.
 (forall (e :: Effects). IOE e -> h e -> Eff e r) -> IO r)
-> IO a
k ((forall r.
  (forall (e :: Effects). IOE e -> h e -> Eff e r) -> IO r)
 -> IO a)
-> (forall r.
    (forall (e :: Effects). IOE e -> h e -> Eff e r) -> IO r)
-> IO a
forall a b. (a -> b) -> a -> b
$ \forall (e :: Effects). IOE e -> h e -> Eff e r
body -> do
      Eff es r -> IO r
forall {r}. Eff es r -> IO r
runInIO (Eff es r -> IO r) -> Eff es r -> IO r
forall a b. (a -> b) -> a -> b
$ do
        h es -> (forall {e :: Effects}. h e -> Eff (e :& es) r) -> Eff es r
forall (e1 :: Effects) (es :: Effects) (h :: Effects -> *) r.
(e1 :> es, CloneableHandle h) =>
h e1 -> (forall (e :: Effects). h e -> Eff (e :& es) r) -> Eff es r
cloneHandleClass h es
h ((forall {e :: Effects}. h e -> Eff (e :& es) r) -> Eff es r)
-> (forall {e :: Effects}. h e -> Eff (e :& es) r) -> Eff es r
forall a b. (a -> b) -> a -> b
$ \h e
h' -> do
          IOE e1
-> (forall {e :: Effects}. IOE e -> Eff (e :& (e :& es)) r)
-> Eff (e :& es) r
forall (e1 :: Effects) (es :: Effects) (h :: Effects -> *) r.
(e1 :> es, CloneableHandle h) =>
h e1 -> (forall (e :: Effects). h e -> Eff (e :& es) r) -> Eff es r
cloneHandleClass IOE e1
io ((forall {e :: Effects}. IOE e -> Eff (e :& (e :& es)) r)
 -> Eff (e :& es) r)
-> (forall {e :: Effects}. IOE e -> Eff (e :& (e :& es)) r)
-> Eff (e :& es) r
forall a b. (a -> b) -> a -> b
$ \IOE e
io' -> do
            IOE (e :& (e :& es))
-> h (e :& (e :& es)) -> Eff (e :& (e :& es)) r
forall (e :: Effects). IOE e -> h e -> Eff e r
body (IOE e -> IOE (e :& (e :& es))
forall (e :: Effects) (es :: Effects). (e :> es) => IOE e -> IOE es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle IOE e
io') (h e -> h (e :& (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')

newtype HandleCloner h1 h2 es
  = MkHandleCloner
      ( forall r.
        h1 es ->
        (forall e. h2 e -> Eff (e :& es) r) ->
        Eff es r
      )

instance (Handle h1, Handle h2) => Handle (HandleCloner h1 h2) where
  handleImpl :: HandleD (HandleCloner h1 h2)
handleImpl = HandleD (HandleCloner h1 h2)
forall (h :: Effects -> *).
(forall (e :: Effects) (es :: Effects).
 (e :> es) =>
 OneWayCoercible (h e) (h es)) =>
HandleD h
handleOneWayCoercible

instance
  (Handle h1, Handle h2) =>
  OneWayCoercible
    (HandleCloner h1 h2 e)
    (HandleCloner h1 h2 es)
  where
  -- FIXME: These instances for higher rank types are annoying
  oneWayCoercibleImpl :: OneWayCoercibleD (HandleCloner h1 h2 e) (HandleCloner h1 h2 es)
oneWayCoercibleImpl = OneWayCoercibleD (HandleCloner h1 h2 e) (HandleCloner h1 h2 es)
forall {k} (a :: k) (b :: k). OneWayCoercibleD a b
unsafeOneWayCoercible

cloneHandle2 ::
  (Handle h1, Handle h2, e1 :> es) =>
  HandleCloner h1 h2 es ->
  h1 e1 ->
  (forall e. h2 e -> Eff (e :& es) r) ->
  Eff es r
cloneHandle2 :: forall (h1 :: Effects -> *) (h2 :: Effects -> *) (e1 :: Effects)
       (es :: Effects) r.
(Handle h1, Handle h2, e1 :> es) =>
HandleCloner h1 h2 es
-> h1 e1
-> (forall (e :: Effects). h2 e -> Eff (e :& es) r)
-> Eff es r
cloneHandle2 (MkHandleCloner forall r.
h1 es
-> (forall (e :: Effects). h2 e -> Eff (e :& es) r) -> Eff es r
c) h1 e1
h1 = h1 es
-> (forall (e :: Effects). h2 e -> Eff (e :& es) r) -> Eff es r
forall r.
h1 es
-> (forall (e :: Effects). h2 e -> Eff (e :& es) r) -> Eff es r
c (h1 e1 -> h1 es
forall (e :: Effects) (es :: Effects). (e :> es) => h1 e -> h1 es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle h1 e1
h1)

instance CloneableHandle IOE where
  cloneableHandleImpl :: CloneableHandleD IOE
cloneableHandleImpl = (forall (e :: Effects). HandleCloner IOE IOE e)
-> CloneableHandleD IOE
forall (h :: Effects -> *).
(forall (e :: Effects). HandleCloner h h e) -> CloneableHandleD h
MkCloneableHandleD HandleCloner IOE IOE e
forall (e :: Effects). HandleCloner IOE IOE e
hcIOE

hcIOE :: HandleCloner IOE IOE e
hcIOE :: forall (e :: Effects). HandleCloner IOE IOE e
hcIOE = (forall r.
 IOE e
 -> (forall (e :: Effects). IOE e -> Eff (e :& e) r) -> Eff e r)
-> HandleCloner IOE IOE e
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (es :: Effects).
(forall r.
 h1 es
 -> (forall (e :: Effects). h2 e -> Eff (e :& es) r) -> Eff es r)
-> HandleCloner h1 h2 es
MkHandleCloner ((forall r.
  IOE e
  -> (forall (e :: Effects). IOE e -> Eff (e :& e) r) -> Eff e r)
 -> HandleCloner IOE IOE e)
-> (forall r.
    IOE e
    -> (forall (e :: Effects). IOE e -> Eff (e :& e) r) -> Eff e r)
-> HandleCloner IOE IOE e
forall a b. (a -> b) -> a -> b
$ \IOE e
io forall (e :: Effects). IOE e -> Eff (e :& e) r
k -> do
  (IOE e -> Eff (e :& e) r) -> IOE e -> Eff e r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn IOE e -> Eff (e :& e) r
forall (e :: Effects). IOE e -> Eff (e :& e) r
k (IOE e -> IOE e
forall (e :: Effects) (es :: Effects). (e :> es) => IOE e -> IOE es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle IOE e
io)

-- | Cloning a @State@ copies its contents to a new @State@.  Changes
-- to one will not effect the other.
instance CloneableHandle (State s) where
  cloneableHandleImpl :: CloneableHandleD (State s)
cloneableHandleImpl = (forall (e :: Effects). HandleCloner (State s) (State s) e)
-> CloneableHandleD (State s)
forall (h :: Effects -> *).
(forall (e :: Effects). HandleCloner h h e) -> CloneableHandleD h
MkCloneableHandleD HandleCloner (State s) (State s) e
forall s (e :: Effects). HandleCloner (State s) (State s) e
forall (e :: Effects). HandleCloner (State s) (State s) e
hcState

hcState :: HandleCloner (State s) (State s) e
hcState :: forall s (e :: Effects). HandleCloner (State s) (State s) e
hcState = (forall r.
 State s e
 -> (forall (e :: Effects). State s e -> Eff (e :& e) r) -> Eff e r)
-> HandleCloner (State s) (State s) e
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (es :: Effects).
(forall r.
 h1 es
 -> (forall (e :: Effects). h2 e -> Eff (e :& es) r) -> Eff es r)
-> HandleCloner h1 h2 es
MkHandleCloner ((forall r.
  State s e
  -> (forall (e :: Effects). State s e -> Eff (e :& e) r) -> Eff e r)
 -> HandleCloner (State s) (State s) e)
-> (forall r.
    State s e
    -> (forall (e :: Effects). State s e -> Eff (e :& e) r) -> Eff e r)
-> HandleCloner (State s) (State s) e
forall a b. (a -> b) -> a -> b
$ \State s e
st forall (e :: Effects). State s e -> Eff (e :& e) r
k -> do
  s
s <- State s e -> Eff e s
forall (e :: Effects) (es :: Effects) s.
(e :> es) =>
State s e -> Eff es s
get State s e
st
  s
-> (forall (e :: Effects). State s e -> Eff (e :& e) r) -> Eff e r
forall s (es :: Effects) a.
s
-> (forall (e :: Effects). State s e -> Eff (e :& es) a)
-> Eff es a
evalState s
s ((forall (e :: Effects). State s e -> Eff (e :& e) r) -> Eff e r)
-> (forall (e :: Effects). State s e -> Eff (e :& e) r) -> Eff e r
forall a b. (a -> b) -> a -> b
$ \State s e
st' ->
    (State s (e :& e) -> Eff ((e :& e) :& e) r)
-> State s (e :& e) -> Eff (e :& e) r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn State s (e :& e) -> Eff ((e :& e) :& e) r
forall (e :: Effects). State s e -> Eff (e :& e) r
k (State s e -> State s (e :& e)
forall (e :: Effects) (es :: Effects).
(e :> es) =>
State s e -> State s es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle State s e
st')

instance CloneableHandle (Exception a) where
  cloneableHandleImpl :: CloneableHandleD (Exception a)
cloneableHandleImpl = (forall (e :: Effects). HandleCloner (Exception a) (Exception a) e)
-> CloneableHandleD (Exception a)
forall (h :: Effects -> *).
(forall (e :: Effects). HandleCloner h h e) -> CloneableHandleD h
MkCloneableHandleD HandleCloner (Exception a) (Exception a) e
forall ex (e :: Effects).
HandleCloner (Exception ex) (Exception ex) e
forall (e :: Effects). HandleCloner (Exception a) (Exception a) e
hcException

hcException :: HandleCloner (Exception ex) (Exception ex) e
hcException :: forall ex (e :: Effects).
HandleCloner (Exception ex) (Exception ex) e
hcException = (forall r.
 Exception ex e
 -> (forall (e :: Effects). Exception ex e -> Eff (e :& e) r)
 -> Eff e r)
-> HandleCloner (Exception ex) (Exception ex) e
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (es :: Effects).
(forall r.
 h1 es
 -> (forall (e :: Effects). h2 e -> Eff (e :& es) r) -> Eff es r)
-> HandleCloner h1 h2 es
MkHandleCloner ((forall r.
  Exception ex e
  -> (forall (e :: Effects). Exception ex e -> Eff (e :& e) r)
  -> Eff e r)
 -> HandleCloner (Exception ex) (Exception ex) e)
-> (forall r.
    Exception ex e
    -> (forall (e :: Effects). Exception ex e -> Eff (e :& e) r)
    -> Eff e r)
-> HandleCloner (Exception ex) (Exception ex) e
forall a b. (a -> b) -> a -> b
$ \Exception ex e
ex forall (e :: Effects). Exception ex e -> Eff (e :& e) r
k -> do
  (Exception ex e -> Eff (e :& e) r) -> Exception ex e -> Eff e r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn Exception ex e -> Eff (e :& e) r
forall (e :: Effects). Exception ex e -> Eff (e :& e) r
k (Exception ex e -> Exception ex e
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Exception ex e -> Exception ex es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle Exception ex e
ex)

instance CloneableHandle (Reader r) where
  cloneableHandleImpl :: CloneableHandleD (Reader r)
cloneableHandleImpl = (forall (e :: Effects). HandleCloner (Reader r) (Reader r) e)
-> CloneableHandleD (Reader r)
forall (h :: Effects -> *).
(forall (e :: Effects). HandleCloner h h e) -> CloneableHandleD h
MkCloneableHandleD HandleCloner (Reader r) (Reader r) e
forall r (e :: Effects). HandleCloner (Reader r) (Reader r) e
forall (e :: Effects). HandleCloner (Reader r) (Reader r) e
hcReader

hcReader :: HandleCloner (Reader r) (Reader r) e
hcReader :: forall r (e :: Effects). HandleCloner (Reader r) (Reader r) e
hcReader = (forall r.
 Reader r e
 -> (forall (e :: Effects). Reader r e -> Eff (e :& e) r)
 -> Eff e r)
-> HandleCloner (Reader r) (Reader r) e
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (es :: Effects).
(forall r.
 h1 es
 -> (forall (e :: Effects). h2 e -> Eff (e :& es) r) -> Eff es r)
-> HandleCloner h1 h2 es
MkHandleCloner ((forall r.
  Reader r e
  -> (forall (e :: Effects). Reader r e -> Eff (e :& e) r)
  -> Eff e r)
 -> HandleCloner (Reader r) (Reader r) e)
-> (forall r.
    Reader r e
    -> (forall (e :: Effects). Reader r e -> Eff (e :& e) r)
    -> Eff e r)
-> HandleCloner (Reader r) (Reader r) e
forall a b. (a -> b) -> a -> b
$ \(MkReader State r e
s) forall (e :: Effects). Reader r e -> Eff (e :& e) r
k -> do
  State r e
-> (forall {e :: Effects}. State r e -> Eff (e :& e) r) -> Eff e r
forall (e1 :: Effects) (es :: Effects) (h :: Effects -> *) r.
(e1 :> es, CloneableHandle h) =>
h e1 -> (forall (e :: Effects). h e -> Eff (e :& es) r) -> Eff es r
cloneHandleClass State r e
s ((forall {e :: Effects}. State r e -> Eff (e :& e) r) -> Eff e r)
-> (forall {e :: Effects}. State r e -> Eff (e :& e) r) -> Eff e r
forall a b. (a -> b) -> a -> b
$ \State r e
s' -> do
    (Reader r (e :& e) -> Eff ((e :& e) :& e) r)
-> Reader r (e :& e) -> Eff (e :& e) r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn Reader r (e :& e) -> Eff ((e :& e) :& e) r
forall (e :: Effects). Reader r e -> Eff (e :& e) r
k (State r (e :& e) -> Reader r (e :& e)
forall r (e :: Effects). State r e -> Reader r e
MkReader (State r e -> State r (e :& e)
forall (e :: Effects) (es :: Effects).
(e :> es) =>
State r e -> State r es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle State r e
s'))

-- | Cloning a @HandleReader@ copies its contents to a new
-- @HandleReader@.  Changes to one will not effect the other.
instance (CloneableHandle h) => CloneableHandle (HandleReader h) where
  cloneableHandleImpl :: CloneableHandleD (HandleReader h)
cloneableHandleImpl = (forall (e :: Effects).
 HandleCloner (HandleReader h) (HandleReader h) e)
-> CloneableHandleD (HandleReader h)
forall (h :: Effects -> *).
(forall (e :: Effects). HandleCloner h h e) -> CloneableHandleD h
MkCloneableHandleD HandleCloner (HandleReader h) (HandleReader h) e
forall (e :: Effects).
HandleCloner (HandleReader h) (HandleReader h) e
forall (h :: Effects -> *) (e :: Effects).
CloneableHandle h =>
HandleCloner (HandleReader h) (HandleReader h) e
hcHandleReader

cloneHandleClass ::
  (e1 :> es, CloneableHandle h) =>
  h e1 ->
  (forall e. h e -> Eff (e :& es) r) ->
  Eff es r
cloneHandleClass :: forall (e1 :: Effects) (es :: Effects) (h :: Effects -> *) r.
(e1 :> es, CloneableHandle h) =>
h e1 -> (forall (e :: Effects). h e -> Eff (e :& es) r) -> Eff es r
cloneHandleClass =
  HandleCloner h h es
-> h e1
-> (forall (e :: Effects). h e -> Eff (e :& es) r)
-> Eff es r
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (e1 :: Effects)
       (es :: Effects) r.
(Handle h1, Handle h2, e1 :> es) =>
HandleCloner h1 h2 es
-> h1 e1
-> (forall (e :: Effects). h2 e -> Eff (e :& es) r)
-> Eff es r
cloneHandle2 (case CloneableHandleD h
forall (h :: Effects -> *). CloneableHandle h => CloneableHandleD h
cloneableHandleImpl of MkCloneableHandleD forall (e :: Effects). HandleCloner h h e
c' -> HandleCloner h h es
forall (e :: Effects). HandleCloner h h e
c')

hcHandleReader :: (CloneableHandle h) => HandleCloner (HandleReader h) (HandleReader h) e
hcHandleReader :: forall (h :: Effects -> *) (e :: Effects).
CloneableHandle h =>
HandleCloner (HandleReader h) (HandleReader h) e
hcHandleReader = (forall r.
 HandleReader h e
 -> (forall (e :: Effects). HandleReader h e -> Eff (e :& e) r)
 -> Eff e r)
-> HandleCloner (HandleReader h) (HandleReader h) e
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (es :: Effects).
(forall r.
 h1 es
 -> (forall (e :: Effects). h2 e -> Eff (e :& es) r) -> Eff es r)
-> HandleCloner h1 h2 es
MkHandleCloner ((forall r.
  HandleReader h e
  -> (forall (e :: Effects). HandleReader h e -> Eff (e :& e) r)
  -> Eff e r)
 -> HandleCloner (HandleReader h) (HandleReader h) e)
-> (forall r.
    HandleReader h e
    -> (forall (e :: Effects). HandleReader h e -> Eff (e :& e) r)
    -> Eff e r)
-> HandleCloner (HandleReader h) (HandleReader h) e
forall a b. (a -> b) -> a -> b
$ \HandleReader h e
hr forall (e :: Effects). HandleReader h e -> Eff (e :& e) r
k -> do
  h e
h <- HandleReader h e -> Eff e (h e)
forall (e :: Effects) (es :: Effects) (h :: Effects -> *).
(e :> es, Handle h) =>
HandleReader h e -> Eff es (h es)
askHandle HandleReader h e
hr
  h e -> (forall {e :: Effects}. h e -> Eff (e :& e) r) -> Eff e r
forall (e1 :: Effects) (es :: Effects) (h :: Effects -> *) r.
(e1 :> es, CloneableHandle h) =>
h e1 -> (forall (e :: Effects). h e -> Eff (e :& es) r) -> Eff es r
cloneHandleClass h e
h ((forall {e :: Effects}. h e -> Eff (e :& e) r) -> Eff e r)
-> (forall {e :: Effects}. h e -> Eff (e :& e) r) -> Eff e r
forall a b. (a -> b) -> a -> b
$ \h e
h' -> do
    h e
-> (forall {e :: Effects}.
    HandleReader h e -> Eff (e :& (e :& e)) r)
-> Eff (e :& e) r
forall (e1 :: Effects) (es :: Effects) (h :: Effects -> *) r.
(e1 :> es, Handle h) =>
h e1
-> (forall (e :: Effects). HandleReader h e -> Eff (e :& es) r)
-> Eff es r
runHandleReader h e
h' ((forall {e :: Effects}. HandleReader h e -> Eff (e :& (e :& e)) r)
 -> Eff (e :& e) r)
-> (forall {e :: Effects}.
    HandleReader h e -> Eff (e :& (e :& e)) r)
-> Eff (e :& e) r
forall a b. (a -> b) -> a -> b
$ \HandleReader h e
hr' -> do
      (HandleReader h (e :& (e :& e)) -> Eff ((e :& (e :& e)) :& e) r)
-> HandleReader h (e :& (e :& e)) -> Eff (e :& (e :& e)) r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn HandleReader h (e :& (e :& e)) -> Eff ((e :& (e :& e)) :& e) r
forall (e :: Effects). HandleReader h e -> Eff (e :& e) r
k (HandleReader h e -> HandleReader h (e :& (e :& e))
forall (e :: Effects) (es :: Effects).
(e :> es) =>
HandleReader h e -> HandleReader h es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle HandleReader h e
hr')

instance
  (TypeError (Text "Coroutine cannot be cloned. Perhaps you want an STM channel?")) =>
  CloneableHandle (Coroutine a b)
  where
  cloneableHandleImpl :: CloneableHandleD (Coroutine a b)
cloneableHandleImpl =
    [Char] -> CloneableHandleD (Coroutine a b)
forall a. HasCallStack => [Char] -> a
error [Char]
"instance CloneableHandle (Coroutine a b) not implemented"

instance
  (TypeError (Text "Writer cannot be cloned. Perhaps you want an STM channel?")) =>
  CloneableHandle (Writer w)
  where
  cloneableHandleImpl :: CloneableHandleD (Writer w)
cloneableHandleImpl =
    [Char] -> CloneableHandleD (Writer w)
forall a. HasCallStack => [Char] -> a
error [Char]
"instance CloneableHandle (Writer a) not implemented"

newtype (h1 :~> h2) es = MkArrow (forall e. h1 e -> h2 (e :& es))

instance (Handle h1, Handle h2) => Handle (h1 :~> h2) where
  handleImpl :: HandleD (h1 :~> h2)
handleImpl = HandleD (h1 :~> h2)
forall (h :: Effects -> *).
(forall (e :: Effects) (es :: Effects).
 (e :> es) =>
 OneWayCoercible (h e) (h es)) =>
HandleD h
handleOneWayCoercible

instance
  (Handle h1, Handle h2) =>
  OneWayCoercible
    ((h1 :~> h2) e)
    ((h1 :~> h2) es)
  where
  -- FIXME: These instances for higher rank types are annoying
  oneWayCoercibleImpl :: OneWayCoercibleD ((:~>) h1 h2 e) ((:~>) h1 h2 es)
oneWayCoercibleImpl = OneWayCoercibleD ((:~>) h1 h2 e) ((:~>) h1 h2 es)
forall {k} (a :: k) (b :: k). OneWayCoercibleD a b
unsafeOneWayCoercible

abstract :: (Handle h2) => (forall e. h1 e -> h2 (e :& es)) -> (h1 :~> h2) es
abstract :: forall (h2 :: Effects -> *) (h1 :: Effects -> *) (es :: Effects).
Handle h2 =>
(forall (e :: Effects). h1 e -> h2 (e :& es)) -> (:~>) h1 h2 es
abstract forall (e :: Effects). h1 e -> h2 (e :& es)
k = (forall (e :: Effects). h1 e -> h2 (e :& es)) -> (:~>) h1 h2 es
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (es :: Effects).
(forall (e :: Effects). h1 e -> h2 (e :& es)) -> (:~>) h1 h2 es
MkArrow (h2 (e :& es) -> h2 (e :& es)
forall (e :: Effects) (es :: Effects). (e :> es) => h2 e -> h2 es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle (h2 (e :& es) -> h2 (e :& es))
-> (h1 e -> h2 (e :& es)) -> h1 e -> h2 (e :& es)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. h1 e -> h2 (e :& es)
forall (e :: Effects). h1 e -> h2 (e :& es)
k)

app ::
  (Handle h2) =>
  (h1 :~> h2) e ->
  h1 e ->
  h2 e
app :: forall (h2 :: Effects -> *) (h1 :: Effects -> *) (e :: Effects).
Handle h2 =>
(:~>) h1 h2 e -> h1 e -> h2 e
app (MkArrow forall (e :: Effects). h1 e -> h2 (e :& e)
f) h1 e
h1 = h2 (e :& e) -> h2 e
forall (h :: Effects -> *) (e :: Effects).
Handle h =>
h (e :& e) -> h e
makeOpHandle (h1 e -> h2 (e :& e)
forall (e :: Effects). h1 e -> h2 (e :& e)
f h1 e
h1)
  where
    makeOpHandle :: forall h e. (Handle h) => h (e :& e) -> h e
    makeOpHandle :: forall (h :: Effects -> *) (e :: Effects).
Handle h =>
h (e :& e) -> h e
makeOpHandle = case forall (a :: Effects) (b :: Effects). In a b -> Dict (a :> b)
have @(e :& e) @e (In e e -> In (e :& e) e
forall (e2 :: Effects) (e1 :: Effects).
In e2 e1 -> In (e1 :& e2) e1
subsume1 (ZW -> In e e
forall (a :: Effects). ZW -> In a a
eq (# #) -> ZW
ZW)) of
      Dict ((e :& e) :> e)
Dict -> h (e :& e) -> h e
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

lmapHC ::
  (Handle h, Handle h2) =>
  (h1 :~> h2) e ->
  HandleCloner h2 h e ->
  HandleCloner h1 h e
lmapHC :: forall (h :: Effects -> *) (h2 :: Effects -> *)
       (h1 :: Effects -> *) (e :: Effects).
(Handle h, Handle h2) =>
(:~>) h1 h2 e -> HandleCloner h2 h e -> HandleCloner h1 h e
lmapHC (:~>) h1 h2 e
f HandleCloner h2 h e
hc = (forall r.
 h1 e -> (forall (e :: Effects). h e -> Eff (e :& e) r) -> Eff e r)
-> HandleCloner h1 h e
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (es :: Effects).
(forall r.
 h1 es
 -> (forall (e :: Effects). h2 e -> Eff (e :& es) r) -> Eff es r)
-> HandleCloner h1 h2 es
MkHandleCloner ((forall r.
  h1 e -> (forall (e :: Effects). h e -> Eff (e :& e) r) -> Eff e r)
 -> HandleCloner h1 h e)
-> (forall r.
    h1 e -> (forall (e :: Effects). h e -> Eff (e :& e) r) -> Eff e r)
-> HandleCloner h1 h e
forall a b. (a -> b) -> a -> b
$ \h1 e
h1 forall (e :: Effects). h e -> Eff (e :& e) r
k1 -> HandleCloner h2 h e
-> h2 e
-> (forall (e :: Effects). h e -> Eff (e :& e) r)
-> Eff e r
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (e1 :: Effects)
       (es :: Effects) r.
(Handle h1, Handle h2, e1 :> es) =>
HandleCloner h1 h2 es
-> h1 e1
-> (forall (e :: Effects). h2 e -> Eff (e :& es) r)
-> Eff es r
cloneHandle2 HandleCloner h2 h e
hc ((:~>) h1 h2 e -> h1 e -> h2 e
forall (h2 :: Effects -> *) (h1 :: Effects -> *) (e :: Effects).
Handle h2 =>
(:~>) h1 h2 e -> h1 e -> h2 e
app (:~>) h1 h2 e
f h1 e
h1) h e -> Eff (e :& e) r
forall (e :: Effects). h e -> Eff (e :& e) r
k1

pureHC :: h2 e -> HandleCloner h1 h2 e
pureHC :: forall (h2 :: Effects -> *) (e :: Effects) (h1 :: Effects -> *).
h2 e -> HandleCloner h1 h2 e
pureHC h2 e
h2 = (forall r.
 h1 e -> (forall (e :: Effects). h2 e -> Eff (e :& e) r) -> Eff e r)
-> HandleCloner h1 h2 e
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (es :: Effects).
(forall r.
 h1 es
 -> (forall (e :: Effects). h2 e -> Eff (e :& es) r) -> Eff es r)
-> HandleCloner h1 h2 es
MkHandleCloner ((forall r.
  h1 e -> (forall (e :: Effects). h2 e -> Eff (e :& e) r) -> Eff e r)
 -> HandleCloner h1 h2 e)
-> (forall r.
    h1 e -> (forall (e :: Effects). h2 e -> Eff (e :& e) r) -> Eff e r)
-> HandleCloner h1 h2 e
forall a b. (a -> b) -> a -> b
$ \h1 e
_ forall (e :: Effects). h2 e -> Eff (e :& e) r
k -> Eff (e :& e) r -> Eff e r
forall (e :: Effects) r. Eff (e :& e) r -> Eff e r
makeOp (h2 e -> Eff (e :& e) r
forall (e :: Effects). h2 e -> Eff (e :& e) r
k h2 e
h2)

fmapHC ::
  (Handle h, Handle h1, Handle h2) =>
  (h1 :~> h2) e ->
  HandleCloner h h1 e ->
  HandleCloner h h2 e
fmapHC :: forall (h :: Effects -> *) (h1 :: Effects -> *)
       (h2 :: Effects -> *) (e :: Effects).
(Handle h, Handle h1, Handle h2) =>
(:~>) h1 h2 e -> HandleCloner h h1 e -> HandleCloner h h2 e
fmapHC (:~>) h1 h2 e
f HandleCloner h h1 e
h = (:~>) h1 h2 e -> HandleCloner h (h1 :~> h2) e
forall (h2 :: Effects -> *) (e :: Effects) (h1 :: Effects -> *).
h2 e -> HandleCloner h1 h2 e
pureHC (:~>) h1 h2 e
f HandleCloner h (h1 :~> h2) e
-> HandleCloner h h1 e -> HandleCloner h h2 e
forall (h :: Effects -> *) (h1 :: Effects -> *)
       (h2 :: Effects -> *) (e :: Effects).
(Handle h, Handle h1, Handle h2) =>
HandleCloner h (h1 :~> h2) e
-> HandleCloner h h1 e -> HandleCloner h h2 e
`apHC` HandleCloner h h1 e
h

apHC ::
  (Handle h, Handle h1, Handle h2) =>
  HandleCloner h (h1 :~> h2) e ->
  HandleCloner h h1 e ->
  HandleCloner h h2 e
apHC :: forall (h :: Effects -> *) (h1 :: Effects -> *)
       (h2 :: Effects -> *) (e :: Effects).
(Handle h, Handle h1, Handle h2) =>
HandleCloner h (h1 :~> h2) e
-> HandleCloner h h1 e -> HandleCloner h h2 e
apHC HandleCloner h (h1 :~> h2) e
cf HandleCloner h h1 e
c1 = (forall r.
 h e -> (forall (e :: Effects). h2 e -> Eff (e :& e) r) -> Eff e r)
-> HandleCloner h h2 e
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (es :: Effects).
(forall r.
 h1 es
 -> (forall (e :: Effects). h2 e -> Eff (e :& es) r) -> Eff es r)
-> HandleCloner h1 h2 es
MkHandleCloner ((forall r.
  h e -> (forall (e :: Effects). h2 e -> Eff (e :& e) r) -> Eff e r)
 -> HandleCloner h h2 e)
-> (forall r.
    h e -> (forall (e :: Effects). h2 e -> Eff (e :& e) r) -> Eff e r)
-> HandleCloner h h2 e
forall a b. (a -> b) -> a -> b
$ \h e
h forall (e :: Effects). h2 e -> Eff (e :& e) r
k2 -> do
  HandleCloner h (h1 :~> h2) e
-> h e
-> (forall {e :: Effects}. (:~>) h1 h2 e -> Eff (e :& e) r)
-> Eff e r
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (e1 :: Effects)
       (es :: Effects) r.
(Handle h1, Handle h2, e1 :> es) =>
HandleCloner h1 h2 es
-> h1 e1
-> (forall (e :: Effects). h2 e -> Eff (e :& es) r)
-> Eff es r
cloneHandle2 (HandleCloner h (h1 :~> h2) e -> HandleCloner h (h1 :~> h2) e
forall (e :: Effects) (es :: Effects).
(e :> es) =>
HandleCloner h (h1 :~> h2) e -> HandleCloner h (h1 :~> h2) es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle HandleCloner h (h1 :~> h2) e
cf) h e
h ((forall {e :: Effects}. (:~>) h1 h2 e -> Eff (e :& e) r)
 -> Eff e r)
-> (forall {e :: Effects}. (:~>) h1 h2 e -> Eff (e :& e) r)
-> Eff e r
forall a b. (a -> b) -> a -> b
$ \(:~>) h1 h2 e
hf -> do
    HandleCloner h h1 (e :& e)
-> h e
-> (forall {e :: Effects}. h1 e -> Eff (e :& (e :& e)) r)
-> Eff (e :& e) r
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (e1 :: Effects)
       (es :: Effects) r.
(Handle h1, Handle h2, e1 :> es) =>
HandleCloner h1 h2 es
-> h1 e1
-> (forall (e :: Effects). h2 e -> Eff (e :& es) r)
-> Eff es r
cloneHandle2 (HandleCloner h h1 e -> HandleCloner h h1 (e :& e)
forall (e :: Effects) (es :: Effects).
(e :> es) =>
HandleCloner h h1 e -> HandleCloner h h1 es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle HandleCloner h h1 e
c1) h e
h ((forall {e :: Effects}. h1 e -> Eff (e :& (e :& e)) r)
 -> Eff (e :& e) r)
-> (forall {e :: Effects}. h1 e -> Eff (e :& (e :& e)) r)
-> Eff (e :& e) r
forall a b. (a -> b) -> a -> b
$ \h1 e
h1 -> do
      (h2 (e :& (e :& e)) -> Eff ((e :& (e :& e)) :& e) r)
-> h2 (e :& (e :& e)) -> Eff (e :& (e :& e)) r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn h2 (e :& (e :& e)) -> Eff ((e :& (e :& e)) :& e) r
forall (e :: Effects). h2 e -> Eff (e :& e) r
k2 ((:~>) h1 h2 (e :& (e :& e))
-> h1 (e :& (e :& e)) -> h2 (e :& (e :& e))
forall (h2 :: Effects -> *) (h1 :: Effects -> *) (e :: Effects).
Handle h2 =>
(:~>) h1 h2 e -> h1 e -> h2 e
app ((:~>) h1 h2 e -> (:~>) h1 h2 (e :& (e :& e))
forall (e :: Effects) (es :: Effects).
(e :> es) =>
(:~>) h1 h2 e -> (:~>) h1 h2 es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle (:~>) h1 h2 e
hf) (h1 e -> h1 (e :& (e :& e))
forall (e :: Effects) (es :: Effects). (e :> es) => h1 e -> h1 es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle h1 e
h1))

liftHC2 ::
  forall h h1 h2 hr es.
  (Handle h, Handle h1, Handle h2) =>
  (forall e. h1 e -> h2 e -> hr e) ->
  HandleCloner h h1 es ->
  HandleCloner h h2 es ->
  HandleCloner h hr es
liftHC2 :: forall (h :: Effects -> *) (h1 :: Effects -> *)
       (h2 :: Effects -> *) (hr :: Effects -> *) (es :: Effects).
(Handle h, Handle h1, Handle h2) =>
(forall (e :: Effects). h1 e -> h2 e -> hr e)
-> HandleCloner h h1 es
-> HandleCloner h h2 es
-> HandleCloner h hr es
liftHC2 forall (e :: Effects). h1 e -> h2 e -> hr e
f HandleCloner h h1 es
c1 HandleCloner h h2 es
c2 = (forall r.
 h es
 -> (forall (e :: Effects). hr e -> Eff (e :& es) r) -> Eff es r)
-> HandleCloner h hr es
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (es :: Effects).
(forall r.
 h1 es
 -> (forall (e :: Effects). h2 e -> Eff (e :& es) r) -> Eff es r)
-> HandleCloner h1 h2 es
MkHandleCloner ((forall r.
  h es
  -> (forall (e :: Effects). hr e -> Eff (e :& es) r) -> Eff es r)
 -> HandleCloner h hr es)
-> (forall r.
    h es
    -> (forall (e :: Effects). hr e -> Eff (e :& es) r) -> Eff es r)
-> HandleCloner h hr es
forall a b. (a -> b) -> a -> b
$ \h es
h forall (e :: Effects). hr e -> Eff (e :& es) r
kr -> do
  HandleCloner h h1 es
-> h es
-> (forall {e :: Effects}. h1 e -> Eff (e :& es) r)
-> Eff es r
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (e1 :: Effects)
       (es :: Effects) r.
(Handle h1, Handle h2, e1 :> es) =>
HandleCloner h1 h2 es
-> h1 e1
-> (forall (e :: Effects). h2 e -> Eff (e :& es) r)
-> Eff es r
cloneHandle2 HandleCloner h h1 es
c1 h es
h ((forall {e :: Effects}. h1 e -> Eff (e :& es) r) -> Eff es r)
-> (forall {e :: Effects}. h1 e -> Eff (e :& es) r) -> Eff es r
forall a b. (a -> b) -> a -> b
$ \h1 e
h1 -> do
    HandleCloner h h2 (e :& es)
-> h es
-> (forall {e :: Effects}. h2 e -> Eff (e :& (e :& es)) r)
-> Eff (e :& es) r
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (e1 :: Effects)
       (es :: Effects) r.
(Handle h1, Handle h2, e1 :> es) =>
HandleCloner h1 h2 es
-> h1 e1
-> (forall (e :: Effects). h2 e -> Eff (e :& es) r)
-> Eff es r
cloneHandle2 (HandleCloner h h2 es -> HandleCloner h h2 (e :& es)
forall (e :: Effects) (es :: Effects).
(e :> es) =>
HandleCloner h h2 e -> HandleCloner h h2 es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle HandleCloner h h2 es
c2) h es
h ((forall {e :: Effects}. h2 e -> Eff (e :& (e :& es)) r)
 -> Eff (e :& es) r)
-> (forall {e :: Effects}. h2 e -> Eff (e :& (e :& es)) r)
-> Eff (e :& es) r
forall a b. (a -> b) -> a -> b
$ \h2 e
h2 -> do
      (hr (e :& (e :& es)) -> Eff ((e :& (e :& es)) :& es) r)
-> hr (e :& (e :& es)) -> Eff (e :& (e :& es)) r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn hr (e :& (e :& es)) -> Eff ((e :& (e :& es)) :& es) r
forall (e :: Effects). hr e -> Eff (e :& es) r
kr (h1 (e :& (e :& es)) -> h2 (e :& (e :& es)) -> hr (e :& (e :& es))
forall (e :: Effects). h1 e -> h2 e -> hr e
f (h1 e -> h1 (e :& (e :& es))
forall (e :: Effects) (es :: Effects). (e :> es) => h1 e -> h1 es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle h1 e
h1) (h2 e -> h2 (e :& (e :& es))
forall (e :: Effects) (es :: Effects). (e :> es) => h2 e -> h2 es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle h2 e
h2))

infixr 9 :~>

infixl 9 `apHC`

-- | You can use @DerivingVia@ with @GenericCloneableHandle@ to derive
-- a 'CloneableHandle' instance for your type, as long as it is a
-- product type of @CloneableHandle@s.
newtype GenericCloneableHandle h e = MkGenericCloneableHandle (h e)

instance (Handle h) => Handle (GenericCloneableHandle h) where
  handleImpl :: HandleD (GenericCloneableHandle h)
handleImpl = (forall (e :: Effects) (es :: Effects).
 (e :> es) =>
 GenericCloneableHandle h e -> GenericCloneableHandle h es)
-> HandleD (GenericCloneableHandle h)
forall (h :: Effects -> *).
(forall (e :: Effects) (es :: Effects). (e :> es) => h e -> h es)
-> HandleD h
handleMapHandle ((forall (e :: Effects) (es :: Effects).
  (e :> es) =>
  GenericCloneableHandle h e -> GenericCloneableHandle h es)
 -> HandleD (GenericCloneableHandle h))
-> (forall (e :: Effects) (es :: Effects).
    (e :> es) =>
    GenericCloneableHandle h e -> GenericCloneableHandle h es)
-> HandleD (GenericCloneableHandle h)
forall a b. (a -> b) -> a -> b
$ \(MkGenericCloneableHandle h e
h) ->
    h es -> GenericCloneableHandle h es
forall {k} (h :: k -> *) (e :: k).
h e -> GenericCloneableHandle h e
MkGenericCloneableHandle (h e -> h 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)

instance
  (Handle h, Generic1 h, GCloneableHandle (Rep1 h)) =>
  CloneableHandle (GenericCloneableHandle h)
  where
  cloneableHandleImpl :: CloneableHandleD (GenericCloneableHandle h)
cloneableHandleImpl = CloneableHandleD h -> CloneableHandleD (GenericCloneableHandle h)
forall a b. Coercible a b => a -> b
coerce (forall (h :: Effects -> *).
(Handle h, Generic1 h, GCloneableHandle (Rep1 h)) =>
CloneableHandleD h
gCloneableHandle @h)

newtype CloneableHandleD h = MkCloneableHandleD (forall e. HandleCloner h h e)

getHandleCloner :: (GCloneableHandle h) => HandleCloner h h e
getHandleCloner :: forall (h :: Effects -> *) (e :: Effects).
GCloneableHandle h =>
HandleCloner h h e
getHandleCloner = case CloneableHandleD h
forall (h :: Effects -> *).
GCloneableHandle h =>
CloneableHandleD h
gCloneableHandleImpl of MkCloneableHandleD forall (e :: Effects). HandleCloner h h e
c -> HandleCloner h h e
forall (e :: Effects). HandleCloner h h e
c

gCloneableHandle ::
  forall h.
  (Handle h, Generic1 h) =>
  (GCloneableHandle (Rep1 h)) =>
  CloneableHandleD h
gCloneableHandle :: forall (h :: Effects -> *).
(Handle h, Generic1 h, GCloneableHandle (Rep1 h)) =>
CloneableHandleD h
gCloneableHandle =
  (forall (e :: Effects). HandleCloner h h e) -> CloneableHandleD h
forall (h :: Effects -> *).
(forall (e :: Effects). HandleCloner h h e) -> CloneableHandleD h
MkCloneableHandleD
    ( (:~>) (Rep1 h) h e
-> HandleCloner h (Rep1 h) e -> HandleCloner h h e
forall (h :: Effects -> *) (h1 :: Effects -> *)
       (h2 :: Effects -> *) (e :: Effects).
(Handle h, Handle h1, Handle h2) =>
(:~>) h1 h2 e -> HandleCloner h h1 e -> HandleCloner h h2 e
fmapHC
        ((forall (e :: Effects). Rep1 h e -> h (e :& e))
-> (:~>) (Rep1 h) h e
forall (h2 :: Effects -> *) (h1 :: Effects -> *) (es :: Effects).
Handle h2 =>
(forall (e :: Effects). h1 e -> h2 (e :& es)) -> (:~>) h1 h2 es
abstract (h e -> h (e :& e)
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 (e :& e)) -> (Rep1 h e -> h e) -> Rep1 h e -> h (e :& e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rep1 h e -> h e
forall k (f :: k -> *) (a :: k). Generic1 f => Rep1 f a -> f a
forall (a :: Effects). Rep1 h a -> h a
to1))
        ((:~>) h (Rep1 h) e
-> HandleCloner (Rep1 h) (Rep1 h) e -> HandleCloner h (Rep1 h) e
forall (h :: Effects -> *) (h2 :: Effects -> *)
       (h1 :: Effects -> *) (e :: Effects).
(Handle h, Handle h2) =>
(:~>) h1 h2 e -> HandleCloner h2 h e -> HandleCloner h1 h e
lmapHC ((forall (e :: Effects). h e -> Rep1 h (e :& e))
-> (:~>) h (Rep1 h) e
forall (h2 :: Effects -> *) (h1 :: Effects -> *) (es :: Effects).
Handle h2 =>
(forall (e :: Effects). h1 e -> h2 (e :& es)) -> (:~>) h1 h2 es
abstract (Rep1 h e -> Rep1 h (e :& e)
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Rep1 h e -> Rep1 h es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle (Rep1 h e -> Rep1 h (e :& e))
-> (h e -> Rep1 h e) -> h e -> Rep1 h (e :& e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. h e -> Rep1 h e
forall k (f :: k -> *) (a :: k). Generic1 f => f a -> Rep1 f a
forall (a :: Effects). h a -> Rep1 h a
from1)) HandleCloner (Rep1 h) (Rep1 h) e
forall (h :: Effects -> *) (e :: Effects).
GCloneableHandle h =>
HandleCloner h h e
getHandleCloner)
    )

-- | You can define a @CloneableHandle@ instance for your @Handle@ as
-- long as it is a product type of @CloneableHandle@s.  To define the
-- instance, use @DerivingVia@ and 'GenericCloneableHandle'.  For
-- example:
--
-- @
-- data MyHandle e = MkMyHandle ('Bluefin.Exception.Exception' String e) ('Bluefin.State.State' Int e)
--   deriving ('Bluefin.Compound.Generic', 'Generic1')
--   deriving ('Bluefin.Compound.Handle') via t'Bluefin.Compound.OneWayCoercibleHandle' MyHandle
--   deriving ('CloneableHandle') via 'GenericCloneableHandle' MyHandle
--
-- instance (e t'Bluefin.Eff.:>' es) => t'Bluefin.Compound.OneWayCoercible' (MyHandle e) (MyHandle es) where
--   'Bluefin.Compound.oneWayCoercibleImpl' = 'Bluefin.Compound.gOneWayCoercible'
-- @
class (Handle h) => CloneableHandle h where
  -- | Blah
  cloneableHandleImpl :: CloneableHandleD h

-- | @Generic@ implementation detail of
-- 'GenericCloneableHandle'. Bluefin users should never need to use
-- this directly.
class (Handle h) => GCloneableHandle h where
  gCloneableHandleImpl :: CloneableHandleD h

-- | A cloneable handle is generically cloneable
instance
  (CloneableHandle h) =>
  GCloneableHandle (Rec1 h)
  where
  gCloneableHandleImpl :: CloneableHandleD (Rec1 h)
gCloneableHandleImpl = CloneableHandleD h -> CloneableHandleD (Rec1 h)
forall a b. Coercible a b => a -> b
coerce (forall (h :: Effects -> *). CloneableHandle h => CloneableHandleD h
cloneableHandleImpl @h)

-- | An annotated cloneable handle is generically cloneable
instance
  (GCloneableHandle h) =>
  GCloneableHandle (M1 i t h)
  where
  gCloneableHandleImpl :: CloneableHandleD (M1 i t h)
gCloneableHandleImpl = CloneableHandleD h -> CloneableHandleD (M1 i t h)
forall a b. Coercible a b => a -> b
coerce (forall (h :: Effects -> *).
GCloneableHandle h =>
CloneableHandleD h
gCloneableHandleImpl @h)

-- | A pair of cloneable handles is generically cloneable
instance
  (GCloneableHandle h1, GCloneableHandle h2) =>
  GCloneableHandle (h1 :*: h2)
  where
  gCloneableHandleImpl :: CloneableHandleD (h1 :*: h2)
gCloneableHandleImpl =
    (forall (e :: Effects). HandleCloner (h1 :*: h2) (h1 :*: h2) e)
-> CloneableHandleD (h1 :*: h2)
forall (h :: Effects -> *).
(forall (e :: Effects). HandleCloner h h e) -> CloneableHandleD h
MkCloneableHandleD ((forall (e :: Effects). HandleCloner (h1 :*: h2) (h1 :*: h2) e)
 -> CloneableHandleD (h1 :*: h2))
-> (forall (e :: Effects). HandleCloner (h1 :*: h2) (h1 :*: h2) e)
-> CloneableHandleD (h1 :*: h2)
forall a b. (a -> b) -> a -> b
$
      ((forall (e :: Effects). h1 e -> (:~>) h2 (h1 :*: h2) (e :& e))
-> (:~>) h1 (h2 :~> (h1 :*: h2)) e
forall (h2 :: Effects -> *) (h1 :: Effects -> *) (es :: Effects).
Handle h2 =>
(forall (e :: Effects). h1 e -> h2 (e :& es)) -> (:~>) h1 h2 es
abstract ((forall (e :: Effects). h1 e -> (:~>) h2 (h1 :*: h2) (e :& e))
 -> (:~>) h1 (h2 :~> (h1 :*: h2)) e)
-> (forall (e :: Effects). h1 e -> (:~>) h2 (h1 :*: h2) (e :& e))
-> (:~>) h1 (h2 :~> (h1 :*: h2)) e
forall a b. (a -> b) -> a -> b
$ \h1 e
h1 -> (forall (e :: Effects). h2 e -> (:*:) h1 h2 (e :& (e :& e)))
-> (:~>) h2 (h1 :*: h2) (e :& e)
forall (h2 :: Effects -> *) (h1 :: Effects -> *) (es :: Effects).
Handle h2 =>
(forall (e :: Effects). h1 e -> h2 (e :& es)) -> (:~>) h1 h2 es
abstract ((forall (e :: Effects). h2 e -> (:*:) h1 h2 (e :& (e :& e)))
 -> (:~>) h2 (h1 :*: h2) (e :& e))
-> (forall (e :: Effects). h2 e -> (:*:) h1 h2 (e :& (e :& e)))
-> (:~>) h2 (h1 :*: h2) (e :& e)
forall a b. (a -> b) -> a -> b
$ \h2 e
h2 -> h1 e -> h1 (e :& (e :& e))
forall (e :: Effects) (es :: Effects). (e :> es) => h1 e -> h1 es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle h1 e
h1 h1 (e :& (e :& e))
-> h2 (e :& (e :& e)) -> (:*:) h1 h2 (e :& (e :& e))
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: h2 e -> h2 (e :& (e :& e))
forall (e :: Effects) (es :: Effects). (e :> es) => h2 e -> h2 es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle h2 e
h2)
        (:~>) h1 (h2 :~> (h1 :*: h2)) e
-> HandleCloner (h1 :*: h2) h1 e
-> HandleCloner (h1 :*: h2) (h2 :~> (h1 :*: h2)) e
forall (h :: Effects -> *) (h1 :: Effects -> *)
       (h2 :: Effects -> *) (e :: Effects).
(Handle h, Handle h1, Handle h2) =>
(:~>) h1 h2 e -> HandleCloner h h1 e -> HandleCloner h h2 e
`fmapHC` (:~>) (h1 :*: h2) h1 e
-> HandleCloner h1 h1 e -> HandleCloner (h1 :*: h2) h1 e
forall (h :: Effects -> *) (h2 :: Effects -> *)
       (h1 :: Effects -> *) (e :: Effects).
(Handle h, Handle h2) =>
(:~>) h1 h2 e -> HandleCloner h2 h e -> HandleCloner h1 h e
lmapHC ((forall (e :: Effects). (:*:) h1 h2 e -> h1 (e :& e))
-> (:~>) (h1 :*: h2) h1 e
forall (h2 :: Effects -> *) (h1 :: Effects -> *) (es :: Effects).
Handle h2 =>
(forall (e :: Effects). h1 e -> h2 (e :& es)) -> (:~>) h1 h2 es
abstract ((forall (e :: Effects). (:*:) h1 h2 e -> h1 (e :& e))
 -> (:~>) (h1 :*: h2) h1 e)
-> (forall (e :: Effects). (:*:) h1 h2 e -> h1 (e :& e))
-> (:~>) (h1 :*: h2) h1 e
forall a b. (a -> b) -> a -> b
$ \(h1 e
h1 :*: h2 e
_) -> h1 e -> h1 (e :& e)
forall (e :: Effects) (es :: Effects). (e :> es) => h1 e -> h1 es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle h1 e
h1) HandleCloner h1 h1 e
forall (h :: Effects -> *) (e :: Effects).
GCloneableHandle h =>
HandleCloner h h e
getHandleCloner
        HandleCloner (h1 :*: h2) (h2 :~> (h1 :*: h2)) e
-> HandleCloner (h1 :*: h2) h2 e
-> HandleCloner (h1 :*: h2) (h1 :*: h2) e
forall (h :: Effects -> *) (h1 :: Effects -> *)
       (h2 :: Effects -> *) (e :: Effects).
(Handle h, Handle h1, Handle h2) =>
HandleCloner h (h1 :~> h2) e
-> HandleCloner h h1 e -> HandleCloner h h2 e
`apHC` (:~>) (h1 :*: h2) h2 e
-> HandleCloner h2 h2 e -> HandleCloner (h1 :*: h2) h2 e
forall (h :: Effects -> *) (h2 :: Effects -> *)
       (h1 :: Effects -> *) (e :: Effects).
(Handle h, Handle h2) =>
(:~>) h1 h2 e -> HandleCloner h2 h e -> HandleCloner h1 h e
lmapHC ((forall (e :: Effects). (:*:) h1 h2 e -> h2 (e :& e))
-> (:~>) (h1 :*: h2) h2 e
forall (h2 :: Effects -> *) (h1 :: Effects -> *) (es :: Effects).
Handle h2 =>
(forall (e :: Effects). h1 e -> h2 (e :& es)) -> (:~>) h1 h2 es
abstract ((forall (e :: Effects). (:*:) h1 h2 e -> h2 (e :& e))
 -> (:~>) (h1 :*: h2) h2 e)
-> (forall (e :: Effects). (:*:) h1 h2 e -> h2 (e :& e))
-> (:~>) (h1 :*: h2) h2 e
forall a b. (a -> b) -> a -> b
$ \(h1 e
_ :*: h2 e
h2) -> h2 e -> h2 (e :& e)
forall (e :: Effects) (es :: Effects). (e :> es) => h2 e -> h2 es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle h2 e
h2) HandleCloner h2 h2 e
forall (h :: Effects -> *) (e :: Effects).
GCloneableHandle h =>
HandleCloner h h e
getHandleCloner