Почему предикат не возвращает логическое значение? - PullRequest
0 голосов
/ 02 сентября 2018

Я пытаюсь выполнить очень простое упражнение - функция фильтра:

def filter[A](x: List[A], f: A => Boolean): List[A] = {
 for(item <- x){
  if(f(item))
   yield item
  }
 }

Но он не компилируется, кажется, что f (item) возвращает что-то отличное от Boolean, но я не могу понять, почему. Чтобы проверить это, я попытался сделать это:

 var b = Boolean
 b = f(item)

После этого я получил ошибку "выражение типа Boolean не соответствует ожидаемому типу Boolean.type". Но я не понимаю этого объяснения.

Не могли бы вы помочь понять, что здесь не так? Функция называется так:

 val list = 1 :: 2 :: 3 :: 4:: 5 :: 6 :: Nil
 val list2 = filter[Int](list, _ % 2 == 0)

Ответы [ 3 ]

0 голосов
/ 02 сентября 2018

Вы, вероятно, знаете, что вы можете просто использовать filter метод List напрямую:

def filter[A](x: List[A], f: A => Boolean): List[A] = x.filter(f)

Но если вы хотите реализовать свой filter метод, используя для понимания, вы можете сделать это следующим образом

def filter[A](x: List[A], f: A => Boolean): List[A] = {
  for {
    item <- x
    if (f(item))
  } yield item
}   
0 голосов
/ 02 сентября 2018

В соответствии с языковой спецификацией предложение yield для понимания не может быть внутри составного выражения, например внутри пары скобок. Это должно быть крайнее слово возвращаемого выражения для понимания.

Как объясняет Тим, ваш if также должен быть в определенном месте, чтобы действовать как фильтр. В этой позиции это называется охранное предложение (обратитесь к спецификации, чтобы увидеть точный синтаксис).

0 голосов
/ 02 сентября 2018

Предикат возвращает Boolean, но синтаксис вашего цикла for неверен. Должно быть так:

def filter[A](x: List[A], f: A => Boolean): List[A] =
  for (item <- x if f(item)) yield item

Но это еще лучше:

def filter[A](x: List[A], f: A => Boolean): List[A] =
  x.filter(f)
...