
Dear all, I was doing a little experimentation with associated type synonyms and ran into a small but unforeseen annoyance. The following, contrived, example snippets illustrate my pain: First, let us declare some of the simplest classes exhibiting associated type synonyms that I can think of, class C a where type T a val :: T a together with a trivial instance for nullary products: instance C () where type T () = () val = () But then, let us try an instance for binary products: instance (C a, C b) => C (a, b) where type T (a, b) = (T a, T b) val = (val, val) I really thought this would work out nicely, but GHC (version 6.8.2) gracefully gives me Couldn't match expected type `T a2' against inferred type `T a' Expected type: T (a2, b) Inferred type: (T a, T a1) In the expression: (val, val) In the definition of `val': val = (val, val) Couldn't match expected type `T b' against inferred type `T a1' Expected type: T (a2, b) Inferred type: (T a, T a1) In the expression: (val, val) In the definition of `val': val = (val, val) while I think I deserve better than that. Can someone (Tom?) please explain (a) why the required unifications fail, (b) whether or not it is reasonable to expect the unifications to succeed, and (c) how I can overcome problems like these? Surely, I can have val take a dummy argument, but I am hoping for something a bit more elegant here. I tried lexically scoped type variables, but to no avail: instance forall a b. (C a, C b) => C (a, b) where type T (a, b) = (T a, T b) val = (val :: T a, val :: T b) gives me Couldn't match expected type `T a2' against inferred type `T a' In the expression: val :: T a In the expression: (val :: T a, val :: T b) In the definition of `val': val = (val :: T a, val :: T b) etc. Cheers, Stefan