在Haskell中导出读取:为什么我必须使用构造函数的参数名称?

时间:2016-01-23 16:01:27

标签: haskell constructor deriving

我一直在试验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;?

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

谢谢!

1 个答案:

答案 0 :(得分:1)

  

我认为派生Read会给我提供与输入数据类型相同的方法,但是在第1行和第2行工作时,第3行不起作用......

现在是Readderiving实现的目标。事实上,表达式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进行一些解析并手动将其转换为所需的数据结构。