Написание вариативного метода предикатов Scala

#scala #variadic

Вопрос:

У меня есть следующий пример:

 val check30 = allTrue(x:Int => x%2 == 0, x:Int => x%3 == 0, x:Int => x%5== 0)
val check30(60) //evaluates to true 
 

Я хочу написать метод предикатов allTrue , который берет несколько предикатов, как в примере, и объединяет их с помощью foldRight .

Я попробовал что-то вроде этого:

 def allTrue[T](pred: T =>Boolean*): Boolean =
    pred.foldRight(true)(_ amp;amp; _)
 

Однако это не работает.

Как я могу сделать это правильно?

Ответ №1:

Ваша проблема в том, что вы не передали значение, которое хотите проверить. Вы можете сделать:

 def allTrue[T](pred: T => Boolean*)(value: T): Boolean =
  pred.forall(p => p(value))
 

Затем, чтобы использовать его:

 val check30 = allTrue[Int](_ % 2 == 0, _ % 3 == 0, _ % 5 == 0)(_)
val result = check30(60) //evaluates to true
println(result)
 

Используя foldRight вы можете сделать:

 def allTrue[T](pred: T => Boolean*)(value: T): Boolean =
  pred.foldRight(true)((p, b) => b amp;amp; p(value))
 

Код, запущенный в Scastie.

Комментарии:

1. Спасибо за ваш ответ. Очень полезно! Но я хочу сделать это с Фолдрайтом…

2. @gython С чего бы тебе захотелось это сделать foldRight ? forall останавливается при первом ложном условии, что повышает производительность.

3. вы абсолютно правы! Однако я хочу попрактиковаться в использовании foldRight и. foldLeft