Dylan
Dylan

Reputation: 13859

Compiler error when using abstract types

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

Answers (1)

Yuriy
Yuriy

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

Related Questions