Multiple lower type bounds in Scala

后端 未结 2 1878
你的背包
你的背包 2021-02-13 14:35

I noticed that tuple.productIterator always returns an Iterator[Any] an wondered if it\'s not possible to set multiple lower bounds (so it could be an

相关标签:
2条回答
  • 2021-02-13 15:11

    For the simple case where A and B are bound by the compiler as the same time as T, IttayD's answer works fine:

    def f[T, A <: T,B <: T](a:A, b:B) = List[T](a,b)
    

    When A and B are already bound as in your class Foo[A, B] example, you need to introduce temporary dummy variables to have the compiler do this job:

    class Foo[A, B](a: A, b: B) {
      def g[T, A1 >: A <: T, B1 >: B <: T] = List[T](a: A1, b: B1)
    }
    

    (For the sake of clarity: A1 >: A <: T means that type A1 must be a supertype of A and a subtype of T, and not that A is a subtype of both A1 and T.)

    A1 and B1 are here for the sole purpose of inferring a correct type for T. If the compiler has to infer them, they will resolve to A1 = A and B1 = B, and then T as the most specific type which is a superclass of both A and B.

    One thing that the compiler doesn't realize, though, is that, by transitivity, we have both T >: A and T >: B, which follows directly from the constraints with respect to A1 and B1. We need to help out with the type ascriptions.

    Now, Product#productIterator could not use this technique, as it's defined in a place where we don't even know A and B, or indeed how many type parameters there are in the concrete subclass.

    0 讨论(0)
  • 2021-02-13 15:21

    It sounds like what you need is an HList: http://apocalisp.wordpress.com/2010/07/06/type-level-programming-in-scala-part-6a-heterogeneous-list%C2%A0basics/

    To answer the specific question:

    scala> def f[T, A <: T,B <: T](a:A, b:B) = List[T](a,b)
    f: [T, A <: T, B <: T](a: A, b: B)List[T]
    
    scala> f(1, true)
    res0: List[AnyVal] = List(1, true)
    
    scala> f("x", "y")
    res1: List[java.lang.String] = List(x, y)
    
    0 讨论(0)
提交回复
热议问题