I have a type (Series
) that hosts data of AnyValue
, an enum with a long list of types that include numeric, string and others (see polars crate if curious). I have a function that is "generic" over a subset of the AnyValue
variants, values that behave as numbers.
I created an enum type AnyNumber
. When I try to write a function that returns an impl Iterator
I get an error that seems to treat my values as types: "Expected struct UInt8Type, found struct UInt16 type"
fn numbers(input: &Series) -> Result<impl Iterator<Item = AnyNumber>> {
match input.dtype() {
DataType::UInt8 => Ok(input.u8()?.into_no_null_iter().map(AnyNumber::UInt8)),
DataType::UInt16 => Ok(input.u16()?.into_no_null_iter().map(AnyNumber::UInt16)),
DataType::UInt32 => Ok(input.u32()?.into_no_null_iter().map(AnyNumber::UInt32)),
...
DataType::Float64 => Ok(input.f64()?.into_no_null_iter().map(AnyNumber::Float64)),
_ => Err(eyre!(
"The underlying type is not a AnyNumber: {}",
input.dtype()
)),
}
}
The error:
error[E0308]: mismatched types
--> /Users/edmund/Programming-Local/tnc-analysis/lib/src/matrix.rs:216:36
|
216 | DataType::UInt16 => Ok(input.u16()?.into_no_null_iter().map(AnyNumber::UInt16)),
| -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `UInt8Type`, found struct `UInt16Type`
| |
| arguments to this enum variant are incorrect
::: /Users/edmund/Programming-Local/tnc-analysis/polars/polars/polars-core/src/chunked_array/mod.rs:478:10
|
478 | ) -> impl Iterator<Item = T::Native>
| __________-
479 | | + '_
480 | | + Send
481 | | + Sync
482 | | + ExactSizeIterator
483 | | + DoubleEndedIterator
484 | | + TrustedLen {
| | -
| | |
| |_______________________the expected opaque type
| the found opaque type
|
= note: expected struct `Map<impl Iterator<Item = ...> + Send + Sync + ExactSizeIterator + DoubleEndedIterator + TrustedLen + '_, ...>` (struct `UInt8Type`)
the full type name has been written to '/Users/edmund/Programming-Local/tnc-analysis/bin/target/release/deps/tnc_analysis_lib-a8155906914e5ad5.long-type-15334500443020542455.txt'
found struct `Map<impl Iterator<Item = ...> + Send + Sync + ExactSizeIterator + DoubleEndedIterator + TrustedLen + '_, ...>` (struct `UInt16Type`)
the full type name has been written to '/Users/edmund/Programming-Local/tnc-analysis/bin/target/release/deps/tnc_analysis_lib-a8155906914e5ad5.long-type-5313474775209893471.txt'
help: the type constructed contains `std::iter::Map<impl Iterator<Item = <UInt16Type as PolarsNumericType>::Native> + Send + Sync + ExactSizeIterator + DoubleEndedIterator + polars_arrow::trusted_len::TrustedLen + '_, fn(u16) -> AnyNumber {AnyNumber::UInt16}>` due to the type of the argument passed
--> /Users/edmund/Programming-Local/tnc-analysis/lib/src/matrix.rs:216:33
|
216 | DataType::UInt16 => Ok(input.u16()?.into_no_null_iter().map(AnyNumber::UInt16)),
| ^^^-------------------------------------------------------^
| |
| this argument influences the type of `Ok`
note: tuple variant defined here
--> /Users/edmund/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:507:5
|
507 | Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
| ^^
The into_no_null_iter()
has the following type signature:
pub fn into_no_null_iter(
&self
) -> impl Iterator<Item = <T as PolarsNumericType>::Native> + Send + Sync + ExactSizeIterator + DoubleEndedIterator + TrustedLen
Why might the compiler focus on a partial expression of the iterator i.e., ignoring the map expression that unifies the type? Is there a workaround other than using collect()
?
Thank you!