{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}
module Dep.Injects
(
Injects (..),
InjectsAll
)
where
import Data.Coerce
import Data.Kind
import GHC.Records
import GHC.TypeLits
type Injects :: ((Type -> Type) -> Type) -> (Type -> Type) -> Type -> Constraint
class Injects r_ (m :: Type -> Type) (accum :: Type) | accum -> m where
inject :: r_ m -> accum
instance (Monoid b) => Injects r_ m (r_ m, b) where
inject :: r_ m -> (r_ m, b)
inject r_ m
r = (r_ m
r, forall a. Monoid a => a
mempty)
instance (Monoid a) => Injects r_ m (a, r_ m) where
inject :: r_ m -> (a, r_ m)
inject r_ m
r = (forall a. Monoid a => a
mempty, r_ m
r)
instance (Monoid b, Monoid c) => Injects r_ m (r_ m, b, c) where
inject :: r_ m -> (r_ m, b, c)
inject r_ m
r = (r_ m
r, forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty)
instance (Monoid a, Monoid c) => Injects r_ m (a, r_ m, c) where
inject :: r_ m -> (a, r_ m, c)
inject r_ m
r = (forall a. Monoid a => a
mempty, r_ m
r, forall a. Monoid a => a
mempty)
instance (Monoid a, Monoid b) => Injects r_ m (a, b, r_ m) where
inject :: r_ m -> (a, b, r_ m)
inject r_ m
r = (forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty, r_ m
r)
instance (Monoid b, Monoid c, Monoid d) => Injects r_ m (r_ m, b, c, d) where
inject :: r_ m -> (r_ m, b, c, d)
inject r_ m
r = (r_ m
r, forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty)
instance (Monoid a, Monoid c, Monoid d) => Injects r_ m (a, r_ m, c, d) where
inject :: r_ m -> (a, r_ m, c, d)
inject r_ m
r = (forall a. Monoid a => a
mempty, r_ m
r, forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty)
instance (Monoid a, Monoid b, Monoid d) => Injects r_ m (a, b, r_ m, d) where
inject :: r_ m -> (a, b, r_ m, d)
inject r_ m
r = (forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty, r_ m
r, forall a. Monoid a => a
mempty)
instance (Monoid a, Monoid b, Monoid c) => Injects r_ m (a, b, c, r_ m) where
inject :: r_ m -> (a, b, c, r_ m)
inject r_ m
r = (forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty, r_ m
r)
type InjectsAll :: [(Type -> Type) -> Type] -> (Type -> Type) -> Type -> Constraint
type family InjectsAll rs_ m e where
InjectsAll '[] m e = ()
InjectsAll (r_ : rs_) m e = (Injects r_ m e, InjectsAll rs_ m e)