约束Function1的参数和结果类型的高级类型

时间:2012-01-15 20:19:05

标签: scala existential-type higher-kinded-types

考虑到一些更高级的类型:

trait Impl [S]
trait Event[S, A]
trait Key  [A]

如何重写以下定义:

def declare[A](fun: Impl[_] => Event[_, A]): Key[A] = ???

fun参数限制为某些 Impl[S] => Event[S, A]实际为S 。例如,在以下情况中:

trait Impl[S] { def ev1: Event[S, Int]; def ev2: Event[T, Int] }

这是一个有效的电话:

declare(_.ev1)

但这不是:

declare(_.ev2)  // this currently compiles

修改

这是一个更完整的例子,它显示了我遇到问题的确切原因:

trait Sys  [S <: Sys[S]]
trait Event[S <: Sys[S], A, Repr]

trait Decl {
  type Impl[S <: Sys[S]]

  protected def declare[U](fun: Impl[_] => Event[_, U, Impl[_]]): Unit = ???
}

声明伴随对象的以下事件无法编译:

object Test extends Decl {
  type Impl[S <: Sys[S]] = Test[S]

  case class Renamed(name: String)

  declare[Renamed](_.renamed)
}

trait Test[S <: Sys[ S]] {
  def renamed: Event[S, Test.Renamed, Test[S]]
}

由于匹配类型的一些问题:

error: type mismatch;
 found   : Event[_$1,Test.Renamed,Test[_$1]] where type _$1
 required: Event[_, Test.Renamed, Test.Impl[_]]
Note: _$1 <: Any, but trait Event is invariant in type S.
You may wish to define S as +S instead. (SLS 4.5)
Note: Test[_$1] <: Test[_], but trait Event is invariant in type Repr.
You may wish to define Repr as +Repr instead. (SLS 4.5)
          declare[ Renamed ]( _.renamed )
                                ^

如果我将函数类型更改为Impl[_] => Event[_, U, _]它会编译,但我真的想重新获得一些类型安全性。

1 个答案:

答案 0 :(得分:1)

问题似乎是存在类型不能用'nice'Function1语法给出:

// error: not found: type S
def declare[A](fun: Impl[S] => Event[S, A] forSome { type S }): Key[A] = ???

...但是在使用普通语法时它可以工作:

// yes!
def declare[A](fun: Function1[Impl[S], Event[S, A]] forSome { type S }): Key[A] = ???

修改

不幸的是,现在我的好用网站搞砸了

missing parameter type for expanded function ((x$1) => x$1.renamed)
[error]    declare[ Renamed ]( _.renamed )

所以我必须坚持使用类型不安全的版本: - (

我想我需要一个像(Impl[S] => Event[S, A]) forAny { type S } ...

这样的新功能