2015-07-02 3 views
0

Я пытаюсь написать функцию, которая должна возвращать разные пары в зависимости от ввода. Я применил «+ -/*» в Scala для моего конкретного использования. Каждый из них (+, -, *, /) имеет три реализации на основе ввода. У меня есть RDD и Float как входы, поэтому он может быть + между RDD и RDD, или Float и RDD, или Float и Float и так далее.Как назначить разные типы возврата функции в Scala?

Теперь у меня есть синтаксический анализатор, который читает выражение из ввода, например: RDD + 1, анализирует его и создает постфикс, чтобы сделать вычисления проще: RDD1 +, а затем я хочу сделать расчет, используя мой реализованный +. с помощью this algorithm Я пытаюсь изменить его таким образом, чтобы он выполнял вычисления на основе моего входного выражения. Например, он содержит:

var lastOp: (Float, Float) => Float = add 

Как я могу изменить это: (Float, Float) => Float к чему-то, что будет принимать (RDD, Float)|(RDD, RDD) |(Float, Float) => RDD = add // моей реализации оного ???

Издание:

Я добавил эту часть с помощью двух ответов ниже: Хорошо я написал:

 def lastop:(Either[RDD[(Int,Array[Float])], Float], Either[RDD[(Int,Array[Float])], Float]) => RDD[(Int,Array[Float])] = sv.+ 

, в котором св является экземпляром из другого класса, который я был переопределение + в том, что, но два разных способах, так что теперь я ма получаю сообщение об ошибке, которую я предполагаю, потому что компилятор путается, о которых реализация использовать это

 error: type mismatch; 
     [error] found : (that: org.apache.spark.rdd.RDD[(Int, Array[Float])])org.apache.spark.rdd.RDD[(Int, Array[Float])] <and> (that: Float)org.apache.spark.rdd.RDD[(Int, Array[Float])] 
     [error] required: (Either[org.apache.spark.rdd.RDD[(Int, Array[Float])],Float], Either[org.apache.spark.rdd.RDD[(Int, Array[Float])],Float]) => org.apache.spark.rdd.RDD[(Int, Array[Float])] 

Примечание: все, что он говорит, это две разные реализации для «+»

+0

Вы можете использовать функцию перегрузки? То есть, реализуйте каждый из этих методов с разными типами аргументов. – marios

+1

afaik, для этого вам нужно будет реализовать свою функцию «добавить» таким же образом. Таким образом, у вас будет только одна реализация, использующая Либо вместо нескольких перегруженных реализаций.Тем не менее, я буду обновлять свой ответ с помощью третьего варианта, надеюсь, лучше удовлетворить ваши потребности. –

+1

Извините, для третьего варианта я думал по линиям Numeric [T], который, как я теперь думаю, не сработает. Тем не менее, я обновил свой ответ на то, что, как я думаю, может работать. Я не думаю, что то, что вы описываете, возможно именно так, как вы его описываете. –

ответ

1

Ну, я не уверен, что это лучший способ сделать это, но это ОДИН способ сделать это и должен привести к использованию вы описали (или по крайней мере близко к нему):

import scala.language.implicitConversions 

// implicit conversions 
implicit def float2Either(in: Float): Either[Float, RDD[(Int,Array[Float])]] = Left(in) 
implicit def rdd2Either(in: RDD[(Int,Array[Float])]): Either[Float, RDD[(Int,Array[Float])]] = Right(in) 

def add(left: Either[Float, RDD[(Int,Array[Float])]], right: Either[Float, RDD[(Int,Array[Float])]]): Float = { 
    (left, right) match { 
    case (Left(someFloat), Left(anotherFloat)) => ??? 
    case (Left(someFloat), Right(someRdd)) => ??? 
    case (Right(someRdd), Left(someFloat)) => ??? 
    case (Right(someRdd), Right(anotherRdd)) => ??? 
    } 
} 
val lastOp: (Either[Float, RDD[(Int,Array[Float])]], Either[Float, RDD[(Int,Array[Float])]]) => Float = add 

Другим путем, и, вероятно, лучше один, будет сутенер моей библиотеки шаблон.

Однако вы бы не смогли решить, что (float + float) даст. Что в самых разумных случаях не должно быть проблемой.

Вы можете написать неявные классы-оболочки для Float и RDD так же, как RichFloat RichT и тому подобное. для каждого из них будут использоваться операторы, которые будут принимать другие в качестве входных данных.

implicit class RichRdd(val underlying: RDD) extends AnyVal { 
    def +(in: Float): Float = ??? 
    def +(in: Test): Float = ??? 
} 
implicit class RicherFloat(val underlying: Float) extends AnyVal { 
    def +(in: RDD): Float = ??? 
} 
+0

Спасибо, что помогли мне. У меня есть некоторые вопросы, что такое lFloat и rFloat, и при тестировании вы имели в виду RDD в моей программе? то что будет lTest и rTest? – Rubbic

+1

Это сопоставление с образцом, используя экстракторы (влево, вправо), чтобы привязать содержащиеся значения к новым локальным VAL. Вероятно, вы должны найти соответствие шаблону и экстракторы –

+0

У меня есть вопрос, следуя нашим обсуждениям здесь, не могли бы вы мне помочь в этом? – Rubbic

1

Я думаю pattern matching правильный путь, вы, возможно, потребуется больше исследований вокруг перегрузкой операторов.

О RDD, это должно быть collection of elements в Spark, где я не знаю, чего вы пытаетесь достичь, добавив список в число, только один элемент в RDD? ..и т.д.

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

import math.hypot 

object test { 

    def myadd(x: Any, y: Any) = (x, y) match { 
     case (x: String, y:String) => x.toInt + y.toInt 
     case (x: String, y:Int) => x.toInt + y.toInt 
     case (x: Int, y:String) => x + y.toInt 
     case (x: Int, y:Int) => x + y 
     case _ => 
    }           //> myadd: (x: Any, y: Any)AnyVal 

    var result = myadd(1,2)     //> result : AnyVal = 3 
    println(result)       //> 3 
    println(result.getClass())    //> class java.lang.Integer 

    result = myadd(1,"2") 
    println(result)       //> 3 
    println(result.getClass())    //> class java.lang.Integer 

    result = myadd(1.0,2) 
    println(result)       //>() 
    println(result.getClass())    //> class scala.runtime.BoxedUnit 

} 
+0

@B. Г-н У. Я положил Any в класс myadd, но он дал и ошибку, потому что я отправляю RDD, и он просит Any !!! не знаю, почему Any не может принять тип RDD – Rubbic

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