我有以下特征(简化示例)
trait F[A, M[_] <: Option[A]] {
def v: A
def f: A => M[A]
}
我希望能够创建以下特征
trait G[A] extends F[A, Some]
但这会产生以下错误
Error:(18, 20) type arguments [A,Some] do not conform to trait F's type parameter bounds [A,M[_] <: Option[A]]
如何绑定M[_]
参数化类型?
编辑:
类型F[A, M[_] <: Option[_]]
将起作用。但实际上我的特质还有其他功能
trait F[A, M[_] <: Option[_]] {
def v: A
def f: A => M[A]
def f2: A => A = {
(a: A) => f(a).get
}
}
在f2
的情况下,即使get
返回A
f
也不会返回M[A]
类型的值
Error:(17, 20) type mismatch;
found : _$1
required: A
(a: A) => f(a).get
答案 0 :(得分:0)
您可以完全约束M
的类型,因为它并不需要采用类型参数:
trait F[A, M <: Option[A]] { // M no longer takes a type parameter
def v: A
def f: A => M
}
trait G[A] extends F[A, Some[A]] // Must specify M[A] since M doesn't take a type parameter
但是,您可能希望提供某种映射机制或某些内容,并转到其他类型M[B]
,在这种情况下,受限制较少的版本可以更好地工作:
trait F[A, M[_] <: Option[_]] { // M is no longer constrained to A
def v: A
def f: A => M[A] // M is manually constrained to A here
}
trait G[A] extends F[A, Some]
<强>更新强>
很遗憾,您的f2
功能无法使用。即使我们知道类型是正确的,编译器也无法正确推断类型(Scala的限制)。您可以将此函数添加到G[A]
,它将按预期工作,因为M[_]
现在有一个具体的类型。
trait G[A] extends F[A, Some]{
def f3: A => A = a => f(a).get
}
作为旁注,你永远不应该使用Option.get
,它会失败使用Option
的目的! flatMap
它或其他东西:)