
On Thu, Mar 6, 2008 at 7:52 PM, Ryan Ingram
I wish there was some form of instance declaration that let you do case analysis; something similar to the following:
instances C [a] where
instance C String where c = "a"
instance C a => C [a] where c = [c,c] instance Num a => C [a] where c = [0]
When trying to find a constraint for C [a] for some type a, the instances would be checked in order: 1) If a was Char, the first instance would be selected. 2) Otherwise, if there was an instance for C a, the second instance would be selected. 3) Otherwise, if there was an instance for Num a, the third instance would be selected. 4) Otherwise a type error would occur.
I agree that this would be nice. But I think that the situation is stickier than it looks on the surface. Consider this: instances GShow [a] where instance [Char] where gShow = id instance [a] where gShow x = "list(" ++ length x ++ ")" gShow' :: [a] -> String gShow' = gShow For any implementation which keeps implementations polymorphic (i.e. no required inlining like C++), despite what the program *says*, gShow' would not be equal to gShow. When gShow' calls gShow, it needs a GShow dictionary; so it does constraint solving and finds a dictionary for [a]. a is not Char, so it uses the [a] dictionary, not the [Char] dictionary. Therefore: gShow "hello" = "hello" gShow' "hello" = "list(5)" That's just the first issue, and that alone is enough to make me not want this. When we get to more complex examples like the one you gave above involving constraints, in order to solve for the constraints needed for an instance of C [a] you need a *disjunction* constraint, which vastly increases the likelihood of an undecidable solution. Luke