具有上限的联合类型

时间:2014-06-24 13:16:56

标签: scala types

我正在遵循这个问题的接受答案中提出的技巧 How to define "type disjunction" (union types)?以支持对方法的多类型参数进行类型检查。

隐含的“证据”

@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]
  }

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

问题

这个编译

foo("test")
foo(Array[Byte](123.toByte))

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

foo(new ByteArrayInputStream("abc".getBytes("UTF-8")))

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

foo(new ByteArrayInputStream("abc".getBytes("UTF-8")).asInstanceOf[InputStream])

有没有办法改变

    implicit object InputStreamWitness extends Input[InputStream]

这是扩展 InputStream所有内容的证据?我觉得有一些上限<:符号插在某处,我真的不知道在哪里......

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

1 个答案:

答案 0 :(得分:7)

Input类型中设置T反对变体,如:Input[-T],这意味着如果A是超类型B,则输入[B]是输入[A]的超类型(反向&#34;继承&#34;)。在您的情况下,它只是意味着Input [InputStream]知道如何处理所有子类输入类型InputStream(如ByteArrayInputStream

我非常喜欢Rex Kerr在this问题中对逆变的解释。但还有很多其他人