Reputation: 13859
I'm trying to implement a "protocol helper" trait that is responsible for matching up Prompts
and Responses
. The eventual goal is to have an object
that defines the various Prompt and Response classes as subclasses of a sealed trait, then have a class
that mixes in the ProtocolSupport
trait for that Protocol object. The problem is that my current approach won't compile, even though I'm fairly sure it should.
Here's a distilled version of what I've got:
trait Protocol {
type Response
type Prompt <: BasePrompt
trait BasePrompt {
type Data
def validate(response: Response): Validated[Data]
}
}
trait ProtocolSupport[P <: Protocol] {
def foo(prompt: P#Prompt, response: P#Response) = {
// compiler error
prompt.validate(response)
}
}
The compiler doesn't like the response
as an argument to prompt.validate
:
[error] found : response.type (with underlying type P#Response)
[error] required: _4.Response where val _4: P
[error] prompt.validate(response)
[error] ^
This isn't very helpful.. it seems to say that it wants a P.Response
but that's exactly what I'm giving it, so what's the problem?
Upvotes: 1
Views: 77
Reputation: 2769
Compiler absolutely right. It is a family polymorphism and compiler expect type from one family (path depended type). It need to be look like that:
//dependent method type need to be used
//it guaranty that prompt & response from the same hierarchy
def foo(proto : P)(prompt: proto.Prompt, response: proto.Response) = {
Because in your example you can call method with with instances of prompt & respond from different hierarchy (type paths). It look like that you can call foo
method with prompt
from HTTPProtocol
but response
from JSONProtocol
.
Update:
Dependent method type released in SCALA 2.10 series
Upvotes: 3