定义的数据类型未定义?

时间:2014-09-11 19:44:33

标签: haskell custom-data-type

我需要一些帮助,试图理解为什么这些定义

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

像魅力一样编译。我显然不够熟练,看不出差异......

1 个答案:

答案 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的列表,但AugmentedSegmentSegment的构造函数,它不是类型。定义数据类型时,它只能引用其他类型,而不能引用其他构造函数。您可以将其更改为

AugmentedSegmentList SegmentlistHeader [Segment]

但这可能不是你想要的。由于SegmentAugmentedSegment构造函数除了添加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,它们不能是其他构造函数。这就是导致您看到错误的原因。

相关问题