【发布时间】:2021-02-13 09:35:35
【问题描述】:
我正在尝试使用单个 [A] 类型参数扩展基类,并使用具有 A[_] 类型参数的子类 - 像这样:
abstract class IsBase[A]
abstract class IsSub[A[_]] extends IsBase[A[_]] {
type T
def get(self: A[T]): T
}
implicit def listIsSub[_T] = new IsSub[List] {
type T = _T;
def get(self: List[T]): T = self(0)
}
val list = List(1, 2)
implicitly[IsSub[List]{ type T = Int }].get(list) // works fine
implicitly[IsBase[List[Int]]] // Could not find implicit value for parameter e
我知道这样做的一种方法是将抽象类型 T 移动到类型参数,就像这样:
abstract class IsSub1[A[_], T] extends IsBase[A[T]]
但在我继续这条路线之前,我只想检查一下是否没有一种直接的方法可以使这项工作保持原样。
谢谢!
【问题讨论】:
-
我不明白你需要
IsSub和IsBase做什么,但我很确定你必须将T设置为IsSub的类型参数。当您说extends IsBase[A[_]]时,A[_]与A[_]类型参数不同。您正在使用通配符,这使得它几乎没有用。我建议使用IsSub[A[_], T] extends IsBase[A[T]]或类似的东西。无论如何,这比使用结构类型要容易得多。 -
您声明 Base 采用完整类型,同时声明 Sub 采用类型构造函数。它们是不同的签名。你需要保持一致。除了声明第二个参数T,你还可以声明
IsBase[C[_]],然后同样声明子IsSub[C[_]] extends IsBase[C] -
@user - 谢谢 - 我确实在我的问题中提到了该解决方案,但获得一些外部验证仍然很好。我觉得这是更好的长期方式。
标签: scala generics typeclass implicit existential-type