module Montis.Core.Extensions where import Data.Data ( Typeable, tyConModule, tyConName, tyConPackage, ) import Data.Kind (Constraint, Type) import Text.Printf (printf) import Type.Reflection (someTypeRep, someTypeRepTyCon) -- | A key to key into the Extension maps. data ExtensionKey where ExtensionKey :: {extensionKeyValue :: String} -> ExtensionKey deriving (Eq, Ord, Show) data Extension (c :: Type -> Constraint) where Extension :: (Typeable a, c a) => a -> Extension c class Nil a instance Nil a -- | Produces a string representation of a type used to key into the extensible -- state map. typeRepr :: forall proxy a. (Typeable a) => proxy a -> ExtensionKey typeRepr proxy = ExtensionKey $ tyconToStr $ someTypeRepTyCon (someTypeRep proxy) where tyconToStr tc = printf "%s.%s.%s" (tyConPackage tc) (tyConModule tc) (tyConName tc)