How to define “type disjunction” (union types)?

前端 未结 15 2523
温柔的废话
温柔的废话 2020-11-22 05:52

One way that has been suggested to deal with double definitions of overloaded methods is to replace overloading with pattern matching:

object Bar {
   def fo         


        
15条回答
  •  天命终不由人
    2020-11-22 06:26

    It's possible to generalize Daniel's solution as follows:

    sealed trait Or[A, B]
    
    object Or {
       implicit def a2Or[A,B](a: A) = new Or[A, B] {}
       implicit def b2Or[A,B](b: B) = new Or[A, B] {}
    }
    
    object Bar {
       def foo[T <% String Or Int](x: T) = x match {
         case _: String => println("str")
         case _: Int => println("int")
       }
    }
    

    The main drawbacks of this approach are

    • As Daniel pointed out, it does not handle collections/varargs with mixed types
    • The compiler does not issue a warning if the match is not exhaustive
    • The compiler does not issue an error if the match includes an impossible case
    • Like the Either approach, further generalization would require defining analogous Or3, Or4, etc. traits. Of course, defining such traits would be much simpler than defining the corresponding Either classes.

    Update:

    Mitch Blevins demonstrates a very similar approach and shows how to generalize it to more than two types, dubbing it the "stuttering or".

提交回复
热议问题