2015-09-10 8 views
0

Я пытаюсь исправить следующее:Как получить оператор lteq <= для работы с кортежами в Scala?

val temp1 = (3, "hello") 
val temp2 = (2, "abcde") 
temp1 <= temp2 

который возвращает ошибку

<console>:24: error: value <= is not a member of (Int, String) 
       temp1 <= temp2 
        ^

Я попытался добавить следующее к моему коду:

implicit val tempOrdering = new Ordering[(Int, String)] { 
    override def compare(a: (Int, String), b: (Int, String)): Int = 
    { 
    if  (a._1 < b._1) { -1 } 
    else if (a._1 > b._1) { 1 } 
    else if (a._2 < b._2) { -1 } 
    else if (a._2 > b._2) { 1 } 
    else 0 
    } 
    override def lteq(a: (Int, String), b: (Int, String)): Boolean = compare(a, b) <= 0 
} 

implicit val tempPartialOrdering = new PartialOrdering[(Int, String)] { 
    override def tryCompare(a: (Int, String), b: (Int, String)): Option[Int] = { 
    if  (a._1 < b._1) { Some(-1) } 
    else if (a._1 > b._1) { Some(1) } 
    else if (a._2 < b._2) { Some(-1) } 
    else if (a._2 > b._2) { Some(1) } 
    else Some(0) 
    } 
    override def lteq(x: (Int, String), y: (Int, String)) = { 
    tryCompare(x, y).map(_ <= 0).getOrElse(false) 
    } 
} 

и TEMP1 < = temp2 все еще не работает.

Я могу выполнять команды, такие как

List(temp1, temp2).min 

но не

min(temp1, temp2) 

так что кажется, что не Scala, видя мое заявление о заказе для (Int, String) кортежей.

я могу ссылаться на мое заявление, используя

tempPartialOrdering.lteq(temp1, temp2) 

и некоторые из моих коллег предложили сделать новый класс только для (Int, String) кортежей, но я нахожу эти решения безвкусный. Я ДЕЙСТВИТЕЛЬНО хотел бы использовать простой старый оператор сравнения «< =»!

Кто-нибудь знает, что я делаю неправильно, что «< =» все еще не является членом (Int, String)? Есть ли способ неявно установить это?

ответ

4

Попробуйте это:

scala> import Ordering.Implicits._ 
import Ordering.Implicits._ 

scala> (2,3) <= (1,2) 
res2: Boolean = false 
+0

Это также работает с моей (Int, String) парой в моем примере - спасибо! –

+0

Возможно, вам действительно понадобится гибридное решение, если второе значение в паре является самым значительным. Я тестировал, что если я использую мой неявный код tempOrdering выше и переписываю, чтобы сначала оценивалось второе значение, это выполняется. Но если вы не объявите заказ, значение по умолчанию будет первым значением как наиболее значимым –

0

Ваши коллеги правы. Создайте собственный тип (класс aka). Это гораздо более элегантно, чем вы даете ему кредит.

0

Я бы просто сделать следующее. Вы можете расширить его по мере необходимости, чтобы получить дополнительную функциональность. Он неуклюж, но он выполняет свою работу и позволяет вам настраивать заказ.

implicit class stringIntTuple(a: (String, Int)) extends (String, Int)(a._1,a._2) { 
    def <= (x: (String, Int)): Boolean = { 
    this._2 <= x._2 
    } 
} 

temp1 <= temp2