Creating a HashMap in Rust using the fold iterator method

I am trying to create a word count HashMap from an array of words using Entry and iterators in Rust. When I try as below,

use std::collections::HashMap;
fn main () {
    let corpus = ["foo", "bar", "bar", "grok", "blah", "foo", "bar"];
    let mut word_count = corpus.iter().fold(HashMap::new(), |mut acc, word| *acc.entry(word).or_insert(0) += 1);
    println!("{:?}", word_count);
}

I get the error: expected struct HashMap, found (), type mismatch.

I can get it to work by creating a new scope and explicitly returning the accumulator as:

use std::collections::HashMap;
fn main () {
    let corpus = ["foo", "bar", "bar", "grok", "blah", "foo", "bar"];
    let mut word_count = corpus.iter().fold(HashMap::new(), |mut acc, word|{
        *acc.entry(word).or_insert(0) += 1;
        acc
    });
    println!("{:?}", word_count);
}

and I get the expected {"foo": 2, "bar": 3, "blah": 1, "grok": 1}.

Usually fold returns the last state of the accumulator, so I was expecting the first approach to work, and am unclear why it does not. Would really appreciate some clarification and any suggestions on alternative approaches (using iterators).


Like explained in the comment from @PitaJ, *acc.entry(word).or_insert(0) += 1 has the type () while the compiler expects fold()'s callback to return the next state each time (it is sometimes called reduce() in other languages, e.g. JavaScript; in Rust; fold() allows you to specify the start value while reduce() takes it from the first item in the iterator).

Because of this, I feel like it is more appropriate use case for a loop, since you don't need to return a new state but to update the map:

let mut word_count = HashMap::new();
for word in &corpus {
    *word_count.entry(word).or_insert(0) += 1;
}

Playground.

However, if you want, there is a method in the itertools crate that does exactly that: counts():

let word_count = corpus.iter().counts();

Playground.