[Haskell-cafe] A yet another question about subtyping and heterogeneous collections
akamaus at gmail.com
Fri Oct 19 11:17:05 CEST 2012
On 10/19/2012 06:14 AM, AntC wrote:
> Roman Cheplyaka <roma <at> ro-che.info> writes:
>> * Dmitry Vyal <akamaus <at> gmail.com> [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:
>>> 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.
> 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).
do I understand you correctly, that the error message is the result of
compiler using depth first search of some kind when calculating
instances? Also can you please elaborate a bit more on using functional
dependencies for this problem? Upcast x y is not a function, it's a
relation, y can be upcasted to different x'es and different y's can be
upcasted to single x.
More information about the Haskell-Cafe