2013-08-18 2 views
1

Я практикую использовать экстрактор:Почему этот список не работает должным образом?

scala> object LE { 
    | def unapply[A](theList: List[A]) = 
    | if (theList.size == 0) None 
    | else Some((theList.head, theList.tail)) 
    | } 
defined module LE 

Он работает для согласования одного элемента:

scala> List(0, 1, 2) match { 
    | case head LE more => println(head, more) 
    | } 
(0,List(1, 2)) 

Но не кажется, что работают для согласования более одного элемента:

scala> List(0, 1, 2) match { 
    | case head LE next LE more => println(head, more) 
    | } 
<console>:10: error: scrutinee is incompatible with pattern type; 
found : List[A] 
required: Int 

Мой экстрактор списков очень похож на экстрактор Stream Scala, который можно использовать следующим образом:

val xs = 58 #:: 43 #:: 93 #:: Stream.empty 
xs match { 
    case first #:: second #:: _ => first - second 
    case _ => -1 
} 

Итак, какая разница не позволяет использовать мой LE таким образом?

ответ

3

Проблема заключается в порядке выполнения. Для #::, так как он заканчивается :, Scala рассматривает его специально, связывая справа налево, а не слева направо (как это обычно бывает для любого другого оператора/типа, например, вашего LE). Следующие работы, как вы ожидаете:

scala> List(0, 1, 2) match { 
    | case head LE (next LE more) => println(head, more) 
    | } 
(0,List(2)) 
+0

Не могли бы вы предложить способ модификации 'LE' или соматера, чтобы« case head LE next LE more' работал? –

+0

Whups! Скопировано неправильно. Отредактированная версия должна работать сейчас. – Shadowlands

+0

большое спасибо! –