-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Description
It would seem easy to create a Thunk
from a multi-argument FnOnce
:
#![feature(default_type_params)]
use std::thunk::Thunk;
fn do_with_callback<F>(callback: F)
where F: FnOnce(int, int) + Send {
let th = Thunk::with_arg(callback);
th.invoke((2, 2));
}
fn main() {
do_with_callback(|x, y| {
println!("{}", x * y);
});
}
However, the compiler produces a puzzling error:
thunk-with-multi-args.rs:7:14: 7:29 error: the trait
core::ops::Fn(_) -> _
is not implemented for the typeF
The issue seems to occur due to use of the unary closure type syntax where generic parameters are needed, and not using .call_once
explicitly. I've managed to fix it thus:
#![feature(default_type_params)]
#![feature(unboxed_closures)]
pub struct Thunk<A=(),R=()> {
invoke: Box<Invoke<A,R>+Send>
}
impl<R> Thunk<(),R> {
pub fn new<F>(func: F) -> Thunk<(),R>
where F : FnOnce<(),R> + Send
{
Thunk::with_arg(func)
}
}
impl<A,R> Thunk<A,R> {
pub fn with_arg<F>(func: F) -> Thunk<A,R>
where F : FnOnce<A,R> + Send
{
Thunk {
invoke: box func
}
}
pub fn invoke(self, arg: A) -> R {
self.invoke.invoke(arg)
}
}
pub trait Invoke<A=(),R=()> {
fn invoke(self: Box<Self>, arg: A) -> R;
}
impl<A,R,F> Invoke<A,R> for F
where F : FnOnce<A,R>
{
fn invoke(self: Box<F>, arg: A) -> R {
let f = *self;
f.call_once(arg)
}
}
Note how the new
constructor is now redundant. Perhaps the specialized constructor should be dropped and Thunk::with_arg
should be renamed to Thunk::new
.
Metadata
Metadata
Assignees
Labels
No labels