{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Generics.Product.Internal.Constraints
(
GHasConstraints (..)
, GHasConstraints' (..)
) where
import Data.Kind (Type, Constraint)
import GHC.Generics
import Data.Generics.Internal.VL.Iso
import Data.Generics.Internal.VL.Traversal
import Data.Generics.Product.Internal.HList
class GHasConstraints' (c :: * -> Constraint) (f :: * -> *) where
gconstraints' :: forall g x.
Applicative g => (forall a. c a => a -> g a) -> f x -> g (f x)
instance
( GHasConstraints' c l
, GHasConstraints' c r
) => GHasConstraints' c (l :*: r) where
gconstraints' f (l :*: r)
= (:*:) <$> gconstraints' @c f l <*> gconstraints' @c f r
instance
( GHasConstraints' c l
, GHasConstraints' c r
) => GHasConstraints' c (l :+: r) where
gconstraints' f (L1 l) = L1 <$> gconstraints' @c f l
gconstraints' f (R1 r) = R1 <$> gconstraints' @c f r
instance c a => GHasConstraints' c (Rec0 a) where
gconstraints' = kIso
instance GHasConstraints' c f
=> GHasConstraints' c (M1 m meta f) where
gconstraints' f (M1 x) = M1 <$> gconstraints' @c f x
instance GHasConstraints' c U1 where
gconstraints' _ _ = pure U1
class GHasConstraints (c :: * -> * -> Constraint) s t where
gconstraints :: TraversalC c (s x) (t x)
instance
( GHasConstraints c l l'
, GHasConstraints c r r'
) => GHasConstraints c (l :*: r) (l' :*: r') where
gconstraints f (l :*: r)
= (:*:) <$> gconstraints @c f l <*> gconstraints @c f r
instance
( GHasConstraints c l l'
, GHasConstraints c r r'
) => GHasConstraints c (l :+: r) (l' :+: r') where
gconstraints f (L1 l) = L1 <$> gconstraints @c f l
gconstraints f (R1 r) = R1 <$> gconstraints @c f r
instance GHasConstraints c s t
=> GHasConstraints c (M1 i m s) (M1 i m t) where
gconstraints f (M1 x) = M1 <$> gconstraints @c f x
instance GHasConstraints c U1 U1 where
gconstraints _ _ = pure U1
instance GHasConstraints c V1 V1 where
gconstraints _ = pure
instance c a b => GHasConstraints c (Rec0 a) (Rec0 b) where
gconstraints = kIso
type family Functions (ts :: [Type]) (g :: Type -> Type) = r | r -> ts where
Functions '[] _ = '[]
Functions (t ': ts) g = ((t -> g t) ': Functions ts g)
class Contains as a where
pick :: Applicative g => HList (Functions as g) -> a -> g a
instance {-# OVERLAPPING #-} Contains (a ': as) a where
pick (h :> _) = h
instance Contains as a => Contains (b ': as) a where
pick (_ :> hs) = pick hs
instance Contains '[] a where
pick _ = pure