Zava
Zava

Reputation: 763

Scala abstract type alias meet type class in method Params

I try to compose Scala type class and abstract type alias together, but that raised some problems for me.
Check out the code: I have a ModelService :

trait ModelService[T] {
  type ID
  def save(t: T): ID
  def find(id: ID): T
}

object ModelService {

  implicit object UserService extends ModelService[User] {
    type ID = Long
    def save(t: User): ID = ???
    def find(id: ID): User = ???
  }

}

and I use type class for implementation:

object ModelHelpers {

  def save[T](model: T)(implicit service: ModelService[T]): service.ID =
    service.save(model)

  def find[T: ModelService](id:) = // here, how can I declare the id's type?
    implicitly[ModelService[T]].find(id)
}

The question is : in the ModelHelpers.save, I can declare the return type using service.ID

But in the ModelHelpers.find, how can I declare the param id's type?

Thanks.

Upvotes: 1

Views: 365

Answers (1)

Peter Schmitz
Peter Schmitz

Reputation: 5844

For example:

type User = String

trait ModelService[T] {
  type ID
  def save(t: T): ID
  def find(id: ID): T
}

object ModelService {
  implicit object UserService extends ModelService[User] {
    type ID = Long
    def save(t: User): ID = t.toLong
    def find(id: ID): User = id.toString
  }
}

object ModelHelpers {
  def save[T](model: T)(implicit service: ModelService[T]): service.ID = service save model
  def find[ID0, T](id: ID0)(implicit service: ModelService[T] { type ID = ID0 }): T = service find id
}

ModelHelpers find 5L // "5": User

Upvotes: 3

Related Questions