Read 类型类不直接声明read;相反,它定义了支持优先级的readsPrec(这在read处理涉及其他类型元素的复杂数据类型的值时很重要)。使用deriving (Read)时得到的定义大致如下
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
(这显然适用于 Tree 数据类型,但类似的规则适用于其他用户定义的 ADT)。 (另外,上面是一个小小的谎言:GHC 实际上使用了不同的实现,但上面是你应该做的事情,除非你愿意在 GHC 内部挖掘。)
read 是根据readsPrec 和readList 定义的(Read 中的另一种方法,除了Char 用于将[Char] 读取为字符串而不是作为Char 的列表)。
如果标准推导不够,对于像您这样的类型,它只是 Ints 的桶,您可以忽略优先级参数。
顺便说一句,Read 和 Show 相当慢;您可能需要考虑使用其他方式对您的数据进行 I/O。