// this is defined in a trait
fn new(k: usize, basis: Vec<Product<B, BaseSign>>, coeffs: Vec<f32>) -> Result<Self> {
if k == 0 {
bail!("k cannot equal 0!")
}
// if any prod doesnt have k elements error
// if any two are the same error
}
A Product is simply:
struct Product<B, BaseSign>(Vec<B>, PhantomData<BaseSign>)
where
B: BasisVector,
BaseSign: Sign;
All that matters about it is that it is a Vec<B>
.
I am also using anyhow.
There are two requirements for the thing I am returning:
- All elements in
basis
must be unique. - All elements in basis must have
k
elements wherek
is a given value
It is decently easy to implement something like this with a for loop.
However, I want to do it functional-like. How would I do this in rust because every time I try I end up with a monstrosity because you can't return values from a closure.
Previous Attempt
(Doesn't work):
Summary
let result = basis
.iter()
.enumerate()
.map(|(i, prod)| {
Ok(if prod.0.len() != k {
Left(bail!("\n{prod:#?}\nmust be size: {k:?}!\n"))
} else if basis[i + 1..].contains(prod) {
Left(bail!(
"Basis must not contain two of the same element:\n{:?}",
prod
))
} else {
Right(())
})
})
.fold(
Right(()),
|acc: Either<Result<Self>, ()>, next: Either<Result<Self>, ()>| match acc {
Left(err) => acc,
Right(unit) => match next {
Left(err) => Left(err),
Right(_) => Right(()),
},
},
);
let phantom = PhantomData;
match result {
Left(err) => err,
Right(_) => Ok( Self { k, basis, coeffs, phantom })
}
My immediate thought process says
It's easy just
iter
thenmap
thenfold
!
But I don't think it's as easy as that.