
On Mon, Nov 16, 2009 at 12:33:51AM -0500, Phillip Pirrip wrote:
Hi,
I have the following data defined.
data TypeCon a = ValConA a | ValConB [a] | ValConC [[a]]
So I can use functions with type like (a->a->a) -> TypeCon a -> TypeCon a -> TypeCon a for all 3 value types, and I think is easier to define one single typeclass for (+), (*) etc.
If I want to express the following idea (the following won't compiler):
data TypeCon a = ValConA a | ValConB [ValConA a] | ValConC [ValConB a]
The reason this doesn't compile is that ValConA and ValConB are not types. Indeed, as their names suggest, they are value constructors. I see what you are trying to do here, but in Haskell there is no way to say 'the type of things which were constructed using the ValConB constructor', you can only say 'TypeCon a' which includes values built out of all three constructors.
data TypeCon a = ValConA a | ValConB [TypeCon a]
Which is a nightmare when I try to manipulate anything in this structure.
Right, this isn't really the same thing: this type features such fun friends as ValConB [ValConA 3, ValConA 6, ValConB [ValConB [ValConA 2], ValConA 9]] and so on.
The alternative I guess is to use 3 different type constructors,
data TypeConA a = ValConA a data TypeConB a = ValConB [ValConA a] data TypeConC a = ValConC [ValConB a]
but then I can't use one signal typeclass for (+) etc. Am I correct?
Yes, this seems like the correct alternative to me. What is so bad about having three separate (smaller) type class instances? In my opinion that would break up the code a bit and make it easier to read anyway, as opposed to a single monolithic instance for TypeCon. -Brent