Problems when using Generic Closus


#1

Hy, I wanted to write a library witch leverage some closure composition
but stumbled about some fundermental problems:

Cutting a complex Example Short:

 fn compose<IN,OUT,OLD,NEW>(func: OLD) -> NEW
    where OLD: Fn( IN ) -> OUT,
          NEW: Fn( IN ) -> OUT
{
    | data: IN | -> OUT {
        //DO SOME STUF
        func(data)
    }
}

fn main() {

    let nfunc = compose( | x: u32 | -> u32 {
        x * 2
    } );

    let res = (nfunc)( 12u32 );

    println!("{}", res);

}

This leads to 2 Errors:

  1. I cannot return the closure because the NEW type does not match the closure type (but It should)

  2. The compiler wants a explicit type for res but this is the full type of the closure created in compose so I can not write it down (but the compiler should be able to infer it based on the return type) this might be fixed if 1. is fixed

Does anyone has a Idea how to solve this (maybe bug). Note that in the
real code the closure closes over some data in a way witch makes it impossible
to return a function pointer or a struck containing some data and a function pointer.


#2

As written, the NEW parameter is generic, so the function would have to return a value of type NEW for any NEW matching the signature, specified by the caller. That doesn’t work. There is a post-1.0 proposal to allow returning unboxed closures (or any value implementing a trait, without specifying its exact type) with syntax like

fn compose<IN, OUT, OLD>(func: OLD) -> impl Fn(IN) -> OUT

but I don’t remember where it is. In the meantime, you can box your closures.


#3

Thanks for the swift reply :smile:

I already expected the problem to lie in the fact, that the type defined on
the outer function is specified inside the function. I just hoped, that
rust has some way to specify this somehow. I hope the RFC will land
soon post 1.0 it would be relay useful :+1:

EDIT:
Btw. the mentioned RFC is #105 referenced in this RFC#0114 but I can’t find it in the RFC repository.