use*_*261 21 haskell typeclass
我有一个自定义数据类型Foo = Foo{ a :: Int, b :: Int},我正在尝试使Foo成为自定义读取实例.我已经有了一个功能bar :: String -> Foo,我尝试这样做:
instance Read (Foo a b) where
read s = bar s
Run Code Online (Sandbox Code Playgroud)
但是当我将文件加载到GHCi中进行测试时,我收到以下错误: Fraction.hs:11:1: read' is not a (visible) method of class Read'
有人能告诉我问题是什么以及我如何实际实例化这种类型?
gee*_*aur 18
在阅读类型类没有声明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
Run Code Online (Sandbox Code Playgroud)
(这显然对于Tree数据类型,但类似的规则适用于其他用户定义的ADT).(另外,上面是一个小小的谎言:GHC实际上使用了不同的实现,但除非你愿意在GHC里面挖掘,否则上面是你应该做的事情.)
read是根据readsPrec和定义的readList(另一种方法Read,对于每种类型都是默认的,除非Char它用来读[Char]作字符串而不是列表Char).
如果标准派生是不够的,对于像你这样的类型只是一个桶的Ints,你可以忽略优先级参数.
BTW,Read而且Show相当缓慢; 您可能需要考虑使用其他方法对数据执行I/O操作.