2

Looking at the predicates like skip_while and take_while they're

skip_while<P>(self, predicate P) -> ...
  where Self: Sized, P: FnMut(&Self::Item) -> bool;

If a predicate is just returning true or false, and not modifying the values, why does it have to be FnMut and not Fn (like Fn(&Self::Item) -> bool)?

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
  • so you can have a state in your closure. FnMut mean it's allowed to mutate its state https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3fcda31e3bbe2fa974adaf92cd8d323b. as doc said "Use FnMut as a bound when you want to accept a parameter of function-like type and need to call it repeatedly, while allowing it to mutate state. If you don't want the parameter to mutate state, use Fn as a bound; if you don't need to call it repeatedly, use FnOnce." https://doc.rust-lang.org/std/ops/trait.FnMut.html – Stargateur Oct 19 '19 at 16:12

1 Answers1

3

The Mut in FnMut means that the predicate can have a mutable state. It says nothing about the parameters.

Additionaly, FnMut is a super-trait of Fn, so you can also pass an Fn where FnMut is accepted.

As a silly example, consider this closure that stores a state (hence is FnMut, but not Fn), but cannot modify the elements in the iterator:

fn main() {
    let v = vec![1, 2, 3, 4, 0, 5, 6, 7];

    println!("{:?}", v.iter().skip_while(|&&v| v != 0).collect::<Vec<_>>());

    let mut state = false;
    let one_after_zero = |&&v: &&u32| {
        if state {
            false
        } else if v == 0 {
            state = true;
            true
        } else {
            true
        }
    };

    println!("{:?}", v.iter().skip_while(one_after_zero).collect::<Vec<_>>());
}

(Permalink to the playground)

Output:

[0, 5, 6, 7]
[5, 6, 7]
mcarton
  • 27,633
  • 5
  • 85
  • 95
  • I guess that makes sense. I've never seen "predicate" refer to anything that had state. I guess it's just a definition but [it seems like a "predicate" here is any call back that returns a boolean, which seems to be the definition (according to stackoverflow)](https://stackoverflow.com/questions/1344015/what-is-a-predicate) I wonder if `scan` is ever needed? Could you write something about how a predicate w/ state ties into scan? – Evan Carroll Oct 19 '19 at 16:29