Класс типов Foldable , кажется, очень близок к тому, что вы хотите. У него есть метод collectFirst
со следующей подписью:
def collectFirst[A, B](fa: F[A])(pf: PartialFunction[A, B]): Option[B] =
и любопытная реализация:
foldRight(fa, Eval.now(Option.empty[B])) { (a, lb) =>
// trick from TraversableOnce,
// used to avoid calling both isDefined and apply (or calling lift)
val x = pf.applyOrElse(a, sentinel)
if (x.asInstanceOf[AnyRef] ne sentinel) Eval.now(Some(x.asInstanceOf[B]))
else lb
}.value
где sentinel
- странная маленькая функция, которая всегда возвращает себя:
private val sentinel: Function1[Any, Any] =
new scala.runtime.AbstractFunction1[Any, Any]{
def apply(a: Any) = this
}
Предполагается, что эти два последних фрагмента кода обеспечат некоторую мотивацию, чтобы не переопределять collectFirst
несколько раз.