2009-06-20 2 views
9

Я пытаюсь понять реализацию List s в Scala. В частности, я пытаюсь получить мою голову вокруг, как вы можете написать матч выражение с помощью оператора инфиксного, например:Разбиение разметки Scala на операторе infix

a match { 
    case Nil => "An empty list" 
    case x :: Nil => "A list without a tail" 
    case x :: xs => "A list with a tail" 
} 

Как выражение матча позволено быть x :: xs, а не List(x, xs)?

ответ

13

Ответ Джей Конрада практически прав. Важно то, что где-то есть объект с именем ::, который реализует метод unapply, возвращающий тип Option[(A, List[A])]. Thusly:

object :: { 
    def unapply[A](ls: List[A]) = { 
    if (ls.empty) None 
    else Some((ls.head, ls.tail)) 
    } 
} 

// case objects get unapply for free 
case object Nil extends List[Nothing] 

В случае :: и List, этот объект происходит, чтобы выйти из того факта, что :: является случай класса, который расширяет List черту. Однако, как показывает вышеприведенный пример, имеет класс.

7

Я считаю :: is actually a class (что является подклассом Перечня), поэтому x :: xs в основном эквивалентен List(x, xs).

Вы можете сделать это с помощью других классов случаев, имеющих имена операторов. Например:

case class %%%(x: Int, y: Int) 

a match { 
    case x %%% y => x + y 
} 
2

Каким должно быть выражение соответствия x :: xs, а не List (x, xs)?

Для того, чтобы ответить на этот вопрос:

Когда рассматривается как шаблон, инфикс операции, такой как р д оп эквивалентно к оп (р, д). То есть оператор opix обрабатывается как шаблон конструктора.

(Программирование в Scala, 1-е изд., Стр. 331)

Смотрите также scala case classes questions