exon-1.7.3.0: lib/Exon/Generic.hs
{-# options_haddock prune #-}
-- | Description: Internal
module Exon.Generic where
import GHC.Generics (C1, D1, K1 (K1), M1 (M1), Meta (MetaData), Rep, S1, from, to)
type family PrepRep (rep :: Type -> Type) :: Maybe Type where
PrepRep (D1 ('MetaData _ _ _ 'True) (C1 _ (S1 _ (K1 _ w)))) = 'Just w
PrepRep (D1 ('MetaData _ _ _ 'True) (C1 _ (K1 _ w))) = 'Just w
class RepIsNewtype (rep :: Maybe Type) (wrapped :: Maybe Type) | rep -> wrapped
instance {-# incoherent #-} wrapped ~ 'Nothing => RepIsNewtype rep wrapped
instance wrapped ~ 'Just w => RepIsNewtype ('Just w) wrapped
class IsNewtype w (wrapped :: Maybe Type) | w -> wrapped
instance RepIsNewtype (PrepRep (Rep w)) wrapped => IsNewtype w wrapped
type NewtypeRep :: Symbol -> Symbol -> Symbol -> Meta -> Type -> Type -> Type -> Type
type NewtypeRep n m p c i w =
D1 ('MetaData n m p 'True) (S1 c (K1 i w))
class UnwrapField (rep :: Type -> Type) (w :: Type) | rep -> w where
unwrapField :: rep x -> w
-- | Record selector
instance UnwrapField (S1 s (K1 i w)) w where
unwrapField (M1 (K1 w)) = w
-- | Plain field
instance UnwrapField (K1 i w) w where
unwrapField (K1 w) = w
class Unwrap (a :: Type) (w :: Type) | a -> w where
unwrap :: a -> w
-- | Constructor ('C1') in a data type ('D1') that's a newtype (@'True@)
instance (
Generic a,
Rep a ~ D1 ('MetaData n m p 'True) (C1 c field),
UnwrapField field w
) => Unwrap a w where
unwrap (from -> M1 (M1 field)) = unwrapField field
class WrapField (rep :: Type -> Type) (w :: Type) | rep -> w where
wrapField :: w -> rep x
-- | Record selector
instance WrapField (S1 s (K1 i w)) w where
wrapField = M1 . K1
-- | Plain field
instance WrapField (K1 i w) w where
wrapField = K1
class Wrap (a :: Type) (w :: Type) | a -> w where
wrap :: w -> a
instance (
Generic a,
Rep a ~ D1 ('MetaData n m p 'True) (C1 c field),
WrapField field w
) => Wrap a w where
wrap w = to (M1 (M1 (wrapField w)))
type OverNt (a :: Type) (w :: Type) =
(Wrap a w, Unwrap a w)