Manuel Schmidt
Manuel Schmidt

Reputation: 2489

Provide type-class when implementing/override method

I would prefer to work more with type-classes but having some issues: Given the following interface

trait Processor[A] {
  def process[B](f: A => B): Processor[B]
}

I have an implementation that needs an Ordering[A] for some other reasons. Hence the method process needs an Ordering[B] to construct a Processor[B].The following is what I would like to do, but it does obviously not work:

class Plant[A, OA <: Ordering[A]] extends Processor[A] {
  def process[B:Ordering](f: A => B): Processor[B] = null // Plant[B, OB <: Ordering[B]]
}

How can I provide the Ordering[B] for the implementation of process?

I know the reason for this is, that Ordering[A] is passed as an implicit second argument. I don't know but shouldn't there be special support for type-classes in Scala similar to Haskell to recognize what I want (only allow Bs that have an Ordering) in the implementation above without this "workaround"?

Upvotes: 0

Views: 107

Answers (2)

Alexey Romanov
Alexey Romanov

Reputation: 170899

No, and this shouldn't work at all. Given your defnition of Processor, this code will compile:

val processor: Processor[Int] = foo() // foo() is some function that returns a Processor
processor.process[Object](x => new Object())

Now if foo is actually implemented as

def foo() = new Plant[Int]()

then its process method won't work with B = Object.

Upvotes: 1

Chris Martin
Chris Martin

Reputation: 30756

I'm not sure I fully understand what you're trying to achieve, but perhaps you could make Processor generic on the context bound?

trait Processor[A, Bound[_]] {
  def process[B: Bound](f: A => B): Processor[B, Any]
}

class Plant[A: Ordering] extends Processor[A, Ordering] {
  def process[B: Ordering](f: A => B) = ???
}

Upvotes: 0

Related Questions