Rfcs: Idea: Built-in way to go from bool to Option

Created on 5 Dec 2018  路  16Comments  路  Source: rust-lang/rfcs

The idea is pretty simple: Add a function called some to booleans such that you can automatically convert to an option.

The basic implementation wouldn't be much more than

fn some<T>(self, data: T) -> Option<T> {
  if self {
    Some(data)
  } else {
    None
  }
}

The purpose of this would be to be able to write something like regex.is_match(string).some(token) without having to explicitly set up an if-statement.

Maybe also add in an *_or_else style function that takes a closure as an input, such that the true case is only ever allocated if it succeeds: regex.is_match(string).and_some(|| build_token()).

Yes/No/Maybe?
I'd like to hear your opinions :)

T-libs

Most helpful comment

I find myself wanting the ability to "map" a bool with surprising regularity. This feature would be brilliant to see in std.

All 16 comments

Obligatory link to the boolinator crate (and its silly test comments)

I have no opinion on whether any of this should be uplifted to std

Personally, I think adding an external crate offsets the convenience of having it. I would rather just have this in std.

I think we should add this, and the closure-based version.

The outcome of https://github.com/rust-lang/rfcs/pull/2180 is that we didn鈥檛 find consensus on names.

For now, I tend to do Some(data).filter(closure).

This isn't quite equivalent: if the Some is expensive to build, that's where you want the closure. The point of the closure version is that you only need to build the value if you need it.

I find myself wanting the ability to "map" a bool with surprising regularity. This feature would be brilliant to see in std.

Another +1 to this. Should I do a PR for it?

@canndrew please do!

I personally would name this to_some and with_some unless anyone has better suggestions.

Perhaps to_opt, to_optional, map, with?

Option's map, and and and_then have direct analogues for bool, so it would be reasonable to reuse the names, but the simplest method does not have an analogue.

impl bool {
    fn ???<T>(self, b: T) -> Option<T>; // "closure-less map"
    fn map<T, F>(self, f: F) -> Option<T>  where F: FnOnce() -> T;
    fn and<T>(self, optb: Option<T>) -> Option<T>;
    fn and_then<T, F>(self, f: F) -> Option<T>  where F: FnOnce() -> Option<T>;
}

let my_opt_value = my_bool.???(get_value());
let my_opt_value = my_bool.map(|| get_value());
let my_opt_value = my_bool.and(get_opt_value());
let my_opt_value = my_bool.and_then(|| get_opt_value());

https://github.com/rust-lang/rfcs/pull/2180#issuecomment-337525480

Perhaps Option/Result could have this "closure-less map" as well, it's not a common operation, but search for .map(|_ shows that it's used occasionally.

my_opt.map(|_| ()) // Ignore the data, but keep the "status"

my_opt.map(|_| { // Same as `if my_opt.is_some() { ... }`
    do_things_with_side_effects();
    return_something()
}) 

Or perhaps it's not needed and bool could successfully live with the usual closure-taking map alone.

@petrochenkov the issue with using map is that it already has a very well-defined use in functional programming, namely that it applies a function to a value wrapped in some context. Bool is not a context the way Option or Vec or even HashMap is.

In Haskell terms: map :: (a -> b) -> f a -> f b, which means "given a function from a to b, and a value of type a wrapped in some context f, give me back a value b wrapped in the same context f".

For Option it would look like this: map :: (a -> b) -> Option a -> Option b, which does not fall in line with your suggested map :: (a -> b) -> Bool -> Option b (here reordered to have the function first).

Personally I'd rather go with either @mark-i-m's suggested to_opt or my own some because they don't already clutter the pre-conceived idea of what a "map" should be.

Any update on the situation? This would be really great to see available in std (instead of having an external dependency), since I often use Meson as a build system on the side (which has huge issues with the Cargo system).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

3442853561 picture 3442853561  路  3Comments

mahkoh picture mahkoh  路  3Comments

rudolfschmidt picture rudolfschmidt  路  3Comments

mqudsi picture mqudsi  路  3Comments

silversolver1 picture silversolver1  路  3Comments