如何从具有特定(参数化)类型的 HList 中提取元素 [英] How to extract an element from an HList with a specific (parameterized) type

查看:37
本文介绍了如何从具有特定(参数化)类型的 HList 中提取元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在链接转换,我想累积每个转换的结果,以便它可以在任何后续步骤中使用,并且所有结果在最后都可用(主要用于调试目的)).有几个步骤,有时我需要添加一个新步骤或更改步骤的输入.

I'm chaining transformations, and I'd like to accumulate the result of each transformation so that it can potentially be used in any subsequent step, and also so that all the results are available at the end (mostly for debugging purposes). There are several steps and from time to time I need to add a new step or change the inputs for a step.

HList 似乎提供了一种方便的方法来以灵活但类型安全的方式收集结果.但我不想让实际步骤复杂化,让它们处理 HList 和伴随的业务.

HList seems to offer a convenient way to collect the results in a flexible but still type-safe way. But I'd rather not complicate the actual steps by making them deal with the HList and the accompanying business.

这是我想编写的组合器的简化版本,但它不起作用.这个想法是,给定一个包含 A、A 的索引和 A -> B 的函数的 HList,mapNth 将提取 A,运行该函数,并将结果放入列表中.生成的扩展列表捕获了新结果的类型,因此可以组合这些 mapN 化步骤中的几个以生成包含每个步骤的结果的列表:

Here's a simplified version of the combinator I'd like to write, which isn't working. The idea is that given an HList containing an A, and the index of A, and a function from A -> B, mapNth will extract the A, run the function, and cons the result onto the list. The resulting extended list captures the type of the new result, so several of these mapNth-ified steps can be composed to produce a list containing the result from each step:

def mapNth[L <: HList, A, B]
    (l: L, index: Nat, f: A => B)
    (implicit at: shapeless.ops.hlist.At[L, index.N]):
    B :: L =
  f(l(index)) :: l

顺便说一下,我还需要 map2Nth 取两个索引和 f: (A, B) =>;C,但我相信问题是一样的.

Incidentally, I'll also need map2Nth taking two indices and f: (A, B) => C, but I believe the issues are the same.

然而,mapNth 不编译,说 l(index) 有类型 at.Out,但是 f> 的参数应该是 A.当然,这是正确的,所以我想我需要的是一种方法来提供证据证明 at.Out 实际上是 A(或者,at.Out <: A).

However, mapNth does not compile, saying l(index) has type at.Out, but f's argument should be A. That's correct, of course, so what I suppose I need is a way to provide evidence that at.Out is in fact A (or, at.Out <: A).

有没有办法表达这种约束?我相信它必须采用隐式的形式,因为当然只有在将 mapNth 应用于特定列表和函数时才能检查约束.

Is there a way to express that constraint? I believe it will have to take the form of an implicit, because of course the constraint can only be checked when mapNth is applied to a particular list and function.

推荐答案

您完全正确需要证据证明 at.OutA,并且您可以提供通过在 at 的类型中包含类型成员的值来证明:

You're exactly right about needing evidence that at.Out is A, and you can provide that evidence by including the value of the type member in at's type:

def mapNth[L <: HList, A, B]
    (l: L, index: Nat, f: A => B)
    (implicit at: shapeless.ops.hlist.At[L, index.N] { type Out = A }):
    B :: L =
  f(l(index)) :: l

Shapeless 中的 At 等类型类的伴随对象也定义了一个 Aux 类型,该类型包括输出类型作为最终类型参数.

The companion objects for type classes like At in Shapeless also define an Aux type that includes the output type as a final type parameter.

def mapNth[L <: HList, A, B]
    (l: L, index: Nat, f: A => B)
    (implicit at: shapeless.ops.hlist.At.Aux[L, index.N, A]):
    B :: L =
  f(l(index)) :: l

这几乎是等价的,但更地道(看起来更好一些).

This is pretty much equivalent but more idiomatic (and it looks a little nicer).

这篇关于如何从具有特定(参数化)类型的 HList 中提取元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆