2012-04-28 10 views
5

Tengo curiosidad sobre las objeciones a implicit parameters discutidas en el artículo Functional Pearl: Implicit Configurations por Kiselyov y Shan.¿Los parámetros implícitos son una dificultad para incluir en GHC?

No es correcto el código en línea (β-reduce) en presencia de parámetros implícitos.

¿Realmente? Esperaría que GHC se alinee en el mismo alcance que el parámetro implícito pasado, ¿no?

Creo que entiendo su objeción de que:

El comportamiento de un término puede cambiar si se añade su firma, se quita o se cambia.

documentación del usuario de GHC explica que los programadores deben tener cuidado en torno polymorphic recursion y monomorphism restriction. ¿Es esto de alguna manera lo que quieren decir con un problema para inline?

Supongo que este ejemplo de recursión polimórfica cubre lo que quieren decir con "generalización sobre parámetros implícitos" también? ¿Algo más?

¿Es la clase de tipo ReifiesStorable de Data.Reflection realmente una solución sensata a estas dificultades? Al parecer, deserializa toda la estructura de datos implícita cada vez que se accede, lo que puede ser desastroso para el rendimiento. Podríamos, por ejemplo, querer que nuestra información implícita sea una tabla de Cayley o una tabla de caracteres que ocupe un registro de RAM y debe tener acceso durante millones de operaciones algebraicas.

¿Existe quizás alguna solución mejor que emplee parámetros implícitos, u otra técnica que el compilador pueda optimizar fácilmente, detrás de escena, garantizando aún más a través del sistema de tipo utilizando subprocesos de estado o lo que sea?

Respuesta

7

Sí, el ejemplo del manual de GHC muestra cómo agregar una firma de tipo puede cambiar la semántica del código con parámetros implícitos, y creo que esto es lo que significan al dividir en línea; Alinear una aplicación de len_acc1 frente a una aplicación de len_acc2 produce el mismo código, a pesar de que los dos tienen una semántica diferente.

En cuanto a la generalización de los parámetros implícitos, significa que no se puede escribir una función que pueda operar en múltiples parámetros implícitos; no hay ningún mecanismo para abstraerse sobre ellos, ya que el parámetro implícito que usa una función está fijado por su tipo. Con la reflexión, puede escribir fácilmente una función como doSomethingWith :: (Reifies s a, Num a) => Proxy s -> a, que puede operar sobre cualquier tipo que reifica un valor numérico.

En cuanto a ReifiesStorable, está buscando una versión anterior del paquete de reflexión; el latest version tiene una implementación muy eficiente en la cual reify solo cuesta tanto como una llamada a función. Tenga en cuenta que, incluso con la implementación anterior, generalmente no usaría la clase ReifiesStorable directamente, sino Reifies, que usa ReifiesStorable para reificar un StablePtr, de modo que solo se copian unos pocos bytes, no el objeto completo. (Esto es lo que hace la implementación original en el documento). Ambas implementaciones son definitivamente lo suficientemente rápidas para el uso práctico, con la implementación antigua y "lenta" que tarda unos 100 ms en reificar y reflejar 100000 valores, y la nueva implementación en 10 Sra.

(Divulgación completa: trabajé en la nueva implementación.)

La implementación rápida depende de los detalles de implementación de Haskell. La implementación más antigua y más lenta se usa automáticamente para las implementaciones de Haskell que aún no se han probado con la implementación rápida; hasta el momento, se ha demostrado que GHC y Hugs funcionan con la implementación rápida. Puede solicitar la implementación lenta con -fslow, pero es poco probable que deje de funcionar a menos que GHC revise significativamente su implementación de clases de tipos. (Incluso si lo hace, solo tendrías que volver a compilar los paquetes que usan el reflejo para que funcione de nuevo.)

+0

Ahh, dulce, entonces 'Data.Reflection' ahora es magia negra. :) ¿Hay algún código o artículos que recomiendas leer? 'Data.Reflection' ya tiene más sentido ahora que veo el directorio de ejemplos. Debo leer otra cosa en 'Data.Tagged' y' Data.Proxy' aunque. –

Cuestiones relacionadas