Affects Version/s: None
Fix Version/s: None
Component/s: Misc Compiler
This might be classified as an enhancement. But here is an example where I would expect type inference to work - I would expect type information to flow from right to left for a right associative operator, but it does not:
So, explicitly calling the operator results in proper type inference flow, but using the same operator in a right associative way doesn't seem to work. Incidentally, I could fix things in this case by making Foo covariant, but that isn't always possible/desireable.
I thought this might be a bug, and went looking through the spec to see what the spec'd behavior is. Page 85 of the spec states that right associative operators are desugared to the declaration of a fresh variable, followed by application:
So I suppose this is behaving exactly as expected. Incidentally, a consequence of this is that right associative operators cannot be usefully non-strict:
But I have to ask - why are right associative operators desugared this way? It does not seem correct. Since the val is a fresh name, it is not even observable and no code can distinguish it from desugaring a :: b to b.::(a). This will have the benefit of better inference, and it would, incidentally, allow a to be non-strict (which is quite useful in some cases, e.g. a fully lazy stream cons.
The only other reason I could think for the current behavior is to avoid stack overflows in the case of long chains of right associative operators (which would be extremely rare - they would have to be literal expressions in your program of many hundreds of elements to SO). But I think the proper behavior in this case is to keep the more straightforward desugaring and let the user worry about handling that - perhaps by making the operator non-strict, or by manually chunking.