2011-03-19 18 views
5

Como resultado de algunas respuestas útiles a una pregunta que publiqué ayer sobre tuplas en Scala, he estado buscando en Scala HLists. Me gustaría volver a hash un ejemplo de C++ a partir de esa pregunta para preguntar a otro:¿Recursión en tiempo de compilación Scala?

En C++ se puede implementar la recursión en tiempo de compilación terminada mediante especialización de plantilla. A menudo he hecho esto operando en tuplas boost que, como Scala/Haskell HLists se construyen componiendo el tipo genérico 'contras' varias veces, una para cada tipo relevante y terminando con null_type. Así que esto:

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

se implementa bajo el capó:

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

Podemos entonces escribir un par de funciones que recursivo en tiempo de compilación sobre esta estructura, que termina cuando el segundo, más especializado la función coincide con el tipo de contras final. Un simple ejemplo, el recuento se muestra a continuación el número de elementos:

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; 
} 

Fundamentalmente este patrón se utiliza a menudo en circunstancias en las que quieres hacer algo diferente para cada uno de los diferentes tipos de elementos tupla (no ilustrados en mi ejemplo) : en C++ la recursión en tiempo de compilación es esencial ya que una vez que se ejecuta el código, la información del tipo se pierde para todos los fines útiles.

Mi pregunta es, ¿es posible algo similar con una Scala HList, p.

val example = 1 :: 2.0 :: "Hello" :: "World" :: HNil 

Soy consciente de que Scala, que se ejecuta en la JVM, tiene la reflexión - y por lo que presumiblemente esto podría implementarse utilizando la recursividad de tiempo de ejecución de una función utilizando los manifiestos y la coincidencia de patrones. Pero me interesa saber si es posible hacer algo similar al ejemplo de C++, utilizando la recursión en tiempo de compilación.

+0

No estoy seguro de lo que se pregunta aquí. Pero dada la tendencia general de sus preguntas, me pregunto si ha consultado los blogs sobre los números de la Iglesia en el sistema de tipo Scala. ¿O cálculo de SKI en el sistema de tipo Scala? –

+0

Gracias Daniel. Sus diversas sugerencias están demostrando ser muy útiles. También he estado hurgando en la fuente de ScalaQuery en busca de inspiración. –

+0

¿Podría agregar un ejemplo del tipo de caso más interesante "en el que desea hacer algo diferente para cada uno de los diversos tipos de elementos de tupla"? –

Respuesta

2

hay un excelente ejemplo de esto en el nuevo libro Scala de profundidad por Joshua Suereth. La Sección 7.4 es "Ejecución condicional usando el sistema de tipo" e introduce el constructo HList y cómo puede usar la recursión en tiempo de compilación para implementar un tipo de IndexedView que puede acceder a un elemento específico de HList. Esto se usa para implementar un tipo AtIndex que se usa para recuperar valores individuales en tiempo de compilación.

0

Sí, puedes. Vea la publicación de mi blog sobre cómo implementar el SKI calculus en el sistema de tipos de Scala para el caso más general. También escribí sobre el caso más específico de loop unrolling and conditional compilation. Finalmente, el solution a este pequeño puzzle muestra la esencia de cómo se puede implementar la recursión en tiempo de compilación.

Cuestiones relacionadas