[Haskell-cafe] RE: why isn't everything an instance of Data?
Ralf.Lammel at microsoft.com
Fri Jun 16 22:30:52 EDT 2006
Cc Haskell-café as proposed by Frederik,
> Why isn't everything an instance of Data?
> It seems natural to give every type which is defined via 'data' an
> automatic Data instance. This would make implementing many things much
> simpler. Certain types such as functions would only be able to have
> "stub" instances, for instance not allowing traversal of constructor
> arguments, but this would no more hurt the user than not having such
> instances defined in the first place. To clarify, what I am suggesting
> is that Data no longer be a class but an interface - one would be able
> to call 'toConstr' on any type.
I get your overall question but let me ask about one detail. When you say "an interface", what does this mean in the Haskell sense (where normally a type-class is like an OO interface *anyhow*)?
> Is there a fear that this would lead to "sloppy programming"?
I agree that it could be convenient to assume gfoldl and all that as true primitives. Personally, I wouldn't necessarily like that: Haskell's type system seems to be designed to (mostly) distinguish parametrically polymorphic functions from the rest; just as much as it (mostly) makes explicit any effects involved in a computation.
Also, how would these primitives need to be implemented? We would need a whole lot of type information in the sense of reflection to be around at run-time.
> Also, it would be nice if it were possible to have the compiler infer,
> in a function such as
> cast :: a -> Maybe b
> that 'a' and 'b' are instances of the same classes. However, unless
> I'm mistaken this would require 'cast' to have special status with the
> compiler (or for there to be some new syntax allowing one to indicate
> that two type variables implement the same classes).
There are several problems here.
First, I doubt that we want to establish "that 'a' and 'b' are instances of the same classes". That sounds like a too special case. I guess we would want to establish that a given type instantiates a given type class.
Second, our new cast operation (which would indeed be very much like an OO down-cast) would need to be a special primitive indeed, including special syntax. If we had first-class type-classes, special syntax is not needed, but we would still need a primitive for the actual cast.
Third, we need to come up with some fairly tricky means of getting the dictionary for a type "out of the blue" at run-time. This would be sort of possible (certainly for monomorphic types) if we had the type of the value/expression around at run-time, so that we can use it to look up a dictionary from a global pool. However, that type is not available without extra effort.
To summarize, if this was the question, this expectation seems to lead pretty far away from what we have in Haskell and likely to get anywhere soon -- as far as I can tell.
> But without such
> inferences, the Generics stuff has limited usefulness - so much in
> Haskell is based on classes, but the only class one can use in the
> argument of say 'everywhere' is Data itself:
> everywhere :: (forall a . Data a => a -> a) -> forall a . Data a => a -> a
There are two stories here:
a) Any type-specific case can make any amount of type-class assumptions even in the original SYB1 style. This gets you pretty far in practice.
b) If you want to write generic functions whose set of types is characterized by a designated type class, then you need to use SYB3 style.
PS: Some related stuff ...
- I uploaded a new SYB paper recently: http://www.cwi.nl/~ralf/syx/
- We also updated the SYB site to include other people's SYB papers: http://www.cs.vu.nl/boilerplate
- See Pablo Nogueira's paper "Context-Parametric Polykinded Types" for some interesting GH-related issues on type classes; http://www.cs.nott.ac.uk/~pni/Papers/
- Finally, I plan to use my new blog for Haskell-related stuff as well: http://blogs.msdn.com/ralflammel/
More information about the Haskell-Cafe