【问题标题】:Constraining higher-kinded types for a Function1's argument and result type为 Function1 的参数和结果类型约束更高种类的类型
【发布时间】:2013-09-28 03:09:50
【问题描述】:

给定一些更高种类的类型:

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[_] =&gt; Event[_, U, _],它会编译,但我真的很想重新获得一些类型安全性。

【问题讨论】:

  • 它需要存在吗?不能只给declare加一个类型参数吗?
  • 我的意思是,如果我正确地解释了“对于某些人”的意思,您可以写 (Impl[s] =&gt; Event[s,A]) forSome {type s} 但我不确定将 S 设置为 @ 的类型参数有什么好处987654336@.
  • @Owen 是的,必须这样。 declare 从伴随对象执行并声明实现类的事件,而与用于实例化该类的系统无关。我只是意识到我的问题是Function1 的语法——所以我添加了一个显示正确语法的答案。
  • 有没有机会你真正寻找的是Impl[s] =&gt; Event[s,A] forAll {type s}(实际上不是有效的scala)?
  • @Owen -- 是的,我在一分钟前就意识到了这一点。可惜这不是一个有效的声明......(我会称之为forAny :) 无论如何谢谢

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


【解决方案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] =&gt; Event[S, A]) forAny { type S }...

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多