
On 10/23/07, Luke Palmer
On 10/23/07, TJ
wrote: What I find strange is, if we can have functions with hidden parameters, why can't we have the same for, say, elements of a list?
Suppose that I have a list of type Show a => [a], I imagine that it would not be particularly difficult to have GHC insert a hidden item along with each value I cons onto the list, in effect making the concrete type of the list [(Dictionary Show, a)]. I'm assuming that it will not be particularly difficult because GHC will know the types of the values I cons onto it, so it will most definitely be able to find the Show dictionary implemented by that type, or report a type mismatch error. No dynamic type information is necessary.
Which is exactly what happens with:
data Showable = forall a. Show a => Showable a stuff = [Showable 42, Showable "hello", Showable 'w']
Which is exactly the kind of 2nd-rate treatment I dislike. What does "data Showable = forall a. Show a => Showable a" do for you anyway? Nothing. You just have to type it down. Imagine if we have to type down our anonymous functions at the top level, and give them a name just to satisfy the language: ugh. I find this extra annoying due to not being able to declare datatypes anywhere other than at top-level.
I am not an OO programming zealot, but I'd like to note here that this is also how (class based) OO languages would allow the programmer to mix types. e.g. I can have a List<Show> where the elements can be instances of Show, or instances of subclasses of Show.
Why does this second rate treatment of type classes exist in Haskell?
I think partially the reason is that such polymorphic data structures are somewhat less useful in Haskell than they are in OO languages. This may be in part due to the fact that there's no down-casting. And certain wrappers, eg. Gtk, emulate up- and down-casting using various typeclass tricks.
I was in a similar dilemma shortly after I started learning Haskell, coming from a C++ and Perl background. I think #perl6 has some logs of me whining about Haskell's "lack" of OO features. How are you supposed to design your programs modularly if you can't have a type-agnostic list?
But it doesn't bug me anymore. I can't really say why. The natural solution space in Haskell is so different than that of OO languages, that you don't really need such existentially polymorphic (just made up that term) objects[1]. There is still plenty of modularity in Haskell programs--I would even call it OO, I think--it just looks different, and took a lot of getting used to. I had to remap what I considered an "object" in my brain.
Anyway, enough preachy. Typeclasses definitely aren't perfect; global instance exportation has gotten me in trouble several times. But, other than
[exists a. Show a => a]
I actually don't understand that line. Substituting forall for exists, someone in my previous thread said that it means every element in the list is polymorphic, which I don't understand at all, since trying to cons anything onto the list in GHCi results in type errors.
What would be a first-rate treatment of type classes to you? What kind of features do you want that they don't have?
Convenience. Same thing 1st-class functions do for me ;-) TJ