2015-10-23 5 views
4

Какова причина создания ::, относящаяся к List и недоступная для всех подклассов Seq? Чтобы дать конкретный пример:Почему :: Работает только со списками?

// :: for pattern matching 
def getTail[E](s: Seq[E]): Seq[E] = s match { 
    case head :: tail => tail 
    case empty => empty 
} 
getTail(Seq(1, 2)) // returns List(2) as expected 
getTail(Seq()) // returns List() as expected 
getTail(Queue(1, 2)) // returns Queue(1, 2), not Queue(2) 
getTail(Buffer(1, 2)) // returns ArrayBuffer(1, 2), not ArrayBuffer(2) 

// :: for building sequences 
1 :: 2 :: 3:: Nil // Creates List(1, 2, 3) 
1 :: 2 :: List(3) // same as above 
1 :: 2 :: Queue(3) // does not compile. :: is not a method within Queue 

Все последовательности упорядочены и имеют понятие «голова» и «хвост», так почему же реализаторы библиотеки коллекций только обеспечивают :: к List? Почему я должен использовать +:, если я хочу иметь возможность работать со всеми Seq?

Редактировать: Я понимаю аргумент производительности - мне давали его почти каждый раз, когда я задавал этот вопрос, но я в основном не согласен с ним. Представьте себе другую библиотеку коллекции, в которой было изменено только одно: удаление :: от List. Что изменится?

  • я все еще могу строить свои списки в производительном способе с использованием +: и Nil такого как "A" +: "B" +: Nil.
  • Я все еще могу элегантно сопоставить шаблон, используя +:, чтобы извлечь различные части моего списка. например case head +: tail => println(head)
  • Существует единый метод построения и сопоставления всех подклассов Seq. Это устраняет необходимость в linter для поиска тонких ошибок, таких как тот, который я ввел в getTail.

честно, я не вижу, как метод уникален для List делает ничего проще, понятнее, или более производительным, чем при использовании +:. И если это так, то я не вижу причин для ::, а конкретно для List. Учитывая это, я не вижу причины для того, чтобы существовать вообще ::.

+1

это довольно запутанно, что им нужны правила ворса, чтобы охранять его. Но не каждый seq имеет эффективный хвост (если требуются ассигнования). –

+0

Я думаю, что это так, так что :: unapply/extractor может быть эффективным. Это означало бы, что: (как минусы) существует только для симметрии. –

+0

@ TheArchetypalPaul Это тривиально, чтобы класс '::' case работал со всеми 'Seq', а не просто' List'. Экстрактор по-прежнему будет эффективен для «List», не так ли? –

ответ

3

Те же рассуждения, что и для всех операторов класса. Как #:: для Stream или ! для Actor.

Как List является односвязным, добавочные элементы и деконструкция в голову + хвост выполняется в O (1). Это, по сути, самая используемая операция для списков. Вся идея списка строится вокруг этой операции.

Обратите внимание, что List поддерживает . Но с использованием :: четко показаны ваши намерения эффективно использовать List.

+0

Я ответил на это, отредактировав свой вопрос. Я не считаю, что производительность является веской причиной наличия '::', поскольку '+:' выполняет идентичную цель, так же, как и исполнитель, и может использоваться всеми подклассами 'Seq'. –