Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Union type with upper bound

Tags:

types

scala

I was following the technique presented in the accepted answer to this question How to define "type disjunction" (union types)? in order to support type checking for a multiple-type parameter to a method.

The implicit "evidence"

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

The API method

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

The Problem

this compiles

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

but this does not (because it's not a concrete InputStream)

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

I have to cast it to the exact super type to make it work (this compiles)

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

Is there a way to change

    implicit object InputStreamWitness extends Input[InputStream]

So that it is an evidence for everything that extends InputStream? I have a feeling there is some upper bound <: notation to plug in somewhere, I just really don't know where...

Or is this where the "crazy lambda calculus stuff" from the highest voted answer to the aforementioned question comes to the rescue?

like image 877
Eran Medan Avatar asked Mar 20 '23 05:03

Eran Medan


1 Answers

Make Input contra variant in type T like: Input[-T], it means that if A is super type of B, then Input[B] is super type of Input[A] (reverse "inheritance"). In your case it simply means that Input[InputStream] knows how to handle all subclasses input type InputStream (like ByteArrayInputStream)

I really like the explanation on contravariance by Rex Kerr in this question. But there are many others

like image 156
4lex1v Avatar answered Mar 31 '23 01:03

4lex1v