
Roman Cheplyaka
* Dmitry Vyal
[2012-10-18 17:31:13+0400] On 10/18/2012 03:20 PM, MigMit wrote:
Why do you need "ALike x", "BLike x" etc.? Why not just "Like u x"?
Hmm, looks like a nice idea. I tried it, unfortunately I can't cope with compiler error messages:
tst.hs:32:15: Context reduction stack overflow; size = 201 Use -fcontext-stack=N to increase stack size to N Upcast a b In the first argument of `(.)', namely `(upcast :: b -> a)' In the expression: (upcast :: b -> a) . (upcast :: c -> b) In the expression: (upcast :: b -> a) . (upcast :: c -> b) $ x
instance (Upcast a b, Upcast b c) => Upcast a c where upcast = (upcast :: b -> a) . (upcast :: c -> b)
This is the offending instance. Remember, GHC only looks at the instance head ("Upcast a c" here) when it decides which instance to use.
Roman
Hi Dmitry, looks like you've got the classic (show . read) difficulty. In your "Upcast a c" instance, the compiler is trying to figure out the type of b. You might think there's only one 'chain' to get from (say) type A to type D -- that is via Upcast A B to Upcast B C to Upcast C D; but there's also an instance Upcast x x -- which means there could be any number of Upcast A A, Upcast B B, etc links in the chain. (And this doesn't count all the other possible instances that might be defined in other modules -- for all the compiler knows at that point.) The modern way to handle this is using type functions (aka type families aka associated types), but I'm not sure how that would apply here. (And, for the record, the old-fashioned way would use functional dependencies, as per the Heterogenous Collections paper aka 'HList's). AntC