繁体   English   中英

Scala编译时递归?

[英]Scala compile-time recursion?

作为对我昨天发布的有关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 ++示例的操作?

约书亚·苏瑞斯(Joshua Suereth)的新书《深度的斯卡拉》(Scala in Depth)中有一个很好的例子。 第7.4节是“使用类型系统进行有条件的执行”,它介绍了HList构造以及如何使用编译时递归来实现可以访问HList特定元素的IndexedView类型。 这用于实现AtIndex类型,该类型用于在编译时检索单个值。

是的你可以。 在最普通的情况下,请参阅我的博客文章有关如何在Scala的类型系统中实现SKI演算 我还写了关于循环展开和条件编译的更具体情况。 最后,这个小难题解决方案显示了一种实现编译时间递归的方法的本质。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM