在模板haskell中执行类型相等 [英] Performing type equality in template haskell
问题描述
在模板Haskell
中有一个函数,它提取记录构造函数总和的类型信息,如下所示:
listFields :: Name - > Q([[String,Name,Type]]])
listFields name = do
TyConI(DataD _ _ _ cons _)< - reify name
let showClause(RecC conName fields )=(map(\(x,_,t) - >(nameBase $ x,x,t))fields)
return $ map showClause cons
如果给定字段的类型,那么如何将该类型的等式与特定的类型比如 这个问题的原因是给定记录构造函数,我们想要转换每个字段为 在另一个答案中,这里有一些可以让你在没有任何重叠实例的情况下编写ToText。它使用我最喜欢的技巧 - 将封闭类型族与datakinds混合在一起,作为具有典型类型类的选择机制(注意:即使使用函数依赖关系,更少重叠实例)来合成实际代码: 名字可能会使用一些工作,并且将参数翻到 I have a function in Given the type in there for a field, how do you compare equality of that type with a particular type like The reason for this question is that given record constructor, we want to convert each field to As a follow-on to the other answer, here's something that lets you write ToText without any overlapping instances. It uses my new favorite trick -- mixing closed type families over datakinds as a "choice" mechanism with typical type classes (note: not even using functional dependencies, much less overlapping instances) to synthesize the actual code: The names could probably use some work, and it might be nice to flip the arguments to 这篇关于在模板haskell中执行类型相等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! GHC.Base.String
或 Data.Text.Internal.Text
?我在 TH
文档中看到 TypeQ
。它构建了类型表达式。但是,我找不到任何关于如何构建特定类型的文档,例如 String 或
Text
或 Int
,以便我可以使用它进行等式比较?将欣赏指针如何做到这一点,特别是如何获得特定类型的AST。
Text
。但是, show 和
,不要调用 pack
对于字符串
和 Text
类型。因此,如果类型为 Text
(不转换)或 String
(仅调用<$ c),则需要生成不同的拼接$ c> pack show
)或别的东西(调用 pack。show
假设显示
实例存在)。
{ - #LANGUAGE TypeFamilies,DataKinds,MultiParamTypeClasses,FlexibleInstances,ScopedTypeVariables,FlexibleContexts# - }
导入Data.List
import Data.Text(unpack,pack,Text)
import Data.Proxy
data ToTextMethod = TTMChar | TTMString | TTMText | TTMShow
type family ToTextHow a where
ToTextHow Char = TTMChar
ToTextHow String = TTMString
ToTextHow Text = TTMText
ToTextHow a = TTMShow
class ToTextC ab其中
toTextC :: a - > b - >文本
实例显示a => ToTextC a(Proxy TTMShow)其中
toTextC a _ = pack(显示a)
实例ToTextC Char(代理TTMChar)其中
toTextC c _ = pack [c]
实例ToTextC字符串(代理TTMString)其中
toTextC s _ =包s
实例ToTextC文本(代理TTMText)其中
toTextC t _ = t
toText :: forall a。 (Show a,ToTextC a(Proxy(ToTextHow a)))=> a - > Text
toText x = toTextC x(Proxy :: Proxy(ToTextHow a))
toTextC
可能会很好,但是这一切在ghc 7.8.3中都可以使用。Template Haskell
that extracts the type information for sum of record constructors as below:listFields :: Name -> Q ([[(String,Name,Type)]])
listFields name = do
TyConI (DataD _ _ _ cons _) <- reify name
let showClause (RecC conName fields) = (map (\(x,_,t) -> (nameBase $ x,x,t)) fields)
return $ map showClause cons
GHC.Base.String
or Data.Text.Internal.Text
? I see TypeQ
in TH
documentation. It builds type expression. However, I can't find any documentation on how to build a particular type like String
or Text
or Int
so that I can use it for equality comparison? Will appreciate pointers on how to do this, especially how to get the AST for a particular type.Text
. However, show
and pack
should be called differently for String
and Text
types. So, need to generate different splices if the type is Text
(no conversion) or String
(only call pack
, don't call show
) or something else (call pack . show
assuming Show
instance exists).{-# LANGUAGE TypeFamilies, DataKinds, MultiParamTypeClasses, FlexibleInstances, ScopedTypeVariables, FlexibleContexts #-}
import Data.List
import Data.Text (unpack, pack, Text)
import Data.Proxy
data ToTextMethod = TTMChar | TTMString | TTMText | TTMShow
type family ToTextHow a where
ToTextHow Char = TTMChar
ToTextHow String = TTMString
ToTextHow Text = TTMText
ToTextHow a = TTMShow
class ToTextC a b where
toTextC :: a -> b -> Text
instance Show a => ToTextC a (Proxy TTMShow) where
toTextC a _ = pack (show a)
instance ToTextC Char (Proxy TTMChar) where
toTextC c _ = pack [c]
instance ToTextC String (Proxy TTMString) where
toTextC s _ = pack s
instance ToTextC Text (Proxy TTMText) where
toTextC t _ = t
toText :: forall a. (Show a, ToTextC a (Proxy (ToTextHow a))) => a -> Text
toText x = toTextC x (Proxy :: Proxy (ToTextHow a))
toTextC
, but this all works even in ghc 7.8.3.