有没有办法在Scala中指定类型参数的子集,推断其余的?

Dra*_*mon 9 scala type-inference

我有一个看起来像这样的课:

class X[A <: Throwable, B, C](b: B, c: C)
Run Code Online (Sandbox Code Playgroud)

可以推断出A,B和C,所以我可以用以下方法实例化它:

val x = new X(3, 4)
Run Code Online (Sandbox Code Playgroud)

这给了我一个X [Nothing,Int,Int] - 经常是我想要的.

但我有时想将A指定为Nothing以外的东西(比如说AssertionError).如果没有指定B和C,这是否可行.我想象的语法如下:

val x = new X[AssertionError](3, 4)
val x = new X[AssertionError, _, _](3, 4)
val x = new X[AssertionError,,](3, 4)
Run Code Online (Sandbox Code Playgroud)

但显然这不起作用.

是否有一些语法,或者某种方式我可以达到相同的结果?

Dra*_*mon 5

我主要担心的是在使用时简化这一点(我不希望为每次使用定义新类型,因为异常类型通常不同).我发现我可以使用伴侣对象来建造一个中间工厂:

class X[A <: Throwable, B, C](b: B, c: C) {
}

trait XFactory[A <: Throwable] {
  def apply[B, C](b: B, c: C): X[A, B, C]
}

object X {
  def apply[A <: Throwable: Manifest](): XFactory[A] = {
    new XFactory[A] {
      override def apply[B, C](b: B, c: C): X[A, B, C] = {
        new X(b, c)
      }
    }
  }
}

val x = X[AssertionError].apply(3,3)
Run Code Online (Sandbox Code Playgroud)

我能看到的唯一缺点是你必须拼出"申请".


fol*_*one 3

如果您不害怕简洁的核心语法,您可能需要使用lamdas 类型

Welcome to Scala version 2.10.0-20121205-235900-18481cef9b (OpenJDK 64-Bit Server VM, Java 1.7.0_15).
Type in expressions to have them evaluated.
Type :help for more information.

scala> case class X[A <: Throwable, B, C](b: B, c: C)
defined class X

scala> type P[A,B] = ({type l[a,b] = X[AssertionError, a, b]})#l[A,B]
defined type alias P

scala> val x = new P(1,2)
x: X[AssertionError,Int,Int] = X(1,2)
Run Code Online (Sandbox Code Playgroud)

不过,正如 Frank S. Thomas 所建议的那样,定义类型别名是一种可行的方法。