2016-06-26 8 views
1

У меня есть следующие функции, определенной:Почему scala не может вывести подстановочный знак из двух функций?

import org.apache.spark.sql.catalyst.{ScalaReflection} 

import ScalaReflection.universe 
import universe.TypeTag 

def scalaTypesFor(dataType: DataType): Set[TypeTag[_]] = ... 

def scalaTypeOpt: Option[TypeTag[_]] = ... 

val catalystType = ... 
scalaTypeOpt.map(v => Set(v)) 
     .getOrElse{ 
     val default = scalaTypesFor(catalystType) 
     default 
     } 

в этом случае, как и scalaTypesFor scalaTypeOpt, как ожидается, с получением TypeTag с подстановочного параметра, они должны быть одного и того же типа. Однако компилятор дал мне следующую ошибку:

Error:(29, 51) inferred type arguments [scala.collection.immutable.Set[_117] forSome { type _$2; type _117 >: org.apache.spark.sql.catalyst.ScalaReflection.universe.TypeTag[_$2] <: org.apache.spark.sql.catalyst.ScalaReflection.universe.TypeTag[_] }] do not conform to method getOrElse's type parameter bounds [B >: scala.collection.immutable.Set[org.apache.spark.sql.catalyst.ScalaReflection.universe.TypeTag[_$2]] forSome { type _$2 }] 
    val effective = scalaTypeOpt.map(v => Set(v)).getOrElse{ 
               ^

Что случилось с типом вывода и как его исправить?

ответ

1

Я думаю, проблема в том, что у вас есть два неизвестных типа _, и нет никакой гарантии, что они совместимы. Также неизменяемые Наборы в scala неверно инвариантны (прежде чем люди начинают комментировать, было много обсуждений, и последнее слово на этом состоит в том, что действительно нет истинной фундаментальной причины, по которой они НЕ должны быть ковариантными), что, как правило, вызывает раздражение и печатать вопросы.

Не есть компилятор вокруг, чтобы проверить, но вы можете попробовать несколько вещей

  1. (вряд ли будет работать) приписывать тип зделали Set[TypeTag[_]](v)
  2. изменить код, чтобы вы позволить компилятор захватить неизвестный тип и доказать себе, что это тот же один, как, например:

    def scalaTypesFor[T](dataType: DataType): Set[TypeTag[T]] = ??? 
    
    def scalaTypeOpt[T]: Option[TypeTag[T]] = ??? 
    
    def xform[T] = { 
        val catalystType = ??? 
        scalaTypeOpt[T].map(v => Set(v)) 
         .getOrElse{ 
         val default = scalaTypesFor[T](catalystType) 
         default 
        } 
    } 
    

или если вы можете сделать-й em local defs

def xform[T] = { 
     def scalaTypesFor(dataType: DataType): Set[TypeTag[T]] = ??? 
     def scalaTypeOpt: Option[TypeTag[T]] = ??? 

     val catalystType = ??? 
     scalaTypeOpt.map(v => Set(v)) 
      .getOrElse{ 
      val default = scalaTypesFor(catalystType) 
      default 
     } 
    } 
+0

это решило вашу проблему? – Creos

 Смежные вопросы

  • Нет связанных вопросов^_^