我一直在试验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
会给我提供与输入数据类型相同的方法,但是在第1行和第2行工作时,第3行不起作用,因为没有给出参数名称:
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)
也派生出&#34;非参数名称构造函数&#34;这样read "DWN 5" :: DataWithName
将另外用于&#34;参数名称构造函数&#34;?
或者,您能否提供一些有关如何处理数据读取/输入的信息?
谢谢!
答案 0 :(得分:1)
我认为派生Read会给我提供与输入数据类型相同的方法,但是在第1行和第2行工作时,第3行不起作用......
现在是Read
或deriving
实现的目标。事实上,表达式D { val = 5 }
根本不正确。 val
只是你从记录结构中得到的另一个正常功能。你甚至可以检查它的类型:
ghci| > :t val
val :: DataWithName -> Int
数据构造函数D
仅接受Int
作为其参数,如其类型所示:
ghci| > :t D
D :: Int -> Data
所以无论你做什么,你都不能像D { val = 5 }
那样给它类型错误。
是否有可能启用派生(Read)以派生“非参数名称构造函数”,以便读取“DWN 5”:: DataWithName对“参数名称构造函数”另外工作?
没有。但您可以对String
进行一些解析并手动将其转换为所需的数据结构。