I think the accumulator soFar becomes False and then the expression soFar && isOkay element never evaluates the isOkay element bit sionce && short circuits. But it will still loop over the entire array, all the way to the end.
You could experiement by changing the all code to:
all : (element -> Bool) -> (Array element -> Bool)
all isOkay =
(\element soFar -> isOkay element && soFar)
This makes perfekt sense. The && operator short circuits but not the foldl itself.
I got curious in the first place, since folds usually have not way of short circuiting. But, since I only introduced log messages in the ìsOkay function I wrongly got the impression of the whole Array.Extra.all short circuiting.
Turns out this has already been tested and evaluated by the Array.Extra developers. Since arrays in Elm are implemented using som kind of trees (for sharing of immutable data) array look up in Elm is not O(1). Read more here.
You can always write a version of fold that has an optional break in it:
type Next a = Cont a | Break a
foldl : (a -> b -> Next b) -> b -> List a -> b
foldl fn acc vals =
case vals of
 -> acc
v :: vs ->
case fn v ac of
Cont newAcc -> foldl fn newAcc vs
Break newAcc -> newAcc
With Arrays I iterated over a slice using Array.get:
This was used to implement a GapBuffer for a text editor. I certainly found that doing it this way was efficient enough to get a UI that scrolled smoothly. But yes, the Array.get access is O(Log n), so not as fast as it could be: