How to convert any type to Symbol using type families?

I want to convert any type to a type level string using some type families.

Of course, I can write something like this:

type family ShowType (t :: Type) :: Symbol where ShowType Int = "Int" ShowType String = "String" ... 

But I wonder if there is any existing mechanism for this? I can do this at runtime using Typeable methods. But how can I automatically convert any type to Symbol ?

+5
source share
1 answer

There is no general solution for all types. But maybe you will find the following interesting.

You can get the name of a type constructor with a Generic instance, although this excludes primitive types such as Int and Float . Below are two ways:

 {-# LANGUAGE AllowAmbiguousTypes#-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeApplications #-} import Data.Proxy import GHC.Generics import GHC.TypeLits -- Solution 1: Defines a type family that extracts the type -- constructor name as a Symbol from a generic Rep. -- Then it can be reified via GHC.TypeLits.symbolVal. type family TyConName (f :: * -> *) :: Symbol where TyConName (M1 D ('MetaData name _mdl _pkg _nt) _f) = name tyConName :: forall as . (Generic a, s ~ TyConName (Rep a), KnownSymbol s) => String tyConName = symbolVal (Proxy @s) -- Solution 2: Uses the GHC.Generics.datatypeName helper -- (value-level string only). tyConName' :: forall adfp . (Generic a, Rep a ~ D1 df, Datatype d) => String tyConName' = datatypeName (from @a undefined) main = do print (tyConName @(Maybe Int)) -- "Maybe" print (tyConName' @(Maybe Int)) -- "Maybe" 
+1
source

Source: https://habr.com/ru/post/1275267/


All Articles