2012-01-31 12 views
7

Supongamos que tenemos el siguiente:La implementación de la clase Mostrar

 
data Foo x 
from_list :: [x] -> Foo x 
to_list :: Foo x -> [x] 

Supongamos que quiero declarar instance (Show x) => Show (Foo x) tal que muestra un valor produce la llamada adecuada a from_list. ¿Cómo exactamente hago eso? En particular, ¿cómo implemento showsPrec para que se cumplan las reglas de precedencia trixy? (Es decir, poner la expresión entre corchetes si y sólo si es necesario.)

+0

Al no ver constructores definidos, no está claro qué lista desea procesar con 'from_list' al mostrar su' Foo x'. ¿Cómo se relacionaría con los campos de Foo? –

+0

No necesita definirlo con 'showsPrec'. Una instanciación completa mínima de 'Show' es simplemente' show', y 'showsPrec' se definirá en términos de ello. El mismo mecanismo permite definir solo uno de '(==)' y '(/ =)' para 'Eq' y obtener el otro de forma gratuita. – danr

+0

Voy por algo como show foo = "Foo (fromList " ++ show (to_list foo) ++ ")", pero usando showsPrec y con el manejo de precedencia correcto. – MathematicalOrchid

Respuesta

18

Lo que se quiere aquí es básicamente el mismo que what Data.Set does, por lo que sólo podemos modificar que un poco de:

instance Show x => Show (Foo x) where 
    showsPrec p xs = showParen (p > 10) $ 
    showString "from_list " . shows (to_list xs) 

En otra palabras, usamos la instancia Show para listas, anteponiendo "from_list " a eso, y usamos showParen para agregar corchetes a su alrededor si el contexto circundante tiene una precedencia mayor que la aplicación de función (que tiene precedencia 10).

> show (from_list [1, 2, 3]) 
"from_list [1,2,3]" 
> show (Just $ from_list [1, 2, 3]) 
"Just (from_list [1,2,3])" 
+0

sucinto y al grano. Gracias. – MathematicalOrchid

+1

En el segundo ejemplo: 'show (Just $ from_list [1, 2, 3])' ¿muestra parantheses porque 'p' evalúa' 11'? ¿O qué exactamente será 'p'? ¿Y qué está configurando la 'p'? – CMCDragonkai

Cuestiones relacionadas