@@ -1,9 +1,14 @@
1+{-# LANGUAGE AllowAmbiguousTypes #-}
2+{-# LANGUAGE DataKinds #-}
3+{-# LANGUAGE FlexibleContexts #-}
14{-# LANGUAGE FlexibleInstances #-}
25{-# LANGUAGE KindSignatures #-}
36{-# LANGUAGE MultiParamTypeClasses #-}
47{-# LANGUAGE ScopedTypeVariables #-}
58{-# LANGUAGE TypeApplications #-}
9+{-# LANGUAGE TypeFamilies #-}
610{-# LANGUAGE TypeOperators #-}
11+{-# LANGUAGE UndecidableInstances #-}
712
813module Data.Generics.Product.Typed
914 ( HasType (..)
@@ -15,14 +20,27 @@ import Data.Generics.Internal.Lens
1520
1621import Data.Kind (Type)
1722import GHC.Generics
18−import GHC.TypeLits
1923
2024class HasType a s where
2125 typed :: Lens' s a
2226
27+instance (Generic s,
28+ FindType a (Rep s) ~ 'Just a,
29+ CountType a (Rep s) ~ 'One,
30+ GHasType (Rep s) a)
31+
32+ => HasType a s where
33+
34+ typed = repIso . gtyped
35+
2336class GHasType (f :: Type -> Type) a where
2437 gtyped :: Lens' (f x) a
2538
39+instance GProductHasType l r a (FindType a l)
40+ => GHasType (l :*: r) a where
41+
42+ gtyped = gproductTyped @_ @_ @_ @(FindType a l)
43+
2644instance (GHasType l a, GHasType r a) => GHasType (l :+: r) a where
2745 gtyped = combine (gtyped @l) (gtyped @r)
2846
@@ -37,3 +55,12 @@ instance GHasType f a => GHasType (M1 D meta f) a where
3755
3856instance GHasType f a => GHasType (M1 C meta f) a where
3957 gtyped = mIso . gtyped
58+
59+class GProductHasType l r a (found :: Maybe Type) where
60+ gproductTyped :: Lens' ((l :*: r) x) a
61+
62+instance GHasType l a => GProductHasType l r a ('Just a) where
63+ gproductTyped = first . gtyped
64+
65+instance GHasType r a => GProductHasType l r a 'Nothing where
66+ gproductTyped = second . gtyped