我该如何推导函数
getField :: (Generic a, HasDatatypeInfo a) => Proxy (name :: Symbol) -> a -> b
使用类型级别字符串(Symbol
)从任意记录中投影字段,使用generics-sop
库?
这类似于Retrieving record function in generic SOP,但我有以下问题:
- OP没有解释如何走完最后一英里才能得到我想要的签名。
- OP定义了复杂的特殊用途的helper类型,我非常希望避免这种类型
- 给定的解决方案只在运行时出错,但编译时匹配应该是可能的,因为类型级别的
DataTypeInfo
是通过DatatypeInfoOf
类型家族提供的(拥有它很好,但不是必需的)。
lens-sop
包似乎也做了类似的事情,但我不知道如何让它为我工作。
我也更喜欢使用IsProductType
类型类的解决方案。
2条答案
按热度按时间umuewwlo1#
我知道这是一个混乱的答案,并不是你真正想要的,但这是我现在能做的最好的。注意,这对乘积类型和求和类型都有效,其中 * 所有 * 构造函数都有指定的字段名。
我认为,通过将名称查找与产品处理的其余部分分离开来,这可能会有所简化。即:使用datatypeinfo来计算字段编号(作为一元自然数),然后使用该编号来挖掘代码。不幸的是,
generics-sop
似乎没有真正出色的工具来处理列表压缩,所以我最终做了很多“手工”工作。示例
lstz6jyr2#
自www.example.com版本起0.1.1.0,
records-sop
提供此功能:它需要作为类型应用程序而不是代理提供的字段名,如下所示:
这提供了编译时提取,尽管它仍然需要一些转换,以适应我的项目中操作标准
generics-sop
元数据的现有代码。这只对单构造函数类型有效。@dfeuer的答案也支持sum类型。
感谢@kosmikus,
generics-sop
的合著者和records-sop
的作者,为回答这个问题而实现了这一点!