我一直在尝试使用 deriving
,但是理解 deriving (Read)
的工作方式有些困难。
让我们看一下以下数据定义:
data Data = D Int deriving (Eq, Read, Show)
data DataWithName = DWN { val :: Int } deriving (Eq, Read, Show)
这里没有什么特别的,只有两个数据类型,都包含一个Int
,但第二个引入了一个名为val
的名称,表示这个Int
。
在交互式控制台中,下面的指令可以正常工作:
*Main> D 5
D 5
*Main> DWN 5
DWN {val = 5}
*Main> DWN { val = 5 }
DWN {val = 5}
以下的代码不起作用(编辑:我预计这个代码不会起作用)
*Main> D { val = 5 }
<interactive>:11:1:
Constructor `D' does not have field `val'
In the expression: D {val = 5}
In an equation for `it': it = D {val = 5}
现在让我们来谈谈这个问题:
我以为派生
Read
会给我相同的输入数据类型的方式,但是在下面的代码中,第一行和第二行可以工作,而第三行不起作用,因为没有给出参数名称:d1 = read "D 1" :: Data -- Works
d2 = read "DWN { value = 1 }" :: DataWithName -- Works
d3 = read "DWN 1" :: DataWithName -- This does not work because parameter is not given.
有没有可能使
derving (Read)
能够推导出“非参数名称构造函数”,以便read "DWN 5" :: DataWithName
能够额外工作,而不仅仅是“参数名称构造函数”?或者你能否提供关于如何处理数据读取/输入的信息?
谢谢!
attoparsec
往往很容易使用,但它没有很好的报告解析错误的功能。parsec
更加复杂,而且在我看来不太直观,但它具有相当不错的错误处理能力。trifecta
以出色的错误处理而闻名,但性能却很差。 - dfeuer