2

Suppose you have a value val list: List[Date]. You would like to know if any one of the dates in this list occur after some startDate. You could do this

  list.fold(false)((a, b) => startDate.compareTo(b) < 0 || a)

which would return true if any date occurred on or after startDate thus achieving our objective.

However, since this is an OR statement being used, if even only one date satisfies the condition startDate.compareTo(b) < 0, then the whole fold operation will return true. Does Scala have a way of terminating execution of the fold and just returning the true when it hits it?

suleydaman
  • 463
  • 1
  • 7
  • 18

2 Answers2

4

However, since this is an OR statement being used, if even only one date satisfies the condition startDate.compareTo(b) < 0, then the whole fold operation will return true.

Actually, not necessarily; startDate.compareTo(b) < 0 could throw an exception. You'd need to change the order of operands to (a, b) => a || startDate.compareTo(b) < 0; even then it would be correct for a List, but not e.g. a Stream.

At any rate, as far as I know the answer is no even for the cases where it's correct. fold can't see inside the function it receives, only call it, so it would require specific support for this case in the compiler.

See also: Abort early in a fold and https://users.scala-lang.org/t/breaking-out-of-a-map-or-other-iteration/1091.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
4

This sounds like a usecase for exists.

list.exists(a => startDate.compareTo(a) < 0)

https://www.scala-lang.org/api/current/scala/collection/immutable/List.html#exists(p:A=%3EBoolean):Boolean

senjin.hajrulahovic
  • 2,961
  • 2
  • 17
  • 32