, 나는이 작업을 수행 할 수 있습니다반복자의 반복자로부터 카티 전 곱을 생성하는 함수를 만드는 방법은 무엇입니까? 나는 하스켈에서리스트의리스트의 직교 제품을 만들려면
product [] = [[]]
product (xs:xss) = concatMap (\k -> map (k:) (product1 xss)) xs
또는이 :
sequence xss
을 나는 효율적인 반복자를 구현하기 위해 노력하고있어 그 녹에 동일한 기능을 수행 할 것입니다,하지만 난 내 시도에 어떤 문제가 있는지 확실하지 않다 :
use std::iter::{empty, once};
fn product<T, I, V>(xss: I) -> Box<Iterator<Item = Iterator<Item = T>>>
where
T: Clone,
V: IntoIterator<Item = T>,
I: IntoIterator<Item = V>,
{
Box::new(xss.into_iter().fold(once(empty()), |acc, xs| {
xs.into_iter().flat_map(|x| acc.map(|ys| ys.chain(once(x))))
}))
}
fn main() {
let data = vec![[1, 2, 3], [10, 20, 30], [100, 200, 300]];
let it: Vec<Vec<u32>> = product(data).collect();
println!("{:?}", it);
}
이러한 오류를 생성합니다 :
error[E0308]: mismatched types
--> src/main.rs:10:9
|
10 | xs.into_iter().flat_map(|x| acc.map(|ys| ys.chain(once(x))))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::iter::Once`, found struct `std::iter::FlatMap`
|
= note: expected type `std::iter::Once<std::iter::Empty<T>>`
found type `std::iter::FlatMap<<V as std::iter::IntoIterator>::IntoIter, std::iter::Map<std::iter::Once<std::iter::Empty<T>>, [[email protected]/main.rs:10:45: 10:67 x:_]>, [[email protected]/main.rs:10:33: 10:68 acc:_]>`
error[E0271]: type mismatch resolving `<std::iter::Once<std::iter::Empty<T>> as std::iter::Iterator>::Item == std::iter::Iterator<Item=T>`
--> src/main.rs:9:5
|
9 |/ Box::new(xss.into_iter().fold(once(empty()), |acc, xs| {
10 | | xs.into_iter().flat_map(|x| acc.map(|ys| ys.chain(once(x))))
11 | | }))
| |_______^ expected struct `std::iter::Empty`, found trait std::iter::Iterator
|
= note: expected type `std::iter::Empty<T>`
found type `std::iter::Iterator<Item=T>`
= note: required for the cast to the object type `std::iter::Iterator<Item=std::iter::Iterator<Item=T>>`
error[E0277]: the trait bound `[{integer}; 3]: std::iter::Iterator` is not satisfied
--> src/main.rs:16:29
|
16 | let it: Vec<Vec<u32>> = product(data).collect();
| ^^^^^^^ `[{integer}; 3]` is not an iterator; maybe try calling `.iter()` or a similar method
|
= help: the trait `std::iter::Iterator` is not implemented for `[{integer}; 3]`
= note: required because of the requirements on the impl of `std::iter::IntoIterator` for `[{integer}; 3]`
= note: required by `product`
error: the `collect` method cannot be invoked on a trait object
--> src/main.rs:16:43
|
16 | let it: Vec<Vec<u32>> = product(data).collect();
| ^^^^^^^
첫 번째 오류가 나에게
Empty<T>
는
Iterator<Item = T>
(적어도 개념적으로)이기 때문에 녹 심지어
fold
와 느리게 소비 반복자를 만들 수 있다는 느낌을주고있다
,하지만 난 희망 잘못된.
Boxed iterator는 느리게 평가 된 Haskell 변수를 대체 할 수 없으므로 되감기 나 복제가 불가능하므로 직접 변환이 작동하지 않습니다. 박스형 체인의 체인으로리스트를 표현하는 것도 효율적이지 않습니다. – red75prime
@ red75prime 좋아요, 그럼 어떻게 일반적이고 기능적인 스타일로 할 수 있습니까? – user1685095
당신은 녹을 쓰고 있지만 하스켈을 생각하면 잘못 될 것입니다. 녹 구현이 어떻게 생겼는지 보려면 [this] (http://killercup.github.io/vibrant-rs/itertools/struct.Product.html)을보십시오. – papagaga