@@ -1,7 +1,7 @@
1−{-# LANGUAGE DefaultSignatures #-}
2{-# LANGUAGE AllowAmbiguousTypes #-}
1{-# LANGUAGE AllowAmbiguousTypes #-}
3{-# LANGUAGE ConstraintKinds #-}
2{-# LANGUAGE ConstraintKinds #-}
4{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE DataKinds #-}
4+{-# LANGUAGE DefaultSignatures #-}
5{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE KindSignatures #-}
6{-# LANGUAGE KindSignatures #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
@@ -34,7 +34,6 @@ module Data.Generics.Product.Types
36import Data.Kind
36import Data.Kind
39import GHC.Generics
38import GHC.Generics
40import Data.Generics.Internal.VL.Traversal
39import Data.Generics.Internal.VL.Traversal
@@ -47,24 +46,24 @@ class HasTypes a s where
47 {-# INLINE types #-}
46 {-# INLINE types #-}
50− ( HasTypes1 (Interesting s a) a s
49+ ( Hastypes' (Interesting s a) a s
51 ) => HasTypes a s where
50 ) => HasTypes a s where
52− types = types1 @(Interesting s a)
51+ types = types' @(Interesting s a)
53 {-# INLINE types #-}
52 {-# INLINE types #-}
55−class HasTypes1 (t :: Bool) a s where
54+class Hastypes' (t :: Bool) a s where
56− types1 :: Traversal' s a
55+ types' :: Traversal' s a
59 ( GHasTypes a (Rep s)
58 ( GHasTypes a (Rep s)
60 , Generic s
59 , Generic s
61− ) => HasTypes1 'True a s where
60+ ) => Hastypes' 'True a s where
62− types1 f s = to <$> gtypes f (from s)
61+ types' f s = to <$> gtypes f (from s)
63− --{-# INLINE types1 #-}
62+ --{-# INLINE types' #-}
65−instance HasTypes1 'False a s where
64+instance Hastypes' 'False a s where
66− types1 _ = pure
65+ types' _ = pure
67− --{-# INLINE types1 #-}
66+ --{-# INLINE types' #-}
69instance {-# OVERLAPPING #-} HasTypes a Bool
68instance {-# OVERLAPPING #-} HasTypes a Bool
70instance {-# OVERLAPPING #-} HasTypes a Char
69instance {-# OVERLAPPING #-} HasTypes a Char
@@ -110,29 +109,43 @@ instance GHasTypes a U1 where
110 gtypes _ _ = pure U1
109 gtypes _ _ = pure U1
111 {-# INLINE gtypes #-}
110 {-# INLINE gtypes #-}
113−--instance GHasTypes a V1 where
115−type Interesting f a = Interesting' f (Rep f) a
113+instance GHasTypes a V1 where
115+ {-# INLINE gtypes #-}
117+type Interesting f a = Interesting' (Rep f) a '[f]
117−type family Interesting' orig f (a :: Type) :: Bool where
119+type family Interesting' f (a :: Type) (seen :: [Type]) :: Bool where
118− Interesting' orig (M1 _ m f) t
120+ Interesting' (M1 _ m f) t seen
119− = Interesting' orig f t
121+ = Interesting' f t seen
120− Interesting' orig (l :*: r) t
122+ Interesting' (l :*: r) t seen
121− = Interesting' orig l t || Interesting' orig r t
123+ = InterestingOr (Interesting' l t seen) r t seen
122− Interesting' orig (l :+: r) t
124+ Interesting' (l :+: r) t seen
123− = Interesting' orig l t || Interesting' orig r t
125+ = InterestingOr (Interesting' l t seen) r t seen
124− Interesting' orig (Rec0 t) t
126+ Interesting' (Rec0 t) t seen
126− Interesting' _ (Rec0 Bool) _ = 'False
127− Interesting' _ (Rec0 Char) _ = 'False
128− Interesting' _ (Rec0 Double) _ = 'False
129− Interesting' _ (Rec0 Float) _ = 'False
130− Interesting' _ (Rec0 Int) _ = 'False
131− Interesting' _ (Rec0 Integer) _ = 'False
132− Interesting' _ (Rec0 Ordering) _ = 'False
133− Interesting' orig (Rec0 orig) _
135− Interesting' _ (Rec0 _) _
128+ Interesting' (Rec0 Char) _ _ = 'False
129+ Interesting' (Rec0 Double) _ _ = 'False
130+ Interesting' (Rec0 Float) _ _ = 'False
131+ Interesting' (Rec0 Int) _ _ = 'False
132+ Interesting' (Rec0 Integer) _ _ = 'False
133+ Interesting' (Rec0 r) t seen
134+ = InterestingUnless (Elem r seen) (Rep r) t (r ': seen)
137 Interesting' _ _ _
135 Interesting' _ _ _
139+type family InterestingUnless (s :: Bool) f (a :: Type) (seen :: [Type]) :: Bool where
140+ InterestingUnless 'True _ _ _ = 'False
141+ InterestingUnless 'False f a seen = Interesting' f a seen
144+type family InterestingOr (b :: Bool) r t seen where
145+ InterestingOr 'True _ _ _ = 'True
146+ InterestingOr 'False r t seen = Interesting' r t seen
148+type family Elem a as where
149+ Elem a (a ': _) = 'True
150+ Elem a (_ ': as) = Elem a as