2015-02-04 2 views
1

Я должен найти, если элемент находится внутри списка, используя scala, и мне разрешено использовать рекурсию. Почему следующий код не работает, поскольку выражение соответствия мне кажется правильным. Моя IDE дает мне ошибку во всех трех случаях и говорит, что тип, mistmatch, boolean требуется.Почему это совпадение не разрешено в scala?

def isInN(x: Int, l: List[Int]): Boolean = (l,l.head) match { 
    case Nil,_ => false 
    case _,x => true 
    case _,_ => isInN (x,l.tail) 
} 

ответ

8

Вы соответствуете кортежу, поэтому вам нужно использовать правильный экстрактор кортежа. т.е. просто добавить скобки:

def isInN(x: Int, l: List[Int]): Boolean = (l, l.head) match { 
    case (Nil, _) => false 
    case (_, x) => true 
    case (_, _) => isInN (x, l.tail) 
} 

Это скомпилирует, но не будет работать так, как вы этого хотите. l.head выдаст исключение, если список пуст. И x в пределах match с нетерпением ожидают матча, так что последние case никогда не будут достигнуты. Чтобы соответствовать идентификатору, вам необходимо окружить его обратными окнами, иначе он будет просто совпадением заполнителя.

Чтобы использовать подобный поиск по шаблону, не вызывая l.head, вы можете шаблон матч на самом List:

def isInN(x: Int, l: List[Int]): Boolean = l match { 
    case Nil => false 
    case `x` :: _ => true 
    case head :: tail => isInN (x, tail) 
} 

Хотя это все аннулируют contains в стандартной коллекции библиотеки:

scala> List(1, 2, 3, 4).contains(2) 
res5: Boolean = true 
+0

You должен объяснить обратные кавычки, добавленные вами вокруг 'x' – Dimitri

+0

@ Dimitri, обратные кавычки там, поэтому' scalac' рассматривает его как 'x', который был указан как параметр, а не как новая переменная. – bb94

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