派生读入 Haskell:为什么我必须使用构造函数的参数名称?
Deriving Read in Haskell: Why do I have to use the contructor's parameter names?
我一直在试验 deriving
并且很难理解 deriving (Read)
的工作原理。
我们来看看下面的数据定义:
data Data = D Int deriving (Eq, Read, Show)
data DataWithName = DWN { val :: Int } deriving (Eq, Read, Show)
没什么特别的,只是两种数据类型,每种都封装了一个 Int
,但第二种数据类型为 Int
.
引入了名称 val
在交互式控制台中,以下说明按预期工作:
*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)
也派生出 "non-parameter-name constructor",这样 read "DWN 5" :: DataWithName
就可以与 "parameter-name constructor" 一起工作?
或者您能否提供一些有关如何处理数据读取/输入的信息?
谢谢!
I thought that deriving Read would give me the same ways how to enter a data type, but in the following line 1 and line 2 work, while line 3 does not work ...
这不是 Read
所做的或 deriving
实现的。事实上,表达式 D { val = 5 }
根本不正确。 val
只是您从记录构造中得到的另一个正常函数。你甚至可以检查它的类型:
ghci| > :t val
val :: DataWithName -> Int
数据构造函数 D
只接受 Int
作为参数,其类型证明了这一点:
ghci| > :t D
D :: Int -> Data
所以无论你做什么,你都不能给它类似 D { val = 5 }
的东西,因为它是一个类型错误。
Is there some possibility to enable deriving (Read) to also derive the "non-parameter-name constructor" such that read "DWN 5" :: DataWithName would work additionally to the "parameter-name constructor"?
没有。但是您可以对 String
进行一些解析并手动将其转换为所需的数据结构。
我一直在试验 deriving
并且很难理解 deriving (Read)
的工作原理。
我们来看看下面的数据定义:
data Data = D Int deriving (Eq, Read, Show)
data DataWithName = DWN { val :: Int } deriving (Eq, Read, Show)
没什么特别的,只是两种数据类型,每种都封装了一个 Int
,但第二种数据类型为 Int
.
val
在交互式控制台中,以下说明按预期工作:
*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)
也派生出 "non-parameter-name constructor",这样 read "DWN 5" :: DataWithName
就可以与 "parameter-name constructor" 一起工作?
或者您能否提供一些有关如何处理数据读取/输入的信息?
谢谢!
I thought that deriving Read would give me the same ways how to enter a data type, but in the following line 1 and line 2 work, while line 3 does not work ...
这不是 Read
所做的或 deriving
实现的。事实上,表达式 D { val = 5 }
根本不正确。 val
只是您从记录构造中得到的另一个正常函数。你甚至可以检查它的类型:
ghci| > :t val
val :: DataWithName -> Int
数据构造函数 D
只接受 Int
作为参数,其类型证明了这一点:
ghci| > :t D
D :: Int -> Data
所以无论你做什么,你都不能给它类似 D { val = 5 }
的东西,因为它是一个类型错误。
Is there some possibility to enable deriving (Read) to also derive the "non-parameter-name constructor" such that read "DWN 5" :: DataWithName would work additionally to the "parameter-name constructor"?
没有。但是您可以对 String
进行一些解析并手动将其转换为所需的数据结构。