#[macro_export] macro_rules! map {
($f:expr) => {
move |it| map($f, it)
};
}
#[macro_export] macro_rules! sum {
($i:expr;$j:expr) => {{
sum($i..=$j)
}};
($i:expr,$($j:expr),*) => {
$i + sum!($($j),*)
};
($i:expr) => {
$i
};
}
#[macro_export] macro_rules! pipe {
($($f:expr),*) => {
|v| {pipe!(@NEXT v, $($f),*) }
};
(@NEXT $v:expr,$f:expr,$($rest:expr),*) => {
pipe!(@NEXT $f($v), $($rest),*)
};
(@NEXT $v:expr,$last:expr) => {
$last($v)
};
}
#[macro_export] macro_rules! ls {
($it:expr) => {
ls![|x| x;$it=>|_|true]
};
($mapper:expr;$it:expr) => {
ls![$mapper;$it=>|_| true]
};
($it:expr=>$filterer:expr) => {
ls![|x| x;$it=>$filterer]
};
($mapper:expr;$it:expr=>$filterer:expr) => {{
let mut ret = Vec::new();
for i in $it {
if $filterer(i) {
ret.push($mapper(i));
}
}
ret
}};
}
#[macro_export] macro_rules! foldl {
($init:expr,$f:expr) => {
move |it| foldl($init,$f,it)
};
($init:expr) => {
move |f,it| foldl($init,f,it)
};
($init:expr=>) => {
move |f| (move |it| foldl($init,f,it))
};
}
#[macro_export] macro_rules! foldr {
($init:expr,$f:expr) => {
move |it| foldr($init,$f,it)
};
($init:expr) => {
move |f,it| foldr($init,f,it)
};
($init:expr=>) => {
move |f| (move |it| foldr($init,f,it))
};
}
#[macro_export] macro_rules! filter {
($f:expr) => {
move |it| filter($f, it)
};
}
#[macro_export] macro_rules! filter_not {
($f:expr) => {
move |it| filter_not($f, it)
};
}
#[macro_export] macro_rules! compose {
($f:expr,$($fs:expr),*) => {
compose!(@NEXT [$f],$($fs),*)
};
(@NEXT [$($fs:expr),*],$f:expr,$($remain_fs:expr),*) => {
compose!(@NEXT [$f,$($fs),*],$($remain_fs),*)
};
(@NEXT [$($fs:expr),*],$f:expr) => {
pipe!($f,$($fs),*)
};
}
#[macro_export] macro_rules! skip {
($n:expr) => {
move |it| skip($n, it)
};
}
#[macro_export] macro_rules! take {
($n:expr) => {
move |it| take($n, it)
};
}
#[macro_export] macro_rules! product {
($i:expr;$j:expr) => {{
product($i..=$j)
}};
($i:expr,$($j:expr),*) => {{
$i * product!($($j),*)
}};
($i:expr) => {
$i
};
}
#[macro_export] macro_rules! concat {
($($it:expr);*) => {{
let mut ret = Vec::new();
$(ret.extend($it););*
ret
}};
}
#[macro_export] macro_rules! fst {
(>$($t:ty),*) => {move |x: ($($t),*)| x.0};
($x:expr) => {{$x.0}};
($x:pat) => {{$x.0}};
}
#[macro_export] macro_rules! snd {
(>$($t:ty),*) => {move |x: ($($t),*)| x.1};
($x:expr) => {{$x.1}};
($x:pat) => {{$x.1}};
}
#[macro_export] macro_rules! rem {
($x:expr,$y:expr) => {{rem($x, $y)}};
($x:expr) => {move |y| rem($x, y)};
}
#[macro_export] macro_rules! abs {
(>$t:ty) => {move |x: $t| x.abs()};
($x:expr) => {{$x.abs()}};
}
#[macro_export] macro_rules! signum {
(>$t:ty) => {move |x: $t| x.signum()};
($x:expr) => {{$x.signum()}};
}
#[macro_export] macro_rules! even {
(>$t:ty) => {move |x: $t| x % 2 == 0};
($x:expr) => {{$x % 2 == 0}};
}
#[macro_export] macro_rules! odd {
(>$t:ty) => {move |x: $t| x % 2 == 1};
($x:expr) => {{$x % 2 == 1}};
}
#[macro_export] macro_rules! recip {
(>$t:ty) => {move |x: $t| 1/$t};
($x:expr) => {{1/$x}};
}
#[macro_export] macro_rules! always {
($x:expr,$y:expr) => {{$x}};
($x:expr) => {move |_| $x};
() => {move |x,_| x};
(=>) => {move |x| (move |_| x)};
}
#[macro_export] macro_rules! add {
($x:expr) => {move |y| $x + y};
($x:expr,$y:expr) => {{$x + $y}};
}
#[macro_export] macro_rules! sub {
($x:expr) => {move |y| $x - y};
($x:expr,$y:expr) => {{$x - $y}};
}
#[macro_export] macro_rules! mul {
($x:expr) => {move |y| $x * y};
($x:expr,$y:expr) => {{$x * $y}};
}
#[macro_export] macro_rules! div {
($x:expr) => {move |y| $x / y};
($x:expr,$y:expr) => {{$x / $y}};
}
#[macro_export] macro_rules! find {
($k:expr) => {move |it| find($k,it)};
($k:expr,$it:expr) => {{find($k,$it)}};
}
#[macro_export] macro_rules! sorted_by {
($f:expr) => {move |it| sorted_by($f, it)};
}
#[macro_export] macro_rules! zip {
($it:expr) => {move |it| zip($it, it)};
}
#[macro_export] macro_rules! zip_with {
($f:expr) => {move |it1, it2| zip_with($f, it1, it2)};
($f:expr=>) => {move |it1| (move |it2| zip_with($f, it1, it2))};
($f:expr,$it:expr) => {move |it| zip_with($f, $it, it)};
}