我需要一些帮助,试图理解为什么这些定义
data SegmentList
= SegmentList SegmentlistHeader [Segment]
| AugmentedSegmentList SegmentlistHeader [AugmentedSegment]
deriving (Show)
data SegmentlistHeader
= SegmentlistHeader DatabaseName Query LabelType TimeStamp
deriving (Show)
data Segment
= Segment SegmentLabel SegmentStart SegmentEnd Session Checksum
| AugmentedSegment SegmentLabel SegmentStart SegmentEnd Session Checksum Metadata
deriving (Show)
type DatabaseName = String
type SegmentLabel = String
type SegmentStart = Double
type SegmentEnd = Double
type Session = String
type LabelType = String
type Query = String
type TimeStamp = String
type Checksum = String
type Metadata = [(String, String)]
导致出现此错误消息:
Not in scope: type constructor or class `AugmentedSegment'
A data constructor of that name is in scope; did you mean -XDataKinds?
虽然:
data UmeQueryPart
= LabelInLabelType String [String] String
| LabelType String
| UmeQueryDominance UmeQueryPart UmeQueryPart String
| UmeQuerySequence UmeQueryPart UmeQueryPart String
| UmeQueryIntersect [UmeQueryPart]
| UmeQueryUnion [UmeQueryPart]
deriving Show
像魅力一样编译。我显然不够熟练,看不出差异......
答案 0 :(得分:6)
从你的编辑中,你有
data SegmentList
= SegmentList SegmentlistHeader [Segment]
| AugmentedSegmentList SegmentlistHeader [AugmentedSegment]
deriving (Show)
data Segment
= Segment SegmentLabel SegmentStart SegmentEnd Session Checksum
| AugmentedSegment SegmentLabel SegmentStart SegmentEnd Session Checksum Metadata
deriving (Show)
问题特别来自SegmentList
的第二个构造函数:
AugmentedSegmentList SegmentlistHeader [AugmentedSegment]
此处您说AugmentedSegmentList
包含AugmentedSegment
的列表,但AugmentedSegment
是Segment
的构造函数,它不是类型。定义数据类型时,它只能引用其他类型,而不能引用其他构造函数。您可以将其更改为
AugmentedSegmentList SegmentlistHeader [Segment]
但这可能不是你想要的。由于Segment
和AugmentedSegment
构造函数除了添加Metadata
字段之外是相同的,因此我建议使用
data Segment
= Segment SegmentLabel SegmentStart SegmentEnd Session Checksum
deriving (Show)
data AugmentedSegment
= AugmentedSegment Segment Metadata
deriving (Show)
然后你可以得到一个仅由类型系统强制执行的AugmentedSegment
的列表,但这也意味着你不能将AugmentedSegment
传递给接受a的函数Segment
。由于这些似乎是不同的东西,这不应该是一个问题。如果是,您可以随时将Segment
中包含的AugmentedSegment
字段传入您关注的函数中,或者您可以更改函数以接受{{1}类型的值1}}而不是。
总之,当你有像
这样的东西时Either Segment AugmentedSegment
data MyType = MyConstructor FieldA FieldB FieldC
符号是类型的名称,MyType
符号是构造函数,您可以将其视为返回类型为MyConstructor
的函数的函数,以及{ {1}}符号都必须是现有的类型,或者可以递归地引用MyType
,它们不能是其他构造函数。这就是导致您看到错误的原因。