Не совсем. Нужно помнить, что, помимо нескольких ключевых слов, все в Scala - это метод invokation для объекта.
Поэтому нам нужно вызвать методы «< =» и «<» для объекта, и каждый такой метод получает параметр. Тогда вам нужно четыре объекта, и есть три явных и два неявных - результаты каждого метода.
Теоретически вы можете передать результат одного из методов другому методу. Я могу думать о двух способов сделать это:
< Имея = возвращает объект, который имеет как параметр он получил и результат Comparision и имеющий < использовать оба эти значения в зависимости от обстоятельств.
Имея < = возвращает либо ложь, либо полученный параметр, и с < либо сбой, либо сравнение с другим параметром. Это можно сделать с помощью класса «Либо» или чего-то на его основе.
Эти два решения очень похожи.
Одна из проблем заключается в том, что потребители таких операторов сравнения ожидают, в результате, булевых. На самом деле это самая простая задача для решения, поскольку вы можете определить неявное из Bitherle [Boolean, T] в Boolean.
Итак, теоретически, это возможно. Вы можете сделать это с помощью собственного класса. Но как бы вы решили изменить уже существующие методы? Знаменитый шаблон Pimp My Class используется для добавления поведения, а не для его изменения.
Вот реализация второго варианта:
object ChainedBooleans {
case class MyBoolean(flag: Either[Boolean, MyInt]) {
def &&(other: MyBoolean): Either[Boolean, MyInt] =
if (flag.isRight || flag.left.get) other.flag else Left(false)
def <(other: MyInt): Either[Boolean, MyInt] =
if (flag.isRight || flag.left.get) flag.right.get < other else Left(false)
def >(other: MyInt): Either[Boolean, MyInt] =
if (flag.isRight || flag.left.get) flag.right.get > other else Left(false)
def ==(other: MyInt): Either[Boolean, MyInt] =
if (flag.isRight || flag.left.get) flag.right.get == other else Left(false)
def !=(other: MyInt): Either[Boolean, MyInt] =
if (flag.isRight || flag.left.get) flag.right.get != other else Left(false)
def <=(other: MyInt): Either[Boolean, MyInt] =
if (flag.isRight || flag.left.get) flag.right.get <= other else Left(false)
def >=(other: MyInt): Either[Boolean, MyInt] =
if (flag.isRight || flag.left.get) flag.right.get >= other else Left(false)
}
implicit def toMyBoolean(flag: Either[Boolean, MyInt]) = new MyBoolean(flag)
implicit def toBoolean(flag: Either[Boolean, MyInt]) =
flag.isRight || flag.left.get
case class MyInt(n: Int) {
def <(other: MyInt): Either[Boolean, MyInt] =
if (n < other.n) Right(other) else Left(false)
def ==(other: MyInt): Either[Boolean, MyInt] =
if (n == other.n) Right(other) else Left(false)
def !=(other: MyInt): Either[Boolean, MyInt] =
if (n != other.n) Right(other) else Left(false)
def <=(other: MyInt): Either[Boolean, MyInt] =
if (this < other || this == other) Right(other) else Left(false)
def >(other: MyInt): Either[Boolean, MyInt] =
if (n > other.n) Right(other) else Left(false)
def >=(other: MyInt): Either[Boolean, MyInt] =
if (this > other || this == other) Right(other) else Left(false)
}
implicit def toMyInt(n: Int) = MyInt(n)
}
А вот сеанс, используя его, показывая, что может и что не может быть сделано:
scala> import ChainedBooleans._
import ChainedBooleans._
scala> 2 < 5 < 7
<console>:14: error: no implicit argument matching parameter type Ordering[Any] was found.
2 < 5 < 7
^
scala> 2 < MyInt(5) < 7
res15: Either[Boolean,ChainedBooleans.MyInt] = Right(MyInt(7))
scala> 2 <= MyInt(5) < 7
res16: Either[Boolean,ChainedBooleans.MyInt] = Right(MyInt(7))
scala> 2 <= 5 < MyInt(7)
<console>:14: error: no implicit argument matching parameter type Ordering[ScalaObject] was found.
2 <= 5 < MyInt(7)
^
scala> MyInt(2) < 5 < 7
res18: Either[Boolean,ChainedBooleans.MyInt] = Right(MyInt(7))
scala> MyInt(2) <= 5 < 7
res19: Either[Boolean,ChainedBooleans.MyInt] = Right(MyInt(7))
scala> MyInt(2) <= 1 < 7
res20: Either[Boolean,ChainedBooleans.MyInt] = Left(false)
scala> MyInt(2) <= 7 < 7
res21: Either[Boolean,ChainedBooleans.MyInt] = Left(false)
scala> if (2 <= MyInt(5) < 7) println("It works!") else println("Ow, shucks!")
It works!
Мэтт, я предлагаю вам принять принятый ответ Александра. Он придумал что-то намного превосходящее. –
Сделали. Благодарим за ответы. Приятно, что вы можете приблизиться к этому в Scala, хотя, вероятно, он более ясен для явной версии с двумя сравнениями и «&&». –