{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Capability.Derive where
import Capability.Constraints
import Data.Coerce (Coercible)
import Unsafe.Coerce (unsafeCoerce)
derive ::
forall t (derived :: [Capability]) (ambient :: [Capability]) m a.
( forall x. Coercible (t m x) (m x)
, All derived (t m)
, All ambient m)
=> (forall m'. (All derived m', All ambient m') => m' a) -> m a
derive :: (forall (m' :: * -> *). (All derived m', All ambient m') => m' a)
-> m a
derive forall (m' :: * -> *). (All derived m', All ambient m') => m' a
action =
let tmDict :: Dict (All derived (t m))
tmDict = All derived (t m) => Dict (All derived (t m))
forall (a :: Constraint). a => Dict a
Dict @(All derived (t m))
mDict :: Dict (All derived m)
mDict =
Dict (All derived (t m)) -> Dict (All derived m)
forall a b. a -> b
unsafeCoerce @_ @(Dict (All derived m)) Dict (All derived (t m))
tmDict in
case Dict (All derived m)
mDict of
Dict (All derived m)
Dict -> m a
forall (m' :: * -> *). (All derived m', All ambient m') => m' a
action
{-# INLINE derive #-}