module Data.Generics.Sum.Internal.Typed
( GAsType (..)
) where
import Data.Kind
import GHC.Generics
import Data.Generics.Internal.Families
import Data.Generics.Internal.HList
import Data.Generics.Internal.Lens
class GAsType (f :: Type -> Type) a where
_GTyped :: Prism' (f x) a
_GTyped = prism ginjectTyped gprojectTyped
ginjectTyped :: a -> f x
gprojectTyped :: f x -> Either (f x) a
instance
( GCollectible f as
, ListTuple a as
) => GAsType (M1 C meta f) a where
ginjectTyped
= M1 . gfromCollection . tupleToList
gprojectTyped
= Right . listToTuple . gtoCollection . unM1
instance GSumAsType (HasPartialTypeTupleP a l) l r a => GAsType (l :+: r) a where
ginjectTyped
= ginjectSumTyped @(HasPartialTypeTupleP a l) @l @r @a
gprojectTyped
= gprojectSumTyped @(HasPartialTypeTupleP a l) @l @r @a
instance GAsType f a => GAsType (M1 D meta f) a where
ginjectTyped
= M1 . ginjectTyped
gprojectTyped
= either (Left . M1) Right . gprojectTyped . unM1
class GSumAsType (contains :: Bool) l r a where
_GSumTyped :: Prism' ((l :+: r) x) a
_GSumTyped = prism (ginjectSumTyped @contains) (gprojectSumTyped @contains)
ginjectSumTyped :: a -> (l :+: r) x
gprojectSumTyped :: (l :+: r) x -> Either ((l :+: r) x) a
instance GAsType l a => GSumAsType 'True l r a where
ginjectSumTyped
= L1 . ginjectTyped
gprojectSumTyped x
= case x of
L1 l -> either (Left . L1) Right (gprojectTyped l)
R1 _ -> Left x
instance GAsType r a => GSumAsType 'False l r a where
ginjectSumTyped
= R1 . ginjectTyped
gprojectSumTyped x
= case x of
R1 r -> either (Left . R1) Right (gprojectTyped r)
L1 _ -> Left x