Option.fold - why is its second argument not a binary operator?

I am sure that there is a good reason for this, but I do not see it.

Fold on (say) List returns

the result of applying the bend operator op between all elements and z

It has an obvious connection with foldLeft and foldRight , which do the same, but with a specific order (and therefore no associative operators are needed)

Fold on Option returns

Returns the result of applying f to this scala.Option value if scala.Option is scala.Option empty. Otherwise, the ifEmpty expression is ifEmpty .

ifEmpty (at position) z for the list. f (in position) op

For None (which, using my mental model Option as a “container”, which may or may not contain a value, is an “empty” container), everything is fine, Option.fold returns zero ( ifEmpty value).

For Some(x) , however, f should not take two parameters z and x so that it matches the Fold sequences (including a similar relationship with foldLeft and foldRight ).

There is definitely a utility argument - having f , just take x as a parameter in practice, probably more convenient. In most cases, if he also took z , which would be ignored. But consistency is also important ...

So can someone explain to me why Fold on Option is still the “right” Fold ?

+5
source share
2 answers

Why should it be?

The reason for "normal" is a binary operator, because "usually" is used over a list that can be processed one by one using binary operators (and an initial value of z).

Discarding by option is a de facto function of the card with a standard case. If you look at its definition, it is literal:

 if (isEmpty) ifEmpty else f(this.get) 

Since you have only one possible argument, f must be a unary operator. It can be argued that there is a fold option that takes a binary operator and uses the ifEmpty value as a seed if the parameter is defined, but your reasonable initial value and your reasonable value when the option is empty can be very different.

As someone pointed out, for different structures you need different types (for example, for trees), because the “reasonable” application of reduction has different structures.

+2
source

scala.Option.fold - error; poor API design.

 Option { // This is equivalent to: map f getOrElse ifEmpty. def fold[B](ifEmpty: => B)(f: A => B): B = if (isEmpty) ifEmpty else f(this.get) } 

The Option.fold method may be convenient, but it does not matter fold (similarly to Either.fold ).

 TraversableOnce { // List, et alia def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op) } 

The advantages of the standard method are that the concept and type signature are consistent (there is no need to view documents again).

Alternatively, Option.foldLeft consistent and accepts a binary operator.

0
source

Source: https://habr.com/ru/post/1204918/


All Articles