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

Nat*_*ell 0 haskell algebraic-data-types

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

data S = NP VP
Run Code Online (Sandbox Code Playgroud)

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

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

data D = A | An | The
type Adj = String -- Too many adjectives for me to list, so I make it a type
                  -- synonym for String.
Run Code Online (Sandbox Code Playgroud)

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

data NP = Maybe D Maybe Adj N
Run Code Online (Sandbox Code Playgroud)

这给了我错误:

Expecting one more argument to `Maybe' In the type `Maybe' In the definition of data 
constructor `Maybe' In the data type declaration for `NP'
Run Code Online (Sandbox Code Playgroud)

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

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

data NP' = NP' {determiner :: Maybe D, adjective :: Maybe Adj, noun :: N}
Run Code Online (Sandbox Code Playgroud)

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

J. *_*son 7

尝试

data NP = NP (Maybe D) (Maybe Adj) N
Run Code Online (Sandbox Code Playgroud)

你需要

  1. 从构造函数名称开始:在本例中 NP
  2. Maybe通过用括号消除歧义,仅应用我所做的一个参数
  3. 在构造函数中表示3个单独的槽,每个组件类型一个

  • @Sintrastes,它是如何构建数据的.在此声明之后,将引入一个函数`NP :: Maybe D - > Maybe Adj - > N - > NP`,这就是你如何构造`NP`类型的对象.你需要一个构造函数名称,因为(比如`Maybe`)数据类型允许有多个构造函数,所以我们需要说明我们的意思. (3认同)
  • @Sintrastes`data VP = V(也许Abv)`不将VP定义为V,也可能是Abv.它说VP是应用于Abv的"V"构造函数; 即它不包含V,只有(可能)一个Adv.几乎可以肯定*不是你想要的. (3认同)
  • @Sintrastes澄清之前的评论:`data VP = V(Maybe Adv)`with`type V = String`,因为类型构造函数和数据构造函数位于两个不同的名称空间中.即第一个"V"与第二个"V"无关,尽管名称相同.您的混淆可能源于这样的常见习惯:当只有后者之一时,给出数据类型的类型构造函数和数据构造函数相同的名称. (2认同)