使用`generics-sop`推导投影函数

Ari*_*ham 7 haskell metaprogramming ghc type-level-computation ghc-generics

我将如何推导函数

getField :: (Generic a, HasDatatypeInfo a) => Proxy (name :: Symbol) -> a -> b
Run Code Online (Sandbox Code Playgroud)

使用类型级字符串 ( Symbol),使用generics-sop库从任意记录中投影字段?

这类似于在通用 SOP 中检索记录功能,但我有以下问题:

  • OP 没有解释如何走最后一英里来获得我想要的签名。
  • OP 定义了复杂的特殊用途助手类型,我很想避免这些类型
  • 给定的解决方案仅在运行时出错,但编译时匹配应该是可能的,因为类型级别DataTypeInfo是通过DatatypeInfoOf类型系列提供的(很好,但不是必需的)。

lens-sop软件包似乎也做了类似的事情,但我不知道如何让它对我有用。

我也更喜欢使用IsProductType类型类的解决方案。

Ari*_*ham 1

从0.1.1.0版本开始,records-sop提供了这个功能

getField :: forall s a b ra. (IsRecord a ra, IsElemOf s b ra) => a -> b
Run Code Online (Sandbox Code Playgroud)

它需要作为类型应用程序而不是代理提供的字段名称,如下所示:

data Foo = Foo { bar :: Int }

getField @"bar" (Foo 42) === 42
Run Code Online (Sandbox Code Playgroud)

这提供了编译时提取,尽管它仍然需要一些转换以适应我的项目中操作标准generics-sop元数据的现有代码。

这只适用于单构造函数类型。@dfeuer 的答案也支持 sum 类型。

感谢 @kosmikus, 的合著者generics-sop和作者records-sop,针对这个问题实现了这一点!