2011-01-05 2 views
6

Три непосредственных подтипа Iterable: Map, Seq и Set. Похоже, что помимо проблем с производительностью - Seq - это карта от целых чисел до значений, а Set - это карта от значений до booleans (true, если значение находится в наборе, в противном случае - false).Почему Seq [V] не расширяет карту [Int, V] и не устанавливает [V] расширение карты [V, Bool]?

Если это так, то почему это не выражается в системе типа путем Seq[V] расширения Map[Int, V] и Set[V] продлить Map[V, Boolean]?

+0

'Set' и' Seq' имеют очень разную семантику от 'Map', поэтому было бы нецелесообразно раскрывать их таким образом. – Gabe

+0

@Gabe, не могли бы вы привести конкретный пример того, что вы подразумеваете под «другой семантикой»? – Adam

+1

Я думаю, что это интересный вопрос, но ответ Мадока является диспозитивным. – Malvolio

ответ

12

Ну, они вроде как делают, по крайней мере, на самом деле общую функциональность. Seq[B] наследует от Int => B (через PartialFunction[Int, B]), Map[A, B] наследует от A => B (также через PartialFunction[A, B]) и Set[A] наследует от A => Boolean. Таким образом, что касается применения функций и методов композиции, все три могут использоваться взаимозаменяемо. Кроме того, они могут использоваться взаимозаменяемо по мере прохождения, так как все реализуют TraversableLike.

+0

Спасибо! В этом случае, я думаю, мой вопрос немного меняется: какова фундаментальная разница в 30 слов или меньше между Map [A, B] и функцией [A, B]? – Adam

+1

@Adam «Карта» проходит, а «Функция» - нет. Таким образом, «Карта» может перечислять свои ключи, но «Функция» не может сделать то же самое для своих параметров. –

4

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

То есть, Map является функцией ключа в значение, то Seq является функцией из Int в значение, а Set является функцией значения в Boolean. Это свойство, которое вы назвали «картой», является funciton. И это уже разделяют все три.

Что, на мой взгляд, Map, Seq и Set действительно о являются:

  • Seq обеспокоен, зная, в каком порядке его элементы. Концептуально, как бы вы добавили элемент в Map? Вам придется перенумеровать все ключи!

  • A Set обеспокоен наличием или отсутствием элемента. Как можно было бы моделировать это в Map? Это должна быть карта со значением по умолчанию, а не с общей картой, и одна, в которой все значения, отличные от значения по умолчанию, одинаковы! Это явно вырожденное поведение, а не абстракция.

  • A Map обеспокоен отображением произвольных ключей на произвольные значения. A Seq не имеет произвольных ключей, а Set не имеет произвольных значений.

+0

«Ну, если все, о чем вы заботитесь» - ну, мой вопрос можно было бы перефразировать как «что конкретно, что дизайнеры библиотеки Scala заботятся о том, что заставило их принять это решение»? – Adam

+0

@Adam См. Http://www.scala-lang.org/sid/3, http://www.scala-lang.org/docu/files/collections-api/collections.html и http: // www. scala-lang.org/docu/files/collections-api/collections-impl.html. –

8

Наблюдение последовательности как назначения от целых чисел к элементам является лишь одним из способов описания последовательности. Есть и другие способы, и нет причин, по которым такой способ описания последовательности должен стать каноническим. Фактическая цель последовательности состоит в том, чтобы сделать кучу элементов доступными и доступными. Последовательность не требуется для фактического назначения целочисленных чисел элементам. Например, большинство реализаций Stream, вероятно, не имеют счетчика, идущего параллельно обходу. Требование, которое наложило бы ненужные накладные расходы на реализацию.

Кроме того, Map[K,V] также является Iterable[(K,V)]. Следуя вашему предложению, Seq[A] также должен был быть Map[Int,A], который также сделает его Iterable[(Int,A)]. Так как Seq простирается Iterable, это сделало бы Seq[A] как в Iterable[A] и Iterable[(Int,A)] (и, рекурсивно, в Iterable[(Int,(Int,A))], Iterable[(Int,(Int,(Int,A)))], и так далее), который не является допустимым способом наследования в Scala.

Вы можете построить аналогичный аргумент для своего предложения относительно Set.

+2

Я думаю, что второй аргумент убедителен. Чтобы упростить его, если 'Seq [A]' extended 'Map [Int, A] ', что бы вернуть' seq.elements() '? – Malvolio

+0

Интересно. Система типа Хаскелла не имеет такого ограничения (на самом деле, она окрашивает этот вид полиморфизма влево и вправо). Интересно посмотреть, как теория Скалы ограничила свою стандартную библиотеку. – Adam

+1

@Adam Я не вижу, чтобы Хаскелл тоже выбрался из этого. Если вы 'foldr' как список в Haskell, вы не складываете кортежи' (Int, A) ': вы складываете' A'. –

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