You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On one hand, flat_map is very useful. On the other hand, scan is very useful. What if we combined both?
I was trying to write a simple FSM, so I tried this ugly abomination (which doesn't work, it just loops):
enumShittyFSM{Default,Escape,End,}pubfnparse(pattern:&[u8]){let parsed:Vec<_> = pattern.iter().scan(Some(ShittyFSM::Default), |state,&x| {loop{let r = match state.take().unwrap(){ShittyFSM::Default => {if x == b'%'{(ShittyFSM::Escape,None)}else{(ShittyFSM::Default,Some(x))}},ShittyFSM::Escape => {match x {
_ => {(ShittyFSM::Default,Some(x))}}},ShittyFSM::End => {returnNone;}};let(newstate, potential_return) = r;*state = Some(newstate);ifletSome(ret) = potential_return {returnSome(ret);}}}).collect();println!("{:?}", parsed);}fnmain(){parse(b"Hello, %world!");}
Then I noticed it doesn't work. So I had to change it up:
enumShittyFSM{Default,Escape,}pubfnparse(pattern:&[u8]){let parsed:Vec<_> = pattern.iter().scan(Some(ShittyFSM::Default), |state,&x| {let r = match state.take().unwrap(){ShittyFSM::Default => {if x == b'%'{(ShittyFSM::Escape,None)}else{(ShittyFSM::Default,Some(x))}},ShittyFSM::Escape => {match x {
_ => {(ShittyFSM::Default,Some(x))}}},};let(newstate, potential_return) = r;*state = Some(newstate);Some(potential_return)}).flat_map(|x| x).collect();println!("{:?}", parsed);}fnmain(){parse(b"Hello, %world!");}
This works, looks just as ugly, and has a .flat_map(|x| x). But hey, this is a FSM! But hey, since this is a FSM, this could be useful for others! But hey, what can we do to improve this?
Well, we could remove the .flat_map(|x| x), for one.
So I propose scan_flat. It scans the iterator flat.
fn scan_flat<St, U, F>(self, initial_state: St, f: F) -> ScanFlat<Self, St, U, F>
where F: FnMut(&mut St, Self::Item) -> U, U: IntoIterator
(it could probably just return a FlatMap and be an alias for .scan(...).flat_map(|x| x), but idk.)
In a perfect world I'd be able to return a function pointer for the next state (fn default_case(key: u8) -> whatever { if key == b'%' { (*escape_case, None) } else { (*default_case, Some(key)) } }), but this is fine.
The text was updated successfully, but these errors were encountered:
Centril
added
the
T-libs-api
Relevant to the library API team, which will review and decide on the RFC.
label
Dec 6, 2017
.flatten() is now available in the nightly compiler.
Closing this since I don't think this requires an RFC. If you want to add this operation to Iterator, please file a PR to rust-lang/rust if you have an implementation or file an issue over there if you don't and want to hear from the library team. My gut feeling is that .scan(..).flatten() is sufficient tho.
On one hand,
flat_map
is very useful. On the other hand,scan
is very useful. What if we combined both?I was trying to write a simple FSM, so I tried this ugly abomination (which doesn't work, it just loops):
Then I noticed it doesn't work. So I had to change it up:
This works, looks just as ugly, and has a
.flat_map(|x| x)
. But hey, this is a FSM! But hey, since this is a FSM, this could be useful for others! But hey, what can we do to improve this?Well, we could remove the
.flat_map(|x| x)
, for one.So I propose
scan_flat
. It scans the iterator flat.(it could probably just return a
FlatMap
and be an alias for.scan(...).flat_map(|x| x)
, but idk.)In a perfect world I'd be able to return a function pointer for the next state (
fn default_case(key: u8) -> whatever { if key == b'%' { (*escape_case, None) } else { (*default_case, Some(key)) } }
), but this is fine.The text was updated successfully, but these errors were encountered: