parsingrusttypesfunctional-programmingparser-combinators

How does one create a struct that holds a type parameterized function in Rust?


I am a beginner in Rust and am trying to create a Parser Combinator library in order to learn the ropes of the language. Very early on in this project I've gotten stuck. I want to have a Parser struct that holds the function used to parse data. Here is my attempt at implementing this.

struct Parser<I, O> {
    parse: impl Fn(&Vec<I>) -> Option<(&Vec<I>, O)>
}

Unfortunately, as the compiler informs me, i can not use the "impl Trait" notation in this way. Another way I've tried is by defining a separate type variable for the type of the function itself, as below.

struct Parser<I, O, F> 
where
    F: impl Fn(&Vec<I>) -> Option<(&Vec<I>, O)>
{
    parse: F
}

However, it seems redundant and unnecessary to have to provide the input, output, and function type, as the function type can be derived from the input and output. Also, the compiler gives me an error due to the fact that neither I or O are used.

I also considered Parser may have to be a trait rather than a struct. However I can't really wrap my head around what that would look like, and it seems like you would run into the same issue trying to define a struct that implemented the Parser trait.


Solution

  • Not a lot of context, but you I'll try doing it this way:

    struct Parser<I, O> {
        parse: Box<dyn Fn(&Vec<I>) -> Option<(&Vec<I>, O)>>,
    }
    
    fn main() {
        let parser = Parser {
            parse: Box::new(|x| {
                Some((x, x.iter().sum::<i32>()))
            })
        };
    
        let v = vec![1, 2, 3, 4];
        let result = (parser.parse)(&v).unwrap();
    
        println!("{:?}", result);
    }
    

    For some more suggestion I would look here: How do I store a closure in a struct in Rust?