```
dbg!(vec![1,2,3].iter().take(5).fold(0, |acc, x| acc + x)); // 6
```

@apublicimage that's exactly the thing I learned! I kinda low key expected for take() to take Iterator<...> and return Option<Iterator<...>>

@jonn @apublicimage The length of something implementing the Iterator trait isn't necessarily known. If it would return an Option, then it would have to do the whole iteration first. Rust's iterators are lazy.

@mo8it @apublicimage ah yes, silly me. But it would be possible if they were even lazier (see Control.Foldl[1] in Haskell).

Actually! Is there some API which allows you to build computation over iterators and then run it, reducing (pun intended) the constant factor in O(n)?

[1]: hackage.haskell.org/package/fo

@jonn @apublicimage What do you mean with building computation over iterators and then running it? This is how iterators work with their lazy nature. map for example doesn't run the computation until the result is required, for example when folding.

Follow

@mo8it @apublicimage ah, but see,

.fold(f).fold(g) won't fuse the folds!

Whereas the library I sent you uses standard combinators (like `ap` from Applicative in Haskell, not sure if there is some go-to combinator implementation in Rust) to fuse the folds!

Thus, when you run a code which builds a computation with Foldl, you get as a return value a computation! You can then run it *snaps fingers* again and [lazily] get the result.

Sign in to participate in the conversation
Doma Social

Mastodon server of https://doma.dev.