Reputation: 1177
I have a data type which I am using to represent rows of columns and columns of rows:
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"
I would like to know how I can state that a constructor in the Object data type definition may "contain" any constructors which are defined elsewhere and a different constructor in the Object data type definition may "contain" a different set of constructors.
So:
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
So the only valid combinations are Object1(A a) Object1(B a) Object1(C a) Object1(D a), Object2(X a), Object2(Y a) and Object2(Z a)
Upvotes: 1
Views: 162
Reputation: 68152
Your Object a
type works for all types a
. So if you have a value of Object a
(as you do in your function), you know nothing about what a
is--particularly, you do not know that it is a value of type Row a
!
Now, this is a little confusing because you have specified Row
twice--as a type and as a constructor of the type Object
. These two are not related at all. That is, in
data Object a = Row a
there is nothing forcing Row a
to contain a value of type Row
.
The simplest fix--and probably what you actually meant to write--is this:
data Object a = Row (Row a)
| Column (Column a)
this is a little confusing because you see Row
and Column
twice, but they mean different things each time. It would be clearer if you wrote it as something like:
data Object a = ObjRow (Row a)
| ObjColumn (Column a)
(These particular names aren't very good because I couldn't think of what to call them, but hopefully they make the distinction clear.)
After you define Object
like this, you should be able to pattern match the way you want to.
Upvotes: 2