tipos - multiplicar haskell
Creación de instancia de clase de tipo de lectura en Haskell para tipo de datos personalizado (2)
Tengo un tipo de datos personalizado Foo = Foo{ a :: Int, b :: Int}
y estoy tratando de hacer de Foo una instancia personalizada de lectura. Ya tengo una bar :: String -> Foo
funciones bar :: String -> Foo
y traté de hacer esto:
instance Read (Foo a b) where
read s = bar s
pero recibo el siguiente error cuando cargo mi archivo en GHCi para probarlo: Fraction.hs:11:1: read'' is not a (visible) method of class Read''
¿Podría alguien decirme cuál es el problema y cómo puedo instanciar realmente este tipo?
Esto se debe a que el método de clase que probablemente querría implementar es readsPrec . Consulte aquí para obtener información completa sobre Leer typeclass: http://zvon.org/other/haskell/Outputprelude/Read_c.html
Por cierto, deberías poder usar la derivación automática y el compilador creará una instancia de esos métodos de lectura, por ejemplo:
data Foo = Foo Int Int
deriving (Read, Show)
La clase de tipos Read no declara read
directamente; en su lugar, define readsPrec
, que admite la prioridad (esto es importante cuando se read
un valor de un tipo de datos complejo que involucra elementos de otros tipos). La definición que se obtiene al usar deriving (Read)
parece aproximadamente a
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 de Tree
, pero se aplican reglas similares para otros ADT definidos por el usuario). (Además, lo anterior es una ligera mentira: GHC en realidad usa una implementación diferente, pero lo anterior es el tipo de cosas que debe hacer a menos que esté dispuesto a indagar dentro de GHC).
read
se define en términos de readsPrec
y readList
(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 grupo de Int
s, puede ignorar el parámetro de precedencia.
Por cierto, Read
y Show
son bastante lentos; Es posible que desee considerar otras formas de hacer E / S con sus datos.