Я играл с шаблоном типа в Scala, но мне не удалось выяснить, как реализовать неявный объект-компаньон, когда тип, с которым я работаю, является общим.Scala Typeclasses с generics
Например, предположим, что я определил черту для класса, предоставляющего функции для помещения вещей в Box
.
case class Box[A](value: A)
trait Boxer[A] {
def box(instance: A): Box[A]
def unbox(box: Box[A]): A
}
implicit object IntBoxer extends Boxer[Int] {
def box(instance: Int) = Box(instance)
def unbox(box: Box[Int]) = box.value
}
def box[A : Boxer](value: A) = implicitly[Boxer[A]].box(value)
def unbox[A : Boxer](box: Box[A]) = implicitly[Boxer[A]].unbox(box)
Это работает, как ожидалось, что позволило мне обеспечить реализацию Boxer
для различных типов. Тем не менее, у меня есть no Идея, как я буду делать это, когда тип, в котором я хочу действовать, является общим. Предположим, я хотел иметь возможность использовать мой Boxer
на любом Seq[A]
. object
s в Scala не может включать в себя параметры типа, так что я в недоумении для куда идти:
// Will not compile - object cannot have type arguments
implicit object SeqBoxer[A] extends Boxer[Seq[A]] { ... }
// Will not compile - 'A' is unrecognized
implicit object SeqBoxer extends Boxer[Seq[A]] { ... }
// Compiles but fails on execution, as this doesn't implement an implicit
// conversion for _specific_ instances of Seq
implicit object SeqBoxer extends Boxer[Seq[_]] {
def box(instance: Seq[_]) = Box(instance)
def unbox(box: Box[Seq[_]]) = box.value
}
// Will not compile - doesn't technically implement Boxer[Seq[_]]
implicit object SeqBoxer extends Boxer[Seq[_]] {
def box[A](instance: Seq[A]) = Box(instance)
def unbox[A](box: Box[Seq[A]]) = box.value
}
// Compiles, but won't resolve with 'implicitly[Boxer[Seq[Foo]]]'
// I had high hopes for this one, too :(
implicit def seqBoxer[A]() = new Boxer[Seq[A]] {
def box(instance: Seq[A]) = Box(instance)
def unbox(box: Box[Seq[A]]) = box.value
}
Есть ли способ поддерживать неявные преобразования родовых типов без неявного отдельного объекта для каждого внутренний тип?
Ах! Я полностью забыл о различии между 'def foo: A' и' def foo(): A'. Это действительно очищает вещи! – KChaloux