{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}
module Generic.Data.Internal.Newtype where
import Data.Coerce (Coercible, coerce)
import Data.Kind (Constraint, Type)
import GHC.Generics (Generic(..), D1, C1, S1, K1)
import GHC.TypeLits (TypeError, ErrorMessage(..))
import Generic.Data.Internal.Meta (MetaDataNewtype, MetaOf)
class (Generic a, Coercible a (Old a), Newtype' a) => Newtype a
instance (Generic a, Coercible a (Old a), Newtype' a) => Newtype a
type Old a = GOld (Rep a)
type family GOld (f :: Type -> Type) where
GOld (D1 _d (C1 _c (S1 _s (K1 _i b)))) = b
type Newtype' a = NewtypeErr a (MetaDataNewtype (MetaOf (Rep a)))
type family NewtypeErr a (b :: Bool) :: Constraint where
NewtypeErr a 'True = ()
NewtypeErr a 'False = TypeError
('Text "The type " ':<>: 'ShowType a ':<>: 'Text " is not a newtype.")
unpack :: Newtype a => a -> Old a
unpack :: forall a. Newtype a => a -> Old a
unpack = a -> GOld (Rep a)
forall a b. Coercible a b => a -> b
coerce
pack :: Newtype a => Old a -> a
pack :: forall a. Newtype a => Old a -> a
pack = GOld (Rep a) -> a
forall a b. Coercible a b => a -> b
coerce