Когда один Сет меньше другого в Скале? - PullRequest
4 голосов
/ 01 июля 2010

Я хотел сравнить мощность множества в Scala. Поскольку вещи иногда «просто работают» в Scala, я попытался использовать < между наборами. Кажется, что все проходит, но я не вижу смысла в результате.

Пример:

scala> Set(1,2,3) < Set(1,4)
res20: Boolean = true
  • Что это возвращает?
  • Где я могу прочитать об этом методе в API?
  • Почему его нет в списке под scala.collection.immutable.Set?

Обновление: даже порядок (??) элементов в наборах, кажется, имеет значение:

scala> Set(2,3,1) < Set(1,3)
res24: Boolean = false

scala> Set(1,2,3) < Set(1,3)
res25: Boolean = true

Ответы [ 3 ]

5 голосов
/ 02 июля 2010

Это не работает с 2.8.На Scala 2.7 происходит следующее:

scala.Predef.iterable2ordered(Set(1, 2, 3): Iterable[Int]) < (Set(1, 3, 2): Iterable[Int])

Другими словами, существует неявное преобразование, определенное для scala.Predef, которое «импортируется» для всего кода Scala, из Iterable[A] в Ordered[Iterable[A]], при условии, что есть неявное A => Ordered[A] доступное.

Учитывая, что порядок итерируемого для множеств не определен, вы не можете предсказать об этом много.Например, если вы добавите элементы, чтобы размер набора был больше четырех, вы получите совершенно другие результаты.

2 голосов
/ 01 июля 2010

Если вы хотите сравнить количество элементов, просто сделайте это напрямую:

scala> Set(1, 2, 3).size < Set(2, 3, 4, 5).size
res0: Boolean = true
0 голосов
/ 02 июля 2010

Мои знания по Scala невелики, но, пройдя некоторый тест, я получаю следующее:

scala> Set(1,2) <
<console>:5: error: missing arguments for method < in trait Ordered;
follow this method with `_' if you want to treat it as a partially applied function
   Set(1,2) <
            ^

Это говорит мне, что < происходит от черты Ordered. Больше подсказок:

scala> Set(1,2) < _
res4: (Iterable[Int]) => Boolean = <function>

То есть Set оценивается в Iterable, потому что, возможно, существует неявное преобразование из Iterable [A] в Ordered [Iterable [A]], но я больше не уверен ... Тесты не соответствуют. Например, эти два могут предложить своего рода лексикографическое сравнение:

scala> Set(1,2,3) < Set(1,2,4)
res5: Boolean = true

1 равно, 2 равно, 3 меньше 4.

scala> Set(1,2,4) < Set(1,2,3)
res6: Boolean = false

Но эти не делают:

scala> Set(2,1) < Set(2,4)
res11: Boolean = true

scala> Set(2,1) < Set(2,2)
res12: Boolean = false

Я думаю, что правильный ответ найден в собственном признаке Ordered: для < между наборами нет реализации, кроме сравнения их hashCode:

Важно, чтобы метод hashCode для экземпляра Ordered [A] был совместим с методом сравнения. Однако невозможно обеспечить разумную реализацию по умолчанию. Поэтому, если вам необходимо вычислить хэш экземпляра Ordered [A], вы должны предоставить его самостоятельно либо при наследовании, либо при создании экземпляра.

...