2011-03-19 77 views
5

由於我昨天發佈了關於Scala中元組的問題的一些有用答案,我一直在尋找Scala HLists。我想重新散列一個C++的例子來問這個問題:Scala編譯時遞歸?

在C++中,可以使用模板專門化實現編譯時遞歸。我經常對boost元組進行操作,這些元組像Scala/Haskell HList一樣,通過多次構造泛型'cons'來構造,每個相關類型一次,並以null_type結尾。因此,這:

boost::tuple<int, std::string, float> 

在引擎蓋下實施:

cons<int, cons<std::string, cons<float, null_type> > > 

然後,我們可以寫一個對函數在該結構上遞歸在編譯時,終止時的第二,更專門函數匹配最終的缺點類型。一個簡單的例子,數如下所示的元素個數:

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上,有反思 - 所以想必這可以使用運行時間遞歸使用清單和模式匹配功能來實現。但我有興趣知道是否可以使用編譯時遞歸來做類似於C++示例的事情?

+0

我不確定在這裏問什麼。但考慮到你的問題的總體趨勢,我想知道你是否看過有關Scala類型系統中Church數字的博客?或Scala類型系統中的SKI演算? – 2011-03-20 23:27:53

+0

謝謝丹尼爾。你的各種建議被證明是非常有用的。我也一直在ScalaQuery來源中尋找靈感。 – 2011-03-21 11:20:22

+0

你可以添加一個更有趣的「你想爲每個元組元素類型做不同的事情」的例子嗎? – 2012-01-03 00:04:13

回答

2

還有就是在這本新書中的Scala深度由Joshua Suereth一個很好的例子。 7.4節是「使用類型系統進行條件執行」,它介紹了HList構造以及如何使用編譯時遞歸來實現可以訪問HList特定元素的IndexedView類型。這用於實現一個AtIndex類型,用於在編譯時檢索單個值。