1

我有一种数据类型,我用它来表示行列和行列:

data Object a = Row a
                |Column a

data Row a = Object a
             | Left(Row a)(Row a)

data Column a = Object a
             | Above(Column a)(Column a)


testfunction::Object a->String
testfunction Row(Left(c)(d)) = "Recognized row"

我想知道如何声明 Object 数据类型定义中的构造函数可能“包含”在其他地方定义的任何构造函数,而 Object 数据类型定义中的不同构造函数可能“包含”一组不同的构造函数。

所以:

data Object a = Object1(Set1 a)
                | Object2(Set2 a)

data Set1 a = A a| B a| C a| D a
data Set2 a = X a| Y a| Z a

所以唯一有效的组合是 Object1(A a) Object1(B a) Object1(C a) Object1(D a)、Object2(X a)、Object2(Y a) 和 Object2(Z a)

4

1 回答 1

2

您的Object a类型适用于所有类型a。所以如果你有一个值Object a(就像你在你的函数中所做的那样),你对什么是一无所知a- 特别是,你知道它是一个类型的值Row a

现在,这有点令人困惑,因为您已经指定Row了两次——作为类型和作为 type 的构造函数Object。这两者完全没有关系。也就是说,在

data Object a = Row a

没有任何东西强制Row a包含 type 的值Row

最简单的修复——也可能是你真正想要写的——是这样的:

data Object a = Row (Row a)
              | Column (Column a)

这有点令人困惑,因为您看到RowColumn两次,但它们每次都意味着不同的东西。如果你把它写成这样会更清楚:

data Object a = ObjRow (Row a)
              | ObjColumn (Column a)

(这些特定的名称不是很好,因为我想不出该怎么称呼它们,但希望它们能清楚地区分它们。)

在你这样定义之后Object,你应该能够按照你想要的方式进行模式匹配。

于 2012-09-09T20:22:07.217 回答