In Rust, there is no type for functions, but rather an Fn trait that looks something like this:
trait Fn<A: Tuple, R> {
fn call(self, args: A) -> R;
}
Then the type of a function can be dyn Fn(A) -> R. This helps with compiler optimizations while still being pretty simple to understand.
In functional languages, we can similarly define an Fn type class:
class Fn s a b where
call : s -> a -> b
But, because there is no concept of Self in type classes, there is no dyn Fn type, which means you have to use generics for everything:
// in Rust 😊
fn run_with_2(f: &dyn Fn(i32) -> i32) -> i32 {
f.call(2)
}
struct SomeFnWrapper<A,B>(Box<dyn Fn(A) -> B>);
-- in Haskell 🤮
runWith2 : Callable f Int Int => f -> Int
runWith2 f = call f 2
-- creating `SomeFnWrapper` is impossible in Haskell
Is there a solution to this? Perhaps some clever use of forall I'm not aware of?
foo :: Xand usecall :: X -> Y -> Zwhen you could just passcall foo :: Y -> Zin the first place?