{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}
module Generics.SOP.Type.Metadata
( module Generics.SOP.Type.Metadata
, Associativity(..)
) where
import Data.Kind (Type)
import Data.Proxy (Proxy (..))
import GHC.Generics
( Associativity(..)
, DecidedStrictness(..)
, SourceStrictness(..)
, SourceUnpackedness(..)
)
import GHC.Types
import GHC.TypeLits
import qualified Generics.SOP.Metadata as M
import Generics.SOP.NP
import Generics.SOP.Sing
data DatatypeInfo =
ADT ModuleName DatatypeName [ConstructorInfo] [[StrictnessInfo]]
| Newtype ModuleName DatatypeName ConstructorInfo
data ConstructorInfo =
Constructor ConstructorName
| Infix ConstructorName Associativity Fixity
| Record ConstructorName [FieldInfo]
data StrictnessInfo =
StrictnessInfo SourceUnpackedness SourceStrictness DecidedStrictness
data FieldInfo =
FieldInfo FieldName
type DatatypeName = Symbol
type ModuleName = Symbol
type ConstructorName = Symbol
type FieldName = Symbol
type Fixity = Nat
class DemoteDatatypeInfo (x :: DatatypeInfo) (xss :: [[Type]]) where
demoteDatatypeInfo :: proxy x -> M.DatatypeInfo xss
instance
( KnownSymbol m
, KnownSymbol d
, DemoteConstructorInfos cs xss
, DemoteStrictnessInfoss sss xss
)
=> DemoteDatatypeInfo ('ADT m d cs sss) xss where
demoteDatatypeInfo _ =
M.ADT
(symbolVal (Proxy :: Proxy m))
(symbolVal (Proxy :: Proxy d))
(demoteConstructorInfos (Proxy :: Proxy cs))
(POP (demoteStrictnessInfoss (Proxy :: Proxy sss)))
instance
(KnownSymbol m, KnownSymbol d, DemoteConstructorInfo c '[ x ])
=> DemoteDatatypeInfo ('Newtype m d c) '[ '[ x ] ] where
demoteDatatypeInfo _ =
M.Newtype
(symbolVal (Proxy :: Proxy m))
(symbolVal (Proxy :: Proxy d))
(demoteConstructorInfo (Proxy :: Proxy c))
class DemoteConstructorInfos (cs :: [ConstructorInfo]) (xss :: [[Type]]) where
demoteConstructorInfos :: proxy cs -> NP M.ConstructorInfo xss
instance DemoteConstructorInfos '[] '[] where
demoteConstructorInfos _ = Nil
instance
(DemoteConstructorInfo c xs, DemoteConstructorInfos cs xss)
=> DemoteConstructorInfos (c ': cs) (xs ': xss) where
demoteConstructorInfos _ =
demoteConstructorInfo (Proxy :: Proxy c) :* demoteConstructorInfos (Proxy :: Proxy cs)
class DemoteConstructorInfo (x :: ConstructorInfo) (xs :: [Type]) where
demoteConstructorInfo :: proxy x -> M.ConstructorInfo xs
instance (KnownSymbol s, SListI xs) => DemoteConstructorInfo ('Constructor s) xs where
demoteConstructorInfo _ = M.Constructor (symbolVal (Proxy :: Proxy s))
instance
(KnownSymbol s, DemoteAssociativity a, KnownNat f)
=> DemoteConstructorInfo ('Infix s a f) [y, z] where
demoteConstructorInfo _ =
M.Infix
(symbolVal (Proxy :: Proxy s))
(demoteAssociativity (Proxy :: Proxy a))
(fromInteger (natVal (Proxy :: Proxy f)))
instance (KnownSymbol s, DemoteFieldInfos fs xs) => DemoteConstructorInfo ('Record s fs) xs where
demoteConstructorInfo _ =
M.Record (symbolVal (Proxy :: Proxy s)) (demoteFieldInfos (Proxy :: Proxy fs))
class DemoteStrictnessInfoss (sss :: [[StrictnessInfo]]) (xss :: [[Type]]) where
demoteStrictnessInfoss :: proxy sss -> NP (NP M.StrictnessInfo) xss
instance DemoteStrictnessInfoss '[] '[] where
demoteStrictnessInfoss _ = Nil
instance
(DemoteStrictnessInfos ss xs, DemoteStrictnessInfoss sss xss)
=> DemoteStrictnessInfoss (ss ': sss) (xs ': xss) where
demoteStrictnessInfoss _ =
demoteStrictnessInfos (Proxy :: Proxy ss )
:* demoteStrictnessInfoss (Proxy :: Proxy sss)
class DemoteStrictnessInfos (ss :: [StrictnessInfo]) (xs :: [Type]) where
demoteStrictnessInfos :: proxy ss -> NP M.StrictnessInfo xs
instance DemoteStrictnessInfos '[] '[] where
demoteStrictnessInfos _ = Nil
instance
(DemoteStrictnessInfo s x, DemoteStrictnessInfos ss xs)
=> DemoteStrictnessInfos (s ': ss) (x ': xs) where
demoteStrictnessInfos _ =
demoteStrictnessInfo (Proxy :: Proxy s )
:* demoteStrictnessInfos (Proxy :: Proxy ss)
class DemoteStrictnessInfo (s :: StrictnessInfo) (x :: Type) where
demoteStrictnessInfo :: proxy s -> M.StrictnessInfo x
instance
( DemoteSourceUnpackedness su
, DemoteSourceStrictness ss
, DemoteDecidedStrictness ds
)
=> DemoteStrictnessInfo ('StrictnessInfo su ss ds) x where
demoteStrictnessInfo _ =
M.StrictnessInfo
(demoteSourceUnpackedness (Proxy :: Proxy su))
(demoteSourceStrictness (Proxy :: Proxy ss))
(demoteDecidedStrictness (Proxy :: Proxy ds))
class SListI xs => DemoteFieldInfos (fs :: [FieldInfo]) (xs :: [Type]) where
demoteFieldInfos :: proxy fs -> NP M.FieldInfo xs
instance DemoteFieldInfos '[] '[] where
demoteFieldInfos _ = Nil
instance
(DemoteFieldInfo f x, DemoteFieldInfos fs xs)
=> DemoteFieldInfos (f ': fs) (x ': xs) where
demoteFieldInfos _ = demoteFieldInfo (Proxy :: Proxy f) :* demoteFieldInfos (Proxy :: Proxy fs)
class DemoteFieldInfo (x :: FieldInfo) (a :: Type) where
demoteFieldInfo :: proxy x -> M.FieldInfo a
instance KnownSymbol s => DemoteFieldInfo ('FieldInfo s) a where
demoteFieldInfo _ = M.FieldInfo (symbolVal (Proxy :: Proxy s))
class DemoteAssociativity (a :: Associativity) where
demoteAssociativity :: proxy a -> M.Associativity
instance DemoteAssociativity 'LeftAssociative where
demoteAssociativity _ = M.LeftAssociative
instance DemoteAssociativity 'RightAssociative where
demoteAssociativity _ = M.RightAssociative
instance DemoteAssociativity 'NotAssociative where
demoteAssociativity _ = M.NotAssociative
class DemoteSourceUnpackedness (a :: SourceUnpackedness) where
demoteSourceUnpackedness :: proxy a -> M.SourceUnpackedness
instance DemoteSourceUnpackedness 'NoSourceUnpackedness where
demoteSourceUnpackedness _ = M.NoSourceUnpackedness
instance DemoteSourceUnpackedness 'SourceNoUnpack where
demoteSourceUnpackedness _ = M.SourceNoUnpack
instance DemoteSourceUnpackedness 'SourceUnpack where
demoteSourceUnpackedness _ = M.SourceUnpack
class DemoteSourceStrictness (a :: SourceStrictness) where
demoteSourceStrictness :: proxy a -> M.SourceStrictness
instance DemoteSourceStrictness 'NoSourceStrictness where
demoteSourceStrictness _ = M.NoSourceStrictness
instance DemoteSourceStrictness 'SourceLazy where
demoteSourceStrictness _ = M.SourceLazy
instance DemoteSourceStrictness 'SourceStrict where
demoteSourceStrictness _ = M.SourceStrict
class DemoteDecidedStrictness (a :: DecidedStrictness) where
demoteDecidedStrictness :: proxy a -> M.DecidedStrictness
instance DemoteDecidedStrictness 'DecidedLazy where
demoteDecidedStrictness _ = M.DecidedLazy
instance DemoteDecidedStrictness 'DecidedStrict where
demoteDecidedStrictness _ = M.DecidedStrict
instance DemoteDecidedStrictness 'DecidedUnpack where
demoteDecidedStrictness _ = M.DecidedUnpack