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

前端 未结 15 2517
温柔的废话
温柔的废话 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:40

    Well, in the specific case of Any*, this trick below won't work, as it will not accept mixed types. However, since mixed types wouldn't work with overloading either, this may be what you want.

    First, declare a class with the types you wish to accept as below:

    class StringOrInt[T]
    object StringOrInt {
      implicit object IntWitness extends StringOrInt[Int]
      implicit object StringWitness extends StringOrInt[String]
    }
    

    Next, declare foo like this:

    object Bar {
      def foo[T: StringOrInt](x: T) = x match {
        case _: String => println("str")
        case _: Int => println("int")
      }
    }
    

    And that's it. You can call foo(5) or foo("abc"), and it will work, but try foo(true) and it will fail. This could be side-stepped by the client code by creating a StringOrInt[Boolean], unless, as noted by Randall below, you make StringOrInt a sealed class.

    It works because T: StringOrInt means there's an implicit parameter of type StringOrInt[T], and because Scala looks inside companion objects of a type to see if there are implicits there to make code asking for that type work.

提交回复
热议问题