我有以下代碼定義類型類。類型類和子類型
trait Foo[T] {
def toFoo(x: T): String
}
trait Foos {
def toFoo[T](f: T => String): Foo[T] = new Foo[T] {
def toFoo(x: T): String = f(x)
}
}
object Foo extends Foos {
def toFoo[A: Foo](a: A) = implicitly[Foo[A]].toFoo(a)
implicit def AToFoo: Foo[A] = toFoo { c =>
"A"
}
implicit def BToFoo[T]: Foo[B] = toFoo { c =>
"B"
}
implicit def ListToFoo[T: Foo]: Foo[List[T]] = toFoo { c =>
c.map(toFoo(_)).
}
}
class A
class B extends A
現在如果我有,如果我做toFoo(List(new A, new B)
我得到List("A", "A")
而不是List("A", "B")
。如何確保使用BtoFoo
方法,而不是AToFoo
用於類型B
的類?
你期望'List(new A,new B)'有什麼類型? – 2012-03-20 13:59:02
我希望'List(new A,new B)'有類型'List [A]' – Stephan 2012-03-22 09:16:48
在這種情況下,當您將'toFoo'映射到'List [A]'上時,它顯然首先執行'Flicit [Foo [A]]'並獲取'AToFoo'隱式def,並將其用於每個元素。類型類專爲類型定向調度而設計,而不是用於價值定向調度,所以它們並不總是很好地與子類型匹配。 – 2012-03-22 18:07:27