为什么我可以使用带有记录语法的Maybe,但不能使用常规的ADT语法?

时间:2014-07-29 23:42:29

标签: haskell algebraic-data-types

我在Haskell中编写了一些数据类型来表示正式的英语语法。

data S = NP VP

到目前为止,句子只是名词短语和动词短语。惊叹于代数数据类型的优雅之美!

我还将一个限定词和形容词定义为:

data D = A | An | The
type Adj = String -- Too many adjectives for me to list, so I make it a type
                  -- synonym for String.

现在,我遇到了定义NP的问题,这是一个带有可选限定词和形容词的名词。我的第一个天生本能是使用Maybe:

data NP = Maybe D Maybe Adj N

给了我错误:

Expecting one more argument to `Maybe' In the type `Maybe' In the definition of data 
constructor `Maybe' In the data type declaration for `NP'

(请注意,根据我是否导入了Data.Maybe,错误不会改变)

我使用它的唯一方法是使用记录语法:

data NP' = NP' {determiner :: Maybe D, adjective :: Maybe Adj, noun :: N}

为什么这只在我使用记录语法时才有效?

2 个答案:

答案 0 :(得分:7)

尝试

data NP = NP (Maybe D) (Maybe Adj) N

你需要

  1. 以构造函数名称开头:在本例中为NP
  2. 只使用一个参数应用于Maybe,我通过使用括号消除歧义
  3. 表示构造函数中的3个单独的插槽,每个组件类型一个

答案 1 :(得分:4)

我认为你打算写(用NP数据构造函数):

data NP = NP Maybe D Maybe Adj N

在您的示例中,NP被定义为具有5个参数的构造函数,第一个参数是裸#34; Maybe"。这不起作用,因为Maybe是一种需要一个类型参数的类型,这是错误消息告诉你的。

要获得所需的解释,您需要用括号括起Maybe _

data NP = NP (Maybe D) (Maybe Adj) N