Scala рекурсия во время компиляции? - PullRequest
5 голосов
/ 20 марта 2011

В результате некоторых полезных ответов на вопрос, который я вчера опубликовал о кортежах в Scala, я просматривал списки Scala HLists.Я хотел бы повторно хэшировать пример C ++ из этого вопроса, чтобы задать другой:

В C ++ можно реализовать рекурсию во время компиляции, завершенную с использованием специализации шаблона.Я часто делал это, работая с буст-кортежами, которые, как и Scala / Haskell HLists, строятся путем составления универсального типа «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

Мне известно, что Scala, работающая на JVM, имеет отражение - и, вероятно, это можно реализовать с помощью рекурсии во время выполнения с функцией, использующей манифесты и сопоставление с образцом.Но мне интересно знать, возможно ли сделать что-то похожее на пример C ++, используя рекурсию во время компиляции?

Ответы [ 3 ]

4 голосов
/ 22 марта 2011

Да, можно реализовать рекурсию времени компиляции, используя неявные параметры. См:

http://apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/
http://jnordenberg.blogspot.com/2008/08/hlist-in-scala.html

2 голосов
/ 13 июня 2012

Прекрасный пример тому есть в новой книге Джошуа Суерета «Глубина в глубине». Раздел 7.4 - «Условное выполнение с использованием системы типов», и в нем представлены конструкция HList и способы использования рекурсии во время компиляции для реализации типа IndexedView, который может обращаться к конкретному элементу HList. Это используется для реализации типа AtIndex, который используется для получения отдельных значений во время компиляции.

0 голосов
/ 13 июня 2012

Да, вы можете. См. Мой пост в блоге о том, как реализовать SKI исчисление в системе типов Scala для наиболее общего случая. Я также написал о более конкретном случае развёртывания цикла и условной компиляции . Наконец, решение этой маленькой головоломки показывает суть одного способа реализации рекурсии во время компиляции.

...