2012-09-09 158 views
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数据类型定义中的不同构造函数可能“包含”一组不同的构造函数。

所以:

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)中,对象2(X a)中,对象2(Y一)和Object2(Z a)

+1

请注意,您应该从外部加括号:目的是对表达式进行分组,而不是调用函数。即'testfunction(Row(Left c d))'。 – huon

+0

谢谢你的评论 – Lethi

回答

2

您的Object a类型适用于全部类型a。所以,如果你有一个Object a值(如你在你的函数来完成),你知道什么是a什么 - 特别是,你不知道这是Row a类型的值!

现在,这有点令人困惑,因为您指定了两次 - 作为Object类型的类型和构造函数。这两个根本没有关系。也就是说,在

data Object a = Row a 

没有什么迫使Row a包含类型的值。

的简单的解决办法 - 也许你真正的意思是写 - 是这样的:

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

这是一个有点混乱,因为你看到和Column两次,但他们的意思是不同的东西,每次。

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

(。这些特殊的名字不太好,因为我不能想到什么就打电话给他们,但希望他们做出区分清楚)

:如果你写的东西像它会更清晰

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

+0

所以这是否意味着如果我有8个对象在“对象”级别,他们都可以包含eachother(如“行”包含“列”和“列”可以包含“行” )没有简单的方法可以说所有8个对象都可以包含彼此的笛卡尔乘积,而不是制造64个构造函数?换句话说,如果Object1可以包含对象2,3,4,5,6,7,8,并且对象2可以包含对象1,3,4,5,6,7,8,则没有更简单的方法来声明这个对象比在一个构造函数中写出64个可能性? – Lethi

+0

编辑到我上面的评论,如果我只想模拟对象1-8的子集之间的递归遏制会怎样。我希望理想的做法是将对象1-5分组到自己的定义中,然后从上面的语句中,可以允许对象1-8包含对象1-5? – Lethi