macro_rules! poly_fn {
(
[ $ ( $ tparams : tt ) , * ] | $ arg : ident : $ arg_typ : ty | -> $ ret_typ :
ty { $ body : expr } , $ ( $ rest : tt ) * ) => { ... };
(
[ $ ( $ tparams : tt , ) * ] | $ arg : ident : $ arg_typ : ty | -> $ ret_typ :
ty { $ body : expr } , $ ( $ rest : tt ) * ) => { ... };
(
| $ arg : ident : $ arg_typ : ty | -> $ ret_typ : ty { $ body : expr } , $ (
$ rest : tt ) * ) => { ... };
(
p ~ $ (
[ $ ( $ pars : tt , ) * ] | $ p_args : ident : $ p_arg_typ : ty | -> $
p_ret_typ : ty { $ p_body : expr } , ) * ~ p f ~ $ (
| $ f_args : ident : $ f_arg_typ : ty | -> $ f_ret_typ : ty { $ f_body : expr
} , ) * ~ f [ $ ( $ tparams : tt ) , * ] | $ arg : ident : $ arg_typ : ty | ->
$ ret_typ : ty { $ body : expr } , $ ( $ rest : tt ) * ) => { ... };
(
p ~ $ (
[ $ ( $ pars : tt , ) * ] | $ p_args : ident : $ p_arg_typ : ty | -> $
p_ret_typ : ty { $ p_body : expr } , ) * ~ p f ~ $ (
| $ f_args : ident : $ f_arg_typ : ty | -> $ f_ret_typ : ty { $ f_body : expr
} , ) * ~ f [ $ ( $ tparams : tt , ) * ] | $ arg : ident : $ arg_typ : ty | ->
$ ret_typ : ty { $ body : expr } , $ ( $ rest : tt ) * ) => { ... };
(
p ~ $ (
[ $ ( $ pars : tt , ) * ] | $ p_args : ident : $ p_arg_typ : ty | -> $
p_ret_typ : ty { $ p_body : expr } , ) * ~ p f ~ $ (
| $ f_args : ident : $ f_arg_typ : ty | -> $ f_ret_typ : ty { $ f_body : expr
} , ) * ~ f | $ arg : ident : $ arg_typ : ty | -> $ ret_typ : ty {
$ body : expr } , $ ( $ rest : tt ) * ) => { ... };
(
p ~ $ (
[ $ ( $ pars : tt , ) * ] | $ p_args : ident : $ p_arg_typ : ty | -> $
p_ret_typ : ty { $ p_body : expr } , ) * ~ p f ~ $ (
| $ f_args : ident : $ f_arg_typ : ty | -> $ f_ret_typ : ty { $ f_body : expr
} , ) * ~ f [ $ ( $ tparams : tt ) , * ] | $ arg : ident : $ arg_typ : ty | ->
$ ret_typ : ty { $ body : expr } ) => { ... };
(
p ~ $ (
[ $ ( $ pars : tt , ) * ] | $ p_args : ident : $ p_arg_typ : ty | -> $
p_ret_typ : ty { $ p_body : expr } , ) * ~ p f ~ $ (
| $ f_args : ident : $ f_arg_typ : ty | -> $ f_ret_typ : ty { $ f_body : expr
} , ) * ~ f [ $ ( $ tparams : tt , ) * ] | $ arg : ident : $ arg_typ : ty | ->
$ ret_typ : ty { $ body : expr } ) => { ... };
(
p ~ $ (
[ $ ( $ pars : tt ) * ] | $ p_args : ident : $ p_arg_typ : ty | -> $ p_ret_typ
: ty { $ p_body : expr } , ) * ~ p f ~ $ (
| $ f_args : ident : $ f_arg_typ : ty | -> $ f_ret_typ : ty { $ f_body : expr
} , ) * ~ f | $ arg : ident : $ arg_typ : ty | -> $ ret_typ : ty {
$ body : expr } ) => { ... };
(
p ~ $ (
[ $ ( $ pars : tt , ) * ] | $ p_args : ident : $ p_arg_typ : ty | -> $
p_ret_typ : ty { $ p_body : expr } , ) * ~ p f ~ $ (
| $ args : ident : $ arg_typ : ty | -> $ ret_typ : ty { $ body : expr } , ) *
~ f ) => { ... };
}
Returns a polymorphic function for use with mapping/folding heterogeneous
types.
This macro is intended for use with simple scenarios, and doesn't handle
trait implementation bounds or where clauses (it might in the future when
procedural macros land). If it doesn't work for you, simply implement
Func on your own.
type I32F32StrBool<'a> = Coprod!(i32, f32, &'a str);
let co1 = I32F32StrBool::inject("lollerskates");
let folded = co1.fold(poly_fn!(
['a] |x: &'a str| -> i8 { 1 },
|x: i32| -> i8 { 2 },
|f: f32| -> i8 { 3 },
));
assert_eq!(folded, 1);Run