La clase de tipos Read no lo hace declarar read
directamente; en su lugar, define readsPrec
, que admite precedencia (esto es importante cuando read
es un valor de un tipo de datos complejo que involucra elementos de otros tipos). La definición se obtiene cuando se utiliza deriving (Read)
se ve más o menos así
instance (Read a) => Read (Tree a) where
readsPrec d r = readParen (d > app_prec)
(\r -> [(Leaf m,t) |
("Leaf",s) <- lex r,
(m,t) <- readsPrec (app_prec+1) s]) r
++ readParen (d > up_prec)
(\r -> [(u:^:v,w) |
(u,s) <- readsPrec (up_prec+1) r,
(":^:",t) <- lex s,
(v,w) <- readsPrec (up_prec+1) t]) r
where app_prec = 10
up_prec = 5
(esto, obviamente, para un tipo de datos Tree
, pero se aplican reglas similares para otros TDAs definidos por el usuario). (Además, lo anterior es una pequeña mentira: GHC realmente utiliza una implementación diferente, pero lo anterior es el tipo de cosas que debe hacer a menos que esté dispuesto a excavar dentro de GHC.)
read
se define en términos de readsPrec
y (el otro método en Read
, que está predeterminado para todos los tipos excepto Char
donde se usa para leer [Char]
como una cadena en lugar de como una lista de Char
).
Si la derivación estándar no es suficiente, para un tipo como el suyo que es simplemente un depósito de Int
s puede ignorar el parámetro de precedencia.
BTW, Read
y Show
son bastante lentos; Es posible que desee considerar otras formas de hacer E/S con sus datos.
¿Tiene alguna sugerencia de alternativas para leer y mostrar? – user381261