I have read several articles expressing that abstract types should be used to achieve f-bounded polymorphism in Scala. This is primarily to alleviate type inference issues, but also to remove the quadratic growth that type parameters seem to introduce when defining recursive types.
These are defined as so:
trait EventSourced[E] {
self =>
type FBound <: EventSourced[E] { type FBound <: self.FBound }
def apply(event: E): FBound
}
However, this appears to introduce two issues:
1) Each time a user wants to reference an object of this type, they must also refer to the FBound
type parameter. This feels like a code smell:
def mapToSomething[ES <: EventSourced[E], E](eventSourced: ES#FBound): Something[ES, E] = ...
2) The compiler is now unable to infer type parameters for methods such as the above, failing with the message:
Type mismatch, expected: NotInferredES#FBound, actual: MyImpl#FBound
Is anyone out there using a successful implementation of f-bounded polymorphism in their solution, whereby the compiler is still able to infer types?