@@ -1,9 +1,10 @@
1+{-# LANGUAGE AllowAmbiguousTypes #-}
1−{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE DataKinds #-}
2−{-# LANGUAGE PolyKinds #-}
3{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE KindSignatures #-}
5{-# LANGUAGE KindSignatures #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
7+{-# LANGUAGE PolyKinds #-}
7{-# LANGUAGE ScopedTypeVariables #-}
8{-# LANGUAGE ScopedTypeVariables #-}
8{-# LANGUAGE TypeApplications #-}
9{-# LANGUAGE TypeApplications #-}
9{-# LANGUAGE TypeOperators #-}
10{-# LANGUAGE TypeOperators #-}
@@ -34,6 +35,7 @@ import Data.Kind
34import GHC.Generics
35import GHC.Generics
35import Data.Generics.Internal.Profunctor.Iso
36import Data.Generics.Internal.Profunctor.Iso
36import Data.Generics.Internal.Profunctor.Prism
37import Data.Generics.Internal.Profunctor.Prism
38+import Data.Generics.Internal.Families.Has
38-- |As 'AsSubtype' but over generic representations as defined by
40-- |As 'AsSubtype' but over generic representations as defined by
39-- "GHC.Generics".
41-- "GHC.Generics".
@@ -41,22 +43,72 @@ class GAsSubtype (subf :: Type -> Type) (supf :: Type -> Type) where
41 _GSub :: Prism' (supf x) (subf x)
43 _GSub :: Prism' (supf x) (subf x)
44− ( GAsSubtype l supf
46+ ( GSplash sub sup
45− , GAsSubtype r supf
47+ , GDowncast sub sup
46− ) => GAsSubtype (l :+: r) supf where
48+ ) => GAsSubtype sub sup where
47− _GSub = without' _GSub _GSub . fromIso sumIso
49+ _GSub f = prismPRavel (prism _GSplash _GDowncast) f
48 {-# INLINE _GSub #-}
50 {-# INLINE _GSub #-}
52+--------------------------------------------------------------------------------
54+class GSplash (sub :: Type -> Type) (sup :: Type -> Type) where
55+ _GSplash :: sub x -> sup x
57+instance (GSplash a sup, GSplash b sup) => GSplash (a :+: b) sup where
58+ _GSplash (L1 rep) = _GSplash rep
59+ _GSplash (R1 rep) = _GSplash rep
60+ {-# INLINE _GSplash #-}
51 ( GIsList () subf subf as as
63 ( GIsList () subf subf as as
52 , GAsType supf as
64 , GAsType supf as
53− ) => GAsSubtype (C1 meta subf) supf where
65+ ) => GSplash (C1 meta subf) supf where
54− _GSub = _GTyped . fromIso (glist @()) . fromIso mIso
66+ _GSplash p = build (prismPRavel (_GTyped . fromIso (glist @()) . fromIso mIso)) p
55− {-# INLINE _GSub #-}
67+ {-# INLINE _GSplash #-}
57−-- instance GAsType supf a => GAsSubtype (S1 meta (Rec0 a)) supf where
69+instance GSplash sub sup => GSplash (D1 c sub) sup where
58−-- _GSub = _GTyped . fromIso (mIso . kIso)
70+ _GSplash (M1 m) = _GSplash m
71+ {-# INLINE _GSplash #-}
60−instance GAsSubtype subf supf => GAsSubtype (D1 meta subf) supf where
73+--------------------------------------------------------------------------------
61− _GSub = _GSub . fromIso mIso
74+
75+class GDowncast sub sup where
76+ _GDowncast :: sup x -> Either (sup x) (sub x)
79+ ( GIsList () sup sup as as
80+ , GDowncastC (HasPartialTypeP as sub) sub sup
81+ ) => GDowncast sub (C1 m sup) where
82+ _GDowncast (M1 m) = case _GDowncastC @(HasPartialTypeP as sub) m of
83+ Left _ -> Left (M1 m)
85+ {-# INLINE _GDowncast #-}
87+instance (GDowncast sub l, GDowncast sub r) => GDowncast sub (l :+: r) where
88+ _GDowncast (L1 x) = case _GDowncast x of
89+ Left _ -> Left (L1 x)
91+ _GDowncast (R1 x) = case _GDowncast x of
92+ Left _ -> Left (R1 x)
94+ {-# INLINE _GDowncast #-}
96+instance GDowncast sub sup => GDowncast sub (D1 m sup) where
97+ _GDowncast (M1 m) = case _GDowncast m of
98+ Left _ -> Left (M1 m)
100+ {-# INLINE _GDowncast #-}
102+class GDowncastC (contains :: Bool) sub sup where
103+ _GDowncastC :: sup x -> Either (sup x) (sub x)
105+instance GDowncastC 'False sub sup where
106+ _GDowncastC sup = Left sup
107+ {-# INLINE _GDowncastC #-}
111+ , GIsList () sup sup subl subl
112+ ) => GDowncastC 'True sub sup where
113+ _GDowncastC sup = Right (build (prismPRavel (_GTyped . fromIso (glist @()))) sup)
62− {-# INLINE _GSub #-}
114+ {-# INLINE _GDowncastC #-}