{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_HADDOCK not-home #-}
module Effectful.Internal.Effect
( Effect
, (:>)(..)
, (:>>)
, Subset(..)
, KnownPrefix(..)
, IsUnknownSuffixOf
, type (++)
, KnownEffects(..)
, Type
) where
import Data.Kind
import GHC.TypeLits
type Effect = (Type -> Type) -> Type -> Type
class (e :: Effect) :> (es :: [Effect]) where
reifyIndex :: Int
reifyIndex =
[Char] -> Int
forall a. HasCallStack => [Char] -> a
error [Char]
"reifyIndex"
instance TypeError
( Text "There is no handler for '" :<>: ShowType e :<>: Text "' in the context"
) => e :> '[] where
reifyIndex :: Int
reifyIndex = [Char] -> Int
forall a. HasCallStack => [Char] -> a
error [Char]
"unreachable"
instance {-# OVERLAPPING #-} e :> (e : es) where
reifyIndex :: Int
reifyIndex = Int
0
instance e :> es => e :> (x : es) where
reifyIndex :: Int
reifyIndex = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ forall (e :: Effect) (es :: [Effect]). (e :> es) => Int
reifyIndex @e @es
type family xs :>> es :: Constraint where
'[] :>> es = ()
(x : xs) :>> es = (x :> es, xs :>> es)
{-# DEPRECATED (:>>) "Usage of (:>>) slows down GHC too much. See https://github.com/haskell-effectful/effectful/issues/52#issuecomment-1269155485 for more information." #-}
class KnownPrefix es => Subset (xs :: [Effect]) (es :: [Effect]) where
subsetFullyKnown :: Bool
subsetFullyKnown =
[Char] -> Bool
forall a. HasCallStack => [Char] -> a
error [Char]
"subsetFullyKnown"
reifyIndices :: [Int]
reifyIndices =
[Char] -> [Int]
forall a. HasCallStack => [Char] -> a
error [Char]
"reifyIndices"
instance {-# INCOHERENT #-}
( KnownPrefix es
, xs `IsUnknownSuffixOf` es
) => Subset xs es where
subsetFullyKnown :: Bool
subsetFullyKnown = Bool
False
reifyIndices :: [Int]
reifyIndices = []
instance KnownPrefix es => Subset '[] es where
subsetFullyKnown :: Bool
subsetFullyKnown = Bool
True
reifyIndices :: [Int]
reifyIndices = []
instance (e :> es, Subset xs es) => Subset (e : xs) es where
subsetFullyKnown :: Bool
subsetFullyKnown = forall (xs :: [Effect]) (es :: [Effect]). Subset xs es => Bool
subsetFullyKnown @xs @es
reifyIndices :: [Int]
reifyIndices = forall (e :: Effect) (es :: [Effect]). (e :> es) => Int
reifyIndex @e @es Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: forall (xs :: [Effect]) (es :: [Effect]). Subset xs es => [Int]
reifyIndices @xs @es
class KnownPrefix (es :: [Effect]) where
prefixLength :: Int
instance KnownPrefix es => KnownPrefix (e : es) where
prefixLength :: Int
prefixLength = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ forall (es :: [Effect]). KnownPrefix es => Int
prefixLength @es
instance {-# INCOHERENT #-} KnownPrefix es where
prefixLength :: Int
prefixLength = Int
0
class (xs :: [Effect]) `IsUnknownSuffixOf` (es :: [Effect])
instance {-# INCOHERENT #-} xs ~ es => xs `IsUnknownSuffixOf` es
instance xs `IsUnknownSuffixOf` es => xs `IsUnknownSuffixOf` (e : es)
type family (xs :: [Effect]) ++ (ys :: [Effect]) :: [Effect] where
'[] ++ ys = ys
(x : xs) ++ ys = x : xs ++ ys
infixr 5 ++
class KnownEffects (es :: [Effect]) where
knownEffectsLength :: Int
knownEffectsLength =
[Char] -> Int
forall a. HasCallStack => [Char] -> a
error [Char]
"knownEffectsLength"
instance KnownEffects es => KnownEffects (e : es) where
knownEffectsLength :: Int
knownEffectsLength = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ forall (es :: [Effect]). KnownEffects es => Int
knownEffectsLength @es
instance KnownEffects '[] where
knownEffectsLength :: Int
knownEffectsLength = Int
0