@@ -1,3 +1,5 @@
1+{-# LANGUAGE TypeInType #-}
2+{-# LANGUAGE PartialTypeSignatures #-}
1{-# LANGUAGE CPP #-}
3{-# LANGUAGE CPP #-}
2{-# LANGUAGE AllowAmbiguousTypes #-}
4{-# LANGUAGE AllowAmbiguousTypes #-}
3{-# LANGUAGE ConstraintKinds #-}
5{-# LANGUAGE ConstraintKinds #-}
@@ -42,12 +44,14 @@ import Data.Generics.Internal.VL.Lens as VL
42import Data.Generics.Internal.Void
44import Data.Generics.Internal.Void
43import Data.Generics.Internal.Families
45import Data.Generics.Internal.Families
44import Data.Generics.Product.Internal.Positions
46import Data.Generics.Product.Internal.Positions
47+import Data.Generics.Product.Internal.GLens
46import Data.Kind (Constraint, Type)
49import Data.Kind (Constraint, Type)
47import Data.Type.Bool (type (&&))
50import Data.Type.Bool (type (&&))
48import GHC.Generics
51import GHC.Generics
49import GHC.TypeLits (type (<=?), Nat, TypeError, ErrorMessage(..))
52import GHC.TypeLits (type (<=?), Nat, TypeError, ErrorMessage(..))
50−import Data.Generics.Internal.Profunctor.Lens
53+import Data.Generics.Internal.Profunctor.Lens as P
53-- == /Running example:/
57-- == /Running example:/
@@ -101,9 +105,11 @@ setPosition = VL.set (position' @i)
102 ( Generic s
106 ( Generic s
103 , ErrorUnless i s (0 <? i && i <=? Size (Rep s))
107 , ErrorUnless i s (0 <? i && i <=? Size (Rep s))
104− , GHasPosition' i (Rep s) a
108+ , cs ~ CRep s
109+ , Coercible (Rep s) cs
110+ , GLens' (HasTotalPositionPSym i) cs a
105 ) => HasPosition' i s a where
111 ) => HasPosition' i s a where
106− position' f s = VL.ravel (repLens . gposition @i) f s
112+ position' f s = VL.ravel (repLens . coerced @cs @cs . glens @(HasTotalPositionPSym i)) f s
107 {-# INLINE position' #-}
113 {-# INLINE position' #-}
109instance -- see Note [Changing type parameters]
115instance -- see Note [Changing type parameters]
@@ -119,17 +125,28 @@ instance -- see Note [Changing type parameters]
120 , Generic s'
126 , Generic s'
121 , Generic t'
127 , Generic t'
122− , GHasPosition' i (Rep s) a
128+ , GLens (HasTotalPositionPSym i) cs ct a b
123− , GHasPosition' i (Rep s') a'
129+ , cs ~ CRep s
124− , GHasPosition i (Rep s) (Rep t) a b
130+ , ct ~ CRep t
131+ , GLens' (HasTotalPositionPSym i) (CRep s') a'
132+ , GLens' (HasTotalPositionPSym i) (CRep t') b'
125 , t ~ Infer s a' b
133 , t ~ Infer s a' b
126− , GHasPosition' i (Rep t') b'
127 , s ~ Infer t b' a
134 , s ~ Infer t b' a
135+ , Coercible cs (Rep s)
136+ , Coercible ct (Rep t)
128 ) => HasPosition i s t a b where
137 ) => HasPosition i s t a b where
130− position = VL.ravel (repLens . gposition @i)
139+ position = VL.ravel (repLens . coerced @cs @ct . glens @(HasTotalPositionPSym i))
131 {-# INLINE position #-}
140 {-# INLINE position #-}
142+-- We wouldn't need the universal 'x' here if we could express above that
143+-- forall x. Coercible (cs x) (Rep s x), but this requires quantified
145+coerced :: forall s t s' t' x a b. (Coercible t t', Coercible s s')
146+ => P.ALens a b (s x) (t x) -> P.ALens a b (s' x) (t' x)
148+{-# INLINE coerced #-}
133-- See Note [Uncluttering type signatures]
150-- See Note [Uncluttering type signatures]
134instance {-# OVERLAPPING #-} HasPosition f (Void1 a) (Void1 b) a b where
151instance {-# OVERLAPPING #-} HasPosition f (Void1 a) (Void1 b) a b where
135 position = undefined
152 position = undefined
@@ -145,3 +162,6 @@ type family ErrorUnless (i :: Nat) (s :: Type) (hasP :: Bool) :: Constraint wher
146 ErrorUnless _ _ 'True
163 ErrorUnless _ _ 'True
166+data HasTotalPositionPSym :: Nat -> (TyFun (Type -> Type) Bool)
167+type instance Eval (HasTotalPositionPSym t) tt = HasTotalPositionP t tt