используя классы типов на SparkTypes - PullRequest
0 голосов
/ 12 мая 2018

Я пытаюсь использовать scala TypeClass для Spark Types, вот небольшой фрагмент кода, который я написал.

trait ThresholdMethods[A] {
    def applyThreshold(): Boolean
}

object ThresholdMethodsInstances {

    def thresholdMatcher[A](v:A)(implicit threshold: ThresholdMethods[A]):Boolean =
        threshold.applyThreshold()

        implicit val exactMatchThresholdStringType = new ThresholdMethods[StringType] {
        def applyThreshold(): Boolean = {
            print("string")
            true
        }
    }

    implicit val exactMatchThresholdNumericType = new ThresholdMethods[IntegerType] {
        def applyThreshold(): Boolean = {
            print("numeric")
            true
        }
    }
}

object Main{
    def main(args: Array[String]): Unit = {
        val spark = SparkSession.builder().appName("ZenDataValidationLib").config("spark.some.config.option", "some-value")
            .master("local").getOrCreate()
        import spark.sqlContext.implicits._
        val df1 = Seq(
            ("2016-04-02", "14", "NULL", 9874, 880, "xyz"), ("2016-04-30", "14", "FR", 9875, 13,"xyz"), ("2017-06-10", "15", "PQR", 9867, 57721,"xyz")
        ).toDF("WEEK", "DIM1", "DIM2","T1","T2","T3")
        import ThresholdMethodsInstances._
        println(df1.schema("T1").dataType)
        ThresholdMethodsInstances.thresholdMatcher(df1.schema("T1").dataType)
    }
}

Когда я запускаю это на моем локальном intellij, выдается следующая ошибка

Error:(46, 51) could not find implicit value for parameter threshold: com.amazon.zen.datavalidation.activity.com.amazon.zen.datavalidation.activity.ThresholdMethods[org.apache.spark.sql.types.DataType]
        ThresholdMethodsInstances.thresholdMatcher(df1.schema("T1").dataType)

Error:(46, 51) not enough arguments for method thresholdMatcher: (implicit threshold: com.amazon.zen.datavalidation.activity.com.amazon.zen.datavalidation.activity.ThresholdMethods[org.apache.spark.sql.types.DataType])Boolean.
Unspecified value parameter threshold.
        ThresholdMethodsInstances.thresholdMatcher(df1.schema("T1").dataType)

Я тоже пробовал то же самое, используя String и Int, и все работало отлично. Может ли кто-нибудь помочь мне в этом на SparkTypes?

1 Ответ

0 голосов
/ 12 мая 2018

Обратите внимание, что StructField.dataType возвращает DataType, а не конкретный подкласс, и ваш код определяет implicit ThresholdMethods только для IntegerType и StringType.

, поскольку происходит разрешение implicitво время компиляции недостаточно информации для компиляции, чтобы определить правильный экземпляр, который бы соответствовал типам.

Это сработало бы, если бы вы (очевидно, вы этого не хотели):

ThresholdMethodsInstances.thresholdMatcher(
  df1.schema("T1").dataType.asInstanceOf[IntegerType]
)

, но на практике вам потребуется нечто более явное, например сопоставление с образцом, а не неявный аргумент.

Вы также можете рассмотреть возможность перехода на строго типизированный Dataset, который будет лучшим выбором здесь.

...