{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Generics.Sum.Internal.Typed
( GAsType (..)
) where
import Data.Kind
import GHC.Generics
import Data.Tagged
import Data.Generics.Internal.Families
import Data.Generics.Product.Internal.List
import Data.Generics.Internal.Profunctor.Iso
import Data.Generics.Internal.Profunctor.Prism
class GAsType (f :: Type -> Type) (as :: [((), Type)]) where
_GTyped :: Prism (f x) (f x) (List as) (List as)
{-# SPECIALISE _GTyped :: (Tagged b b -> Tagged t t) #-}
instance
( GIsList () f f as as
) => GAsType (M1 C meta f) as where
_GTyped = mIso . glist @()
{-# INLINE[0] _GTyped #-}
instance GSumAsType (HasPartialTypeP a l) l r a => GAsType (l :+: r) a where
_GTyped = _GSumTyped @(HasPartialTypeP a l)
{-# INLINE[0] _GTyped #-}
instance GAsType f a => GAsType (M1 D meta f) a where
_GTyped = mIso . _GTyped
{-# INLINE[0] _GTyped #-}
class GSumAsType (contains :: Bool) l r (a :: [((), Type)]) where
_GSumTyped :: Prism ((l :+: r) x) ((l :+: r) x) (List a) (List a)
instance GAsType l a => GSumAsType 'True l r a where
_GSumTyped = left . _GTyped
{-# INLINE[0] _GSumTyped #-}
instance GAsType r a => GSumAsType 'False l r a where
_GSumTyped = right . _GTyped
{-# INLINE[0] _GSumTyped #-}