在Haskell中为自定义数据类型创建Read type类的实例 [英] Creating instance of Read type class in Haskell for custom data type
问题描述
我有一个自定义的数据类型 Foo = Foo {a :: Int,b :: Int}
,我试图让Foo成为一个自定义的read实例。我已经有一个函数 bar :: String - > Foo
,我试过这样做:
instance Read(Foo ab)where
read s = bar s
但是当我将文件加载到GHCi中进行测试时出现以下错误它: Fraction.hs:11:1:read'不是Read类的(可见)方法
有人可以告诉我什么是问题,我怎么能实际地实例化这种类型? 阅读 typeclass不会声明直接读取
;相反,它定义了 readsPrec
,它支持优先级(当读取
复杂数据类型的值时这很重要其他类型的元素)。当你使用派生(读取)
时,你得到的定义看起来大致像
instance(Read a)=> Read(Tree a)其中
readsPrec dr = readParen(d> app_prec)
(\r - > [(Leaf m,t)|
(Leaf ,s)-lex r,
(m,t)< - readsPrec(app_prec + 1)s])r
++ readParen(d> up_prec)
( (u:s)< - readsPrec(up_prec + 1)r,
(:^:,t) < - lex s,
(v,w)< - readsPrec(up_prec + 1)t])r
其中app_prec = 10
up_prec = 5
(这显然对于 如果标准派生是不够的,对于类似你的类型,它只是一个 顺便说一句, I have a custom data type but I'm getting the following error when I load my file into GHCi to test it: Could someone tell me what the problem is and how I can actually instantiate this type? The Read typeclass doesn't declare (this obviously for a If the standard derivation isn't sufficient, for a type like yours that is simply a bucket of BTW, 这篇关于在Haskell中为自定义数据类型创建Read type类的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!树
数据类型,但类似的规则适用于其他用户定义的ADT)。 (另外,上面是一个小小的谎言:GHC实际上使用了不同的实现,但是除非你愿意在GHC内部进行挖掘,否则以上就是你应该做的事。)
$根据 readsPrec
和 readList $定义b $ b
read
c $ c>( Read
中的另一种方法,除 Char
以外的每种类型均默认用于读取 [Char]
作为字符串而不是 Char
的列表)。
Int
s的存储桶,您可以忽略优先级参数。 p>
读取
和显示
您可能需要考虑其他方式对您的数据进行I / O操作。Foo = Foo{ a :: Int, b :: Int}
and I'm trying to make Foo a custom instance of read. I already have a function bar :: String -> Foo
and I tried doing this:instance Read (Foo a b) where
read s = bar s
Fraction.hs:11:1: read' is not a (visible) method of class Read'
read
directly; instead, it defines readsPrec
, which supports precedence (this is important when read
ing a value of a complex data type involving elements of other types). The definition you get when you use deriving (Read)
looks roughly likeinstance (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
data type, but similar rules apply for other user-defined ADTs). (Also, the above is a slight lie: GHC actually uses a different implementation, but the above is the kind of thing you should do unless you're willing to dig around inside of GHC.)read
is defined in terms of readsPrec
and readList
(the other method in Read
, which is defaulted for every type except Char
where it's used to read [Char]
as a string instead of as a list of Char
).Int
s you can ignore the precedence parameter.Read
and Show
are rather slow; you may want to consider other ways to do I/O with your data.