Scala: "любые" и "все" функции
мой Haskell * немного ржавый, поэтому я могу представить, что Im пропустил очевидное:
def any[A](s: Traversable[A], f: A => Boolean): Boolean = {
s.foldLeft(false)((bool, elem) => bool || f(elem))
}
Применяется ли одно из этих свойств к нему?
- предопределено где-то в папке Scala
- косвенный и быстрее написанный как один однострочный
- неправильно (я его не тестировал, извините;))
* на самом деле SML, но это на 99% то же самое, но неизвестно никому под солнцем.
Ответы
Ответ 1
-
Он предопределен и называется exists
. И forall
будет функцией "все", которую вы ищете.
scala> Vector(3, 4, 5).exists(_ % 2 == 0)
res1: Boolean = true
scala> Vector(3, 4, 5).forall(_ % 2 == 0)
res2: Boolean = false
-
Вы можете сделать его более эффективным с помощью цикла for
с break
(от scala.util.control.Breaks
). (См. Стандартную реализацию библиотеки exists
и forall
.)
-
Правильно.
Ответ 2
Существуют методы Traversable, эквивалентные any
и all
:
def all[A](xs: Traversable[A], p: A => Boolean): Boolean = xs forall p
def any[A](xs: Traversable[A], p: A => Boolean): Boolean = xs exists p
Ответ 3
- Нет, это не связано с этими именами. Вы можете использовать
exists
из пакета Traversable.
-
Самый большой недостаток вашей реализации - это то, что необходимо будет потреблять все ваши траверсы, когда для any
, если они есть, это действительно так, если вы уже можете дать свой ответ. То же самое касается all
. Но можно легко реализовать это, чтобы он не оценивал всю последовательность. Другим решением было бы реализовать монаду для этого типа операции. Затем вы должны позвонить:
a and b and c
, что эквивалентно a.and(b).and(c)
-
Это правильно.
BTW, другая функция, которую я считаю отсутствующей, является функцией sum
.
Ответ 4
Как насчет exists
:
scala> List(1,2,3).exists(_ > 2)
res12: Boolean = true
На Traversable.