haskell dynamic typeclass

haskell - Combinar clases Data.Dynamic y type



typeclass (1)

Dada una variable de tipo Dynamic , ¿es posible aprovechar las clases de tipos de la variable interna sin condicionar el tipo exacto? Por ejemplo, digamos que quiero escribir una función prettyShow . Si el tipo interno es una instancia de Show , entonces deberíamos usar esa instancia; de lo contrario, deberíamos usar la instancia de la clase Dynamic . En el código, esto podría verse así:

prettyShow :: Dynamic -> String prettyShow x = case fromDynamic x :: (forall a. Show a => Maybe a) of Nothing -> show x Just y -> show y

Editar: dado que parece que esto no se puede hacer directamente, ¿cuál es una buena solución que se puede hacer?


Esto se puede hacer usando la implementación de Dynamic en la biblioteca open-typerep (si acepta usar programación genérica y muchas extensiones GHC).

{-# LANGUAGE TypeOperators #-} import Data.TypeRep type Types = BoolType :+: IntType :+: ListType x, y :: Dynamic Types x = toDyn [False,True] y = toDyn [1, 2 :: Int] test1 = show x test2 = show y

La definición de show es simple, y puede usar la biblioteca para definir otras funciones sobre valores dinámicos.

En el ejemplo anterior utilicé un tipo de universo de tipo cerrado. Pero al usar trucos a la Carta de tipos de datos también puede definir funciones para universos abiertos. Por ejemplo, show está abierto.

Actuación

Un punto de referencia simple muestra que esta Dynamic es 2-3 veces más lenta que Data.Dynamic en la base para el universo de tipo pequeño utilizado anteriormente. Aumentar el universo a 30 constructores de tipo lo hace un poco más de 10 veces más lento.

Derivado automático para nuevos tipos

open-typerep admite la creación de universos a partir de un pequeño número de tipos de representación predefinidos. En principio, debería ser posible utilizar TemplateHaskell para autoderivar representaciones para nuevos tipos, pero será difícil generar las instancias adecuadas para Witness y PWitness ya que dependen de qué otras instancias están disponibles. (El Witness se usa, por ejemplo, en la instancia Show para Dynamic ).