在其他数据类型中使用定义的数据类型

时间:2014-03-03 16:11:42

标签: haskell types

继续我的问题:How do I attach optional attributes to values?

我正在尝试定义音乐的Haskell表示。

我想做点什么:

data Chord = Chord Int Modality [Annotate] deriving (Eq, Show, Read)

,正如我所理解的那样定义了一个和弦的新类型。

然后我希望能够将其他事件中的和弦添加到分数中

data Event = Note Int | Chord Int Modality [Annotate] | Rest

然而,编译器说我正在尝试两次定义Chord。

那么,有没有办法在新数据类型定义中使用先前定义的数据类型?对我来说,我正在做的事情或多或少像经典的树定义:

data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)  

哪个有效。那么为什么在这个例子中使用“Tree”是可以的,而不是在我的“Chord”中呢?

2 个答案:

答案 0 :(得分:7)

问题不在于定义类型两次,而在于定义构造函数 Chord两次。你可能想要

type Note = Int

data Event = NoteEvent Note | ChordEvent Chord | Rest

或者,您可以按原样保留Event,但是您基本上已经内联了Chord数据类型的整个定义,因此您不再需要它了。

答案 1 :(得分:4)

data Chord = Chord Int Modality [Annotate] deriving (Eq, Show, Read)

注意Chord在这里使用了两次。这两次出现用于两个不同的事情。

data Chord =                       -- This one defines a new data type
     Chord Int Modality [Annotate] -- This one defines a new data constructor

可以将这两个名称赋予相同的名称,因为它们存在于不同的名称空间中。

data Event = Note Int | Chord Int Modality [Annotate] | Rest

现在您正在尝试定义另一个名为Chord的数据构造函数,这是一个禁忌。数据构造函数必须在模块中的所有数据类型中都是唯一的。如果您想在此处使用 Chord类型,请按以下方式使用:

data Event = NoteEvent Int    | -- A new data constructor, then optionally type(s)
             ChordEvent Chord | -- A new data constructor, then optionally type(s)
             OtherEvent         -- A new data constructor, then optionally type(s)