@@ -1,7 +1,6 @@
1{-# LANGUAGE AllowAmbiguousTypes #-}
1{-# LANGUAGE AllowAmbiguousTypes #-}
2{-# LANGUAGE ConstraintKinds #-}
2{-# LANGUAGE ConstraintKinds #-}
3{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE DataKinds #-}
4−{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE KindSignatures #-}
5{-# LANGUAGE KindSignatures #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
@@ -13,8 +12,6 @@
13{-# LANGUAGE TypeOperators #-}
12{-# LANGUAGE TypeOperators #-}
14{-# LANGUAGE UndecidableInstances #-}
13{-# LANGUAGE UndecidableInstances #-}
16−{-# LANGUAGE UndecidableSuperClasses #-}
18-----------------------------------------------------------------------------
15-----------------------------------------------------------------------------
20-- Module : Data.Generics.Product.Types
17-- Module : Data.Generics.Product.Types
@@ -37,7 +34,7 @@ module Data.Generics.Product.Types
39import Data.Generics.Product.Internal.Types
36import Data.Generics.Product.Internal.Types
40−import Data.Generics.Product.Constraints
37+import Data.Kind (Constraint)
42import GHC.Generics
39import GHC.Generics
43import Data.Generics.Internal.VL.Traversal
40import Data.Generics.Internal.VL.Traversal
@@ -56,14 +53,65 @@ instance
56class HasTypesDeep a s where
53class HasTypesDeep a s where
57 typesDeep :: Traversal' s a
54 typesDeep :: Traversal' s a
57+ foldOr :: Applicative g => (a -> g a) -> b -> g b
62+instance {-# OVERLAPPABLE #-} Or a b where
66+ ( HasConstraints' (Or a) s
59−instance Deep (Equals a) s => HasTypesDeep a s where
67+ ) => HasTypesDeep a s where
60− typesDeep f = constraints @(Deep (Equals a)) (foldEquals f (typesDeep @a f))
69+ typesDeep f s = constraints' @(Or a) (foldOr f) s
71+--------------------------------------------------------------------------------
72+type family Primitive a :: Bool where
73+ Primitive Int = 'True
74+ Primitive Char = 'True
75+ Primitive Bool = 'True
76+ Primitive Integer = 'True
78+ -- TODO: more primitives, or perhaps abstract from stop condition
81+-- deep constrained traversals, stopping at primitive types
82+class HasConstraints' (c :: * -> Constraint) s where
83+ constraints' :: forall g.
84+ Applicative g => (forall a. c a => a -> g a) -> s -> g s
86+instance (Generic s, GHasConstraints' c (Rep s)) => HasConstraints' c s where
87+ constraints' f s = to <$> gconstraints' @c f (from s)
89+class GHasConstraints' (c :: * -> Constraint) (f :: * -> *) where
90+ gconstraints' :: forall g x.
91+ Applicative g => (forall a. c a => a -> g a) -> f x -> g (f x)
93+instance (GHasConstraints' c l, GHasConstraints' c r) => GHasConstraints' c (l :*: r) where
94+ gconstraints' f (l :*: r) = (:*:) <$> gconstraints' @c f l <*> gconstraints' @c f r
96+instance (GHasConstraints' c l, GHasConstraints' c r) => GHasConstraints' c (l :+: r) where
97+ gconstraints' f (L1 l) = L1 <$> gconstraints' @c f l
98+ gconstraints' f (R1 r) = R1 <$> gconstraints' @c f r
100+instance GRec c (Primitive a) (K1 R a) => GHasConstraints' c (K1 R a) where
101+ gconstraints' = grec @c @(Primitive a)
103+instance GHasConstraints' c f => GHasConstraints' c (M1 m meta f) where
104+ gconstraints' f (M1 x) = M1 <$> gconstraints' @c f x
106+instance GHasConstraints' c U1 where
107+ gconstraints' _ _ = pure U1
62−class Equals a b where
109+class GRec (c :: * -> Constraint) (s :: Bool) (f :: * -> *) where
63− foldEquals :: (a -> g a) -> (b -> g b) -> b -> g b
110+ grec :: forall g x.
111+ Applicative g => (forall a. c a => a -> g a) -> f x -> g (f x)
65−instance Equals a a where
113+instance HasConstraints' c a => GRec c 'False (K1 R a) where
66− foldEquals f _ = f
114+ grec f (K1 s) = K1 <$> constraints' @c @a f s
68−instance {-# OVERLAPPABLE #-} Equals a b where
116+instance c a => GRec c 'True (K1 R a) where
69− foldEquals _ g = g
117+ grec f s = kIso f s