2

我一直在尝试deriving并且很难理解它是如何deriving (Read)工作的。

我们来看看下面的数据定义:

data Data         = D Int deriving (Eq, Read, Show)
data DataWithName = DWN { val :: Int } deriving (Eq, Read, Show)

没什么特别的,只是两种数据类型各自封装了一个Int,但第二种引入valInt.

在交互式控制台中,以下说明按预期工作:

*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)也可以派生“非参数名称构造函数”,read "DWN 5" :: DataWithName以便与“参数名称构造函数”一起工作?

或者您能否提供一些有关如何处理数据读取/输入的信息?

谢谢!

4

1 回答 1

2

我认为派生 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 }一个类型错误。

是否有可能使派生(读取)也可以派生“非参数名称构造函数”,以便读取“DWN 5”:: DataWithName 可以在“参数名称构造函数”之外起作用?

不,但是您可以对 进行一些解析String并将其手动转换为所需的数据结构。

于 2016-01-23T16:29:04.440 回答