I think what is wanted is a intersection type like this:
fn f(g : Fn(&File) -> () ∧ Fn(&Cursor) -> ())
The intersection of two functions is a single function that can accept either signature (it is like overloading) as opposed to a union type which would be either. The reason to prefer function intersections can be seen by considering the difference between the following:
fn f(g : Fn(File) -> File ∧ Fn(Cursor) -> Cursor) fn f(g : Fn(File ∨ Cursor) -> Fn(File ∨ Cursor))
The first guarantees to return the same type of object that you pass, the second does not. Note: they are intersections on types, not traits / type-classes, so ‘Fn’ would need to be a type not a trait. Intersection types do not work well with traits (type-classes) as they are both trying to control overload resolution. As Rust has taken the type-class route to control overloading, adding intersection types would not make sense to me. Higher-kinded-types work nicely with type-classes, so that is the way to go. Union types cause all sorts of problems and are generally unsafe, and Rust has disjoint-union types already (enums) which provide a save sort of union type.
HKT will provide monomorphisation, which you wanted, as does the solution I posted above where you pass the same function twice. Intersection of function types provides an alternative to HKT to do this, but I prefer HKT with traits/type-classes. Union types require (unsafe) runtime polymorphism which is the same as the runtime polymorphism provided by enums.