由于对我昨天发布的关于 Scala 元组的问题的一些有用答案,我一直在研究 Scala HLists。我想从那个问题重新散列一个 C++ 示例来问另一个问题:
在 C++ 中,可以实现使用模板特化终止的编译时递归。我经常在 boost 元组上执行此操作,就像 Scala/Haskell HLists 一样,它是通过多次组合通用“cons”类型来构造的,每个相关类型一次并以 null_type 终止。所以这:
boost::tuple<int, std::string, float>
在引擎盖下实现为:
cons<int, cons<std::string, cons<float, null_type> > >
然后我们可以编写一对函数,在编译时在这个结构上递归,当第二个更专业的函数匹配最终的 cons 类型时终止。一个简单的例子,计算元素的数量如下所示:
template<typename T1, typename T2>
void countTupleElements( boost::tuples::cons<T1, T2>& tupleRec, int index, const std::vector<std::string>& vals )
{
return 1 + countTupleElements( tupleRec.tail );
}
template<typename T>
void countTupleElements( boost::tuples::cons<T, boost::tuples::null_type>& tupleRec, int index, const std::vector<std::string>& vals )
{
return 1;
}
至关重要的是,这种模式通常用于您想要对每种元组元素类型(在我的示例中未说明)执行不同操作的情况:在 C++ 中,编译时递归是必不可少的,因为一旦代码运行,类型信息就会丢失出于所有有用的目的。
我的问题是,Scala HList 是否有类似的可能,例如
val example = 1 :: 2.0 :: "Hello" :: "World" :: HNil
我知道在 JVM 上运行的 Scala 具有反射功能 - 因此大概可以使用运行时递归和使用清单和模式匹配的函数来实现。但我很想知道是否可以使用编译时递归来做类似于 C++ 示例的事情?