{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}
module Plutarch.Internal.Generic (
PGeneric,
PGeneric',
PCode,
gpfrom,
gpto,
) where
import Data.Constraint (Dict (Dict))
import Data.Kind (Constraint)
import GHC.Exts (Any)
import GHC.Generics (Generic)
import Generics.SOP (All2, I, SOP, Top)
import Generics.SOP.GGP (GCode, GDatatypeInfo, GFrom, GTo, gfrom, gto)
import Plutarch.Internal.Term (PType, S, Term)
import Plutarch.Internal.TypeFamily (ToPType2)
import Unsafe.Coerce (unsafeCoerce)
class GFrom a => GFrom' a
instance GFrom a => GFrom' a
class GTo a => GTo' a
instance GTo a => GTo' a
type PGeneric' :: PType -> S -> Constraint
class
( Generic (a s)
, GFrom (a s)
, GTo (a s)
, All2 Top (PCode a)
, All2 Top (GCode (a s))
, GDatatypeInfo (a s)
) =>
PGeneric' a s
instance
( Generic (a s)
, GFrom (a s)
, GTo (a s)
, All2 Top (PCode a)
, All2 Top (GCode (a s))
, GDatatypeInfo (a s)
) =>
PGeneric' a s
type PGeneric :: PType -> Constraint
class (forall s. PGeneric' a s) => PGeneric a
instance (forall s. PGeneric' a s) => PGeneric a
type PCode :: PType -> [[PType]]
type PCode a = ToPType2 (GCode (a Any))
gpfrom :: forall a s. PGeneric a => a s -> SOP (Term s) (PCode a)
gpfrom :: forall (a :: PType) (s :: S).
PGeneric a =>
a s -> SOP @PType (Term s) (PCode a)
gpfrom a s
x = case (Dict (PGeneric' a s)
forall (a :: Constraint). a => Dict a
Dict :: Dict (PGeneric' a s)) of
Dict (PGeneric' a s)
Dict -> SOP @Type I (GCode (a s)) -> SOP @PType (Term s) (PCode a)
forall a b. a -> b
unsafeCoerce (a s -> SOP @Type I (GCode (a s))
forall a. (GFrom a, Generic a) => a -> SOP @Type I (GCode a)
gfrom a s
x :: SOP I (GCode (a s)))
gpto :: forall a s. PGeneric a => SOP (Term s) (PCode a) -> a s
gpto :: forall (a :: PType) (s :: S).
PGeneric a =>
SOP @PType (Term s) (PCode a) -> a s
gpto SOP @PType (Term s) (PCode a)
x = case (Dict (PGeneric' a s)
forall (a :: Constraint). a => Dict a
Dict :: Dict (PGeneric' a s)) of
Dict (PGeneric' a s)
Dict -> SOP @Type I (GCode (a s)) -> a s
forall a. (GTo a, Generic a) => SOP @Type I (GCode a) -> a
gto (SOP @PType (Term s) (PCode a) -> SOP @Type I (GCode (a s))
forall a b. a -> b
unsafeCoerce SOP @PType (Term s) (PCode a)
x :: SOP I (GCode (a s)))