5

我有一个 F 有界类型Sys

trait Sys[S <: Sys[S]]

还有一些将其作为类型参数的特征:

trait Foo[S <: Sys[S]]

假设我有一个要使用 a 调用的方法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)
                                    ^

如果Sys, Foo, invoke, Update,Openedobserve被给定,我如何修复偏函数。允许将值或类型成员添加到Foo.

4

2 回答 2

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)
}

更新:

你是绝对正确的。对于所有新类型替换,您需要为将类型参数移动到正文定义别名。

键入别名示例:

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) = ()          
于 2014-01-08T12:16:47.790 回答
0

一个可能的解决方案是铸造:

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

显然这是可怕的,而不是首选的解决方案,所以我正在等待其他答案。

于 2014-01-07T22:04:15.340 回答