参数化类型边界

时间:2015-09-16 18:34:14

标签: scala types

我有以下特征(简化示例)

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

1 个答案:

答案 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它或其他东西:)