The syntax for a function that takes no parameters and returns nothing is f: fn().
To be more general and support closures that capture values, you would use one of the Fn, FnMut, or FnOnce traits. You want to use the most flexible one that still works how you will be calling it, which would be FnMut here. So that parameter would now be f: impl FnMut().
You're actually trying to map, where the function takes a parameter and returns a value, so that would be more like f: impl FnMut(T) -> T.
Your result function needs to declare T as a type parameter, and add constraints for all the things you're trying to do with it. Apart from the map call, you're also creating a 0 and adding values. So the most direct translation I can make of your code is:
extern crate num;
use num::Zero;
use std::ops::{Add, Range};
fn result<T>(r: Range<T>, mut f: impl FnMut(T) -> T) -> T
where
T: Zero + Add<Output = T>,
Range<T>: Iterator<Item = T>,
{
r.map(|n| f(n)).fold(T::zero(), |acc, ele| acc + ele)
}
You can do this without the num crate if you use the Sum trait instead of the manual fold. The call to map can also be simplified in this case, so I'd write it like this:
use std::iter::Sum;
use std::ops::Range;
fn result<T: Sum>(r: Range<T>, f: impl FnMut(T) -> T) -> T
where
Range<T>: Iterator<Item = T>,
{
r.map(f).sum()
}
You're basically creating a processing pipeline here, starting with items of type T and ending in R. f is your mapping function - it translates (maps) each T to R, and then you run the sum over all the resulting Rs. Does that help/make sense? Or did I miss the thrust of your question?
By default, Sum takes the same type as an input, but it can be parameterized too. So you could be a little more generic like:
fn result<I: Iterator, T, R: Sum<T>>(r: I, f: impl FnMut(I::Item) -> T) -> R {
r.map(f).sum()
}
So we have I::Item mapped to T and summed as R.
The primitive types in the standard library only implement Sum<Self> and Sum<&Self>, but other types can do more. For instance, num-bigint's types can Sum any integer input.
result = (1..6).sum(|n| 6*n+2)
f = |n| 6*n+2
result = (1..6).map(f).reduce(0,|x,y| x+y)
result = (1..).map(|n| 6*n+2).take(6).sum()
result = (6*n+2 for n in 1..6).sum()
result = (6*n+2 for n in 1..).take(6).sum()
As a general function:
result = |r,f,zero=0| r.map(f).reduce(zero,|x,y| x+y)
Moss is already oxidated. And soon it might be moisted too.
Then nothing will prevent me from feeding the dragon, disgracing everybody down to earth.
But feeding dragons before you need to is already flawed. It takes an amount of time before they come out of their dark holes.