具有上限的联合类型

Era*_*dan 4 types scala

我正在遵循这个问题的接受答案中提出的技术 如何定义"类型分离"(联合类型)?为了支持对方法的多类型参数进行类型检查.

隐含的"证据"

@implicitNotFound(msg="Only String, Array[Byte] and InputStream are supported")
  sealed class Input[T]
  object Input{
    implicit object ByteArrayWitness extends Input[Array[Byte]]
    implicit object StringWitness extends Input[String]
    implicit object InputStreamWitness extends Input[InputStream]
  }
Run Code Online (Sandbox Code Playgroud)

API方法

def foo[T: Input](param: T) =
  param match {
    case x: String => //...
    case x: Array[Byte] => //...
    case x: InputStream => //...
    case _ => throw new UnsupportedOperationException(s"not implemented for type ${param.getClass}")
  }
Run Code Online (Sandbox Code Playgroud)

问题

这个编译

foo("test")
foo(Array[Byte](123.toByte))
Run Code Online (Sandbox Code Playgroud)

但这不是(因为它不具体InputStream)

foo(new ByteArrayInputStream("abc".getBytes("UTF-8")))
Run Code Online (Sandbox Code Playgroud)

我必须将其转换为确切的超类型以使其工作(此编译)

foo(new ByteArrayInputStream("abc".getBytes("UTF-8")).asInstanceOf[InputStream])
Run Code Online (Sandbox Code Playgroud)

有没有办法改变

    implicit object InputStreamWitness extends Input[InputStream]
Run Code Online (Sandbox Code Playgroud)

所以这是所有延伸 的证据InputStream吗?我有一种感觉,有一些上限<:符号插在某处,我真的不知道在哪里...

或者这是从上述问题的最高投票答案的"疯狂的lambda微积分"来拯救?

4le*_*x1v 7

使Input反向变型T,如:Input[-T],它意味着如果A是超类型B的,然后输入[B]是超级类型输入的[A](反向"继承").在你的情况下,它只是意味着Input [InputStream]知道如何处理所有子类输入类型InputStream(如ByteArrayInputStream)

我真的很喜欢Rex Kerr在这个问题上对逆变的解释.但还有很多其他的