use crate::box_iter::box_once;
use crate::{Bind, Cv, DataT, Exn, Native, PathsPtr, RunPtr, ValR, ValXs};
use alloc::boxed::Box;
pub type Filter<F> = (&'static str, Box<[Bind]>, F);
pub type Fun<D> = Filter<Native<D>>;
pub fn run<D: DataT>((name, arity, run): Filter<RunPtr<D>>) -> Fun<D> {
(name, arity, Native::new(run))
}
pub(crate) type RunPathsPtr<D> = (RunPtr<D>, PathsPtr<D>);
pub(crate) fn paths<D: DataT>((name, arity, (run, paths)): Filter<RunPathsPtr<D>>) -> Fun<D> {
(name, arity, Native::new(run).with_paths(paths))
}
pub fn v(n: usize) -> Box<[Bind]> {
core::iter::repeat(Bind::Var(())).take(n).collect()
}
pub fn bome<'a, V: 'a>(r: ValR<V>) -> ValXs<'a, V> {
box_once(r.map_err(Exn::from))
}
pub fn unary<'a, D: DataT>(
mut cv: Cv<'a, D>,
f: impl Fn(D::V<'a>, D::V<'a>) -> ValR<D::V<'a>> + 'a,
) -> ValXs<'a, D::V<'a>> {
bome(f(cv.1, cv.0.pop_var()))
}