存在类型或类型参数绑定失败

时间:2014-01-07 21:51:14

标签: scala pattern-matching existential-type type-bounds bounded-quantification

我有一个F-bounded类型Sys

trait Sys[S <: Sys[S]]

以及将其作为类型参数的一些特征:

trait Foo[S <: Sys[S]]

假设我有一个用Foo调用的方法:

def invoke[S <: Sys[S]](foo: Foo[S]) = ()

假设我有一个模型更新类型,以及一个带有Foo的子类型:

sealed trait Update
case class Opened[S <: Sys[S]](foo: Foo[S]) extends Update

注册模型观察者的辅助函数:

def observe(pf: PartialFunction[Update, Unit]) = ()

现在以下失败:

observe {
  case Opened(foo) => invoke(foo)
}

<console>:16: error: inferred type arguments [Any] do not conform to method invoke's
                     type parameter bounds [S <: Sys[S]]
                case Opened(foo) => invoke(foo)
                                    ^

我如何修复部分功能,如果SysFooinvokeUpdateOpened和{ {1}}给出了。允许将值或类型成员添加到observe

2 个答案:

答案 0 :(得分:1)

如何将 Foo 特征的类型参数移动到类型变量:

trait Sys[S <: Sys[S]]
trait Foo { type S <: Sys[S] }

sealed trait Update
case class Opened(foo: Foo) extends Update

def invoke(foo: Foo) = ()
def observe(pf: PartialFunction[Update, Unit]) = ()

observe {
  case Opened(foo) => invoke(foo)
}

<强>更新

你是对的。对于所有新类型替换,您需要为move类型参数定义别名。

输入别名示例:

trait Sys[S <: Sys[S]]
class A extends Sys[A]
class B extends Sys[B]

trait Foo { type S <: Sys[S] }
trait Boo { type S <: Sys[S] } 

object module_A{
  type Foo = com.company.Foo { type S <: A }
  type Boo = com.company.Boo { type S <: A }
}

def invoke(foo: module_A.Foo, boo: module_A.Boo) = ()          

答案 1 :(得分:0)

可能的解决方案是施放:

observe {
  case Opened(foo) => invoke(foo.asInstanceOf[Foo[~] forSome { type ~ <: Sys[~] }])
}

显然这很糟糕,不是首选解决方案,所以我在等待其他答案。