作为昨天我发布的有关Scala元组的问题的一些有用答案的结果,我一直在研究Scala HLists。我想重新讨论一个来自该问题的C++示例以提出另一个问题:
在C++中,可以使用模板特化实现编译时递归终止。我经常在boost元组上执行此操作,就像Scala/Haskell HLists一样,通过多次组合通用的“cons”类型构建,每次为每个相关类型构建一次,最后以null_type终止。所以这个:
我们可以编写一对函数,对这个结构进行编译时递归,当第二个更专业的函数匹配最后一个cons类型时终止。下面是一个简单的例子,计算元素数量:
在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++示例一样使用编译时递归来实现类似的功能?