Categories
Tags
algorithms APIT arm assembly asynchronous base64 Blogging box c clang-format cmake compiler concurrency const_fn contravariant cos covariant cpp Customization cybersecurity DataStructure db Demo deserialization discrete doc DP Dynamic Example FFI flat_map FP Functional functions futures Fuwari GATs gccrs generics gitignore GUI hacking hashmap haskell heap interop invariant iterator justfile kernel LaTeX LFU linux MachineLearning Markdown math ML OnceLock optimization OS parallels perf physics pin postgresql release RPIT rust science Science serialization shift sin SmallProjects std String surrealdb swisstable synchronous tan traits triangulation utf16 utf8 Video x86_64 xilem zig
734 words
4 minutes
260108_traits_flat_map_iterator
link
flat_map자세히 이해하기|🔝|
let cartesian: Vec<(i32, i32)> = (1..=3)
.flat_map(|x| (10..=12)
.map(move |y| (x, y)))
.collect();
println!("{cartesian:?}");Line-by-Line Explanation|🔝|
let cartesian: Vec<(i32, i32)> =Declares a variable named cartesian
Its type is a vector of tuples:
Vec<(i32, i32)>Outer Range Iterator|🔝|
(1..=3)std::ops::RangeInclusive<i32>flat_map|🔝|
.flat_map(|x| ...)What flat_map does|🔝|
- Takes each element x
- Maps it to another iterator
- Flattens all produced iterators into one sequence
- 각 요소 x를 취합니다
- 다른 반복기에 매핑합니다
- 플랫텐은 모두 하나의 시퀀스로 생성된 반복자입니다
Signature (simplified):|🔝|
fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where
Self: FnMut(Self::Item) -> I,
U: IntoIterator
F: FnMut(Self::Item) -> U,Key idea:|🔝|
map→ nested iterators(중첩 반복자)flat_map→ single flattened iterator(단일 평탄 반복기)
Inner map|🔝|
.map(move |y| (x, y))(1,10), (1,11), (1,12)- What happens here:
- For each
x, we map overy - For each
y, we produce a tuple(x, y)- 각
x에 대해y위에 매핑합니다 - 각
y에 대해 튜플(x, y)를 생성합니다
- 각
- For each
Why move Is Needed|🔝|
- 오너쉽 문제 때문 ㅠㅠ
move |y| (x, y)xcomes from the outer closureThe inner closure may outlive the outer closure
move copies
xinto the inner closure- ‘x’는 외부 폐쇄에서 나옵니다
- 내부 폐쇄는 외부 폐쇄보다 오래 지속될 수 있습니다
- 복사본 ‘x’를 내부 클로저로 이동합니다.
Since
i32isCopy, this is:- Zero cost
- Required by the borrow checker
Without move ❌:|🔝|
borrowed value does not live long enoughFlattening in Action
- Each
xproduces an iterator:
| x | produced iterator |
|---|---|
| 1 | (1,10),(1,11),(1,12) |
| 2 | (2,10),(2,11),(2,12) |
| 3 | (3,10),(3,11),(3,12) |
마무리는 collect()|🔝|
.collect();Consumes the iterator
Allocates a
Vec<(i32, i32)>Stores all produced values
- 반복기를 소모합니다
Vec<(i32, i32)>를 할당합니다- 생산된 모든 가치를 저장합니다
Type inference uses:
Vec<(i32, i32)>🧠 Mental Model원조는 역시 하스켈 코드이다.ㅋ|🔝|
- Equivalent Haskell Code
- 역시 원조는 하스켈 코드
[(x, y) | x <- [1..3], y <- [10..12]]- Rust Iterator Pipeline
- 마무리
(1..=3)
.flat_map(|x|
(10..=12).map(move |y| (x, y))
)🧩 Why This Is Powerful|🔝|
- Zero intermediate allocations
- Lazy evaluation
- Compile-time checked
- Parallelizable
- Equivalent to nested loops, but functional
🧩 이것이 강력한 이유|🔝|
- 중간 할당 없음
- 게으른 평가
- 컴파일 시간 확인
- 병렬화 가능
- 중첩 루프와 동등하지만 기능적
✅ Rewritten Using fold|🔝|
fn main() {
let cartesian: Vec<(i32, i32)> = (1..=3)
.fold(Vec::new(), |mut acc, x| {
for y in 10..=12 {
acc.push((x, y));
}
acc
});
println!("{cartesian:?}");
}비슷한 글|🔝|

Haskell로 코드를 바꿔보자.|🔝|
- 🐦 Equivalent Haskell Code
- ✅ Most Direct (List Comprehension)
[(x, y) | x <- [1..3], y <- [10..12]]This is the closest semantic equivalent.
✅ Explicit concatMap Version (matches flat_map)
concatMap (\x -> map (\y -> (x, y)) [10..12]) [1..3]main :: IO ()
main = do
let result = concatMap (\x -> map (\y -> (x, y)) [10..12]) [1..3]
print result- ✅ Fully Desugared Functional Version
foldr (\x acc -> map (\y -> (x, y)) [10..12] ++ acc) [] [1..3]main :: IO ()
main = do
let result = foldr (\x acc -> map (\y -> (x, y)) [10..12] ++ acc) [] [1..3]
print result🔍 Line-by-Line Correspondence|🔝|
| Rust | Haskell |
|---|---|
| (1..=3) | [1..3] |
flat_map | concatMap |
map | map |
move | implicit closure capture |
(x, y) | (x, y) |
| iterator | list |
🧠 Conceptual Mapping|🔝|
Rust
- Iterators are lazy
flat_mapproduces an iterator of iterators and flattens them- move explicitly captures
x- 반복자는 게으릅니다
flat_map은 반복자의 반복자를 생성하여 평평하게 만듭니다- 이동은
x를 명시적으로 캡처합니다
Haskell
- Lists are lazy by default
- concatMap does exactly what flat_map does
- Closures capture automatically
- 목록은 기본적으로 게으릅니다
- concatMap은 flat_map이 하는 일을 정확히 수행합니다
- 폐쇄는 자동으로 캡처됩니다
260108_traits_flat_map_iterator
https://younghakim7.github.io/blog/posts/260108_traits_flat_map_iterator/