继续我的问题: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”中呢?
答案 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)