[Haskell-cafe] A yet another question about subtyping and heterogeneous collections
anthony_clayden at clear.net.nz
Fri Oct 19 04:14:36 CEST 2012
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:
> > 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.
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).
More information about the Haskell-Cafe