Reputation: 763
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
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