gpt4 book ai didi

Haskell 内省(introspection)记录的字段名称和类型

转载 作者:行者123 更新时间:2023-12-02 15:19:59 25 4
gpt4 key购买 nike

基于 recent exchange ,我已经确信使用 Template Haskell 生成一些代码以确保编译时类型安全。

我需要内省(introspection)记录字段名称和类型。我明白我可以 get field names通过使用constrFields . toConstr :: Data a => a -> [String] 。但我需要的不仅仅是字段名称,我还需要知道它们的类型。例如,我需要知道 Bool 类型的字段名称.

如何构造函数 f :: a -> [(String, xx)]哪里a是记录,String是字段名称,xx字段类型是什么?

最佳答案

该类型以及其他所有内容都应该在 reify 提供的 Info 值中可用。具体来说,您应该获得一个 TyConI,其中包含 a Dec value ,从中可以得到 Con values specifying the constructors 的列表。然后,记录类型应使用 RecC,这将为您提供字段列表 described by a tuple包含字段名称、字段是否严格以及 the type .

您从那里去哪里取决于您想用这一切做什么。

<小时/>

编辑:为了实际演示上述内容,这里有一个非常糟糕的快速且肮脏的函数,用于查找记录字段:

import Language.Haskell.TH

test :: Name -> Q Exp
test n = do rfs <- fmap getRecordFields $ reify n
litE . stringL $ show rfs

getRecordFields :: Info -> [(String, [(String, String)])]
getRecordFields (TyConI (DataD _ _ _ cons _)) = concatMap getRF' cons
getRecordFields _ = []

getRF' :: Con -> [(String, [(String, String)])]
getRF' (RecC name fields) = [(nameBase name, map getFieldInfo fields)]
getRF' _ = []

getFieldInfo :: (Name, Strict, Type) -> (String, String)
getFieldInfo (name, _, ty) = (nameBase name, show ty)

将其导入到另一个模块中,我们可以像这样使用它:

data Foo = Foo { foo1 :: Int, foo2 :: Bool }

foo = $(test ''Foo)

在 GHCi 中加载该值,foo 中的值为 [("Foo",[("foo1","ConT GHC.Types.Int"),("foo2", “ConT GHC.Types.Bool”)])]

这能给你一个大概的想法吗?

关于Haskell 内省(introspection)记录的字段名称和类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8684984/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com