The trait just makes the ambiguous fan-out easier to pull off. Returning
Curried would probably have worked as well.
If I’m understanding things correctly, if you convert
Calculate("const", 1, 2), you’ll get this:
/* 0 */ Calculate
/* 1 */ .applyBegin
/* 2 */ .applyNext("const")
/* 3 */ .applyNext(1)
/* 4 */ .applyNext(2)
/* 5 */ .applyEnd
Until line 2, the compiler knows the exact type which will be returned, but from line 2 on, the return value is just
Operation, which extends
On line 3, either the compiler looks and sees that
Operation doesn’t implement these directly, and fails to compile, or trusts that one of it’s subtypes will implement it (though it doesn’t know which one) and the code triggers a
NoSuchMethodError at runtime.
So, I guess the problem isn’t that
Curried, it’s that the return type is dependent on the value passed. Overloading
applyNext should work, because the compiler can trace the types, but I don’t know if there’s a way to do this for runtime values (or a good way to prevent this from happening).