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
Add functions similar to then() and then_some() on bool in Rust which take a bool and return an option which is None if the bool is false and Some f() or Some x if the bool is true.
module Option
let thenSome (value: 'a) (cond: bool) : 'a option =
if cond then Some value else None
let thenSomeWith (thunk: unit -> 'a) (cond: bool) : 'a option =
if cond then Some (thunk()) else None
Alternative names: Option.fromBool / Option.fromBoolWith
The existing way of approaching this problem in F# is ...
let opt = if x < 10 then Some x else None
Which becomes:
let opt' = x < 10 |> Option.thenSome x
Pros and Cons
The advantages of making this adjustment to F# are ...
It makes it a bit nicer to write pipelined code that needs to convert a bool value to an option. An example:
let combine (a: string option) (b: string option) : string option =
match a, b with
| Some a', Some b' -> Some(b' + a')
| None, _ -> b
| _ -> a
let fizzBuzz n =
n % 3 = 0
|> Option.thenSome "Fizz"
|> combine (n % 5 = 0 |> Option.thenSome "Buzz")
|> Option.defaultWith (fun () -> string n)
The alternative way to write this using if ... then ... else:
let fizzBuzz' n =
if n % 3 = 0 then Some "Fizz" else None
|> combine (if n % 5 = 0 then Some "Buzz" else None)
|> Option.defaultWith (fun () -> string n)
I suggest that the version using Option.thenSome emphasizes the important part of the logic and gets rid of the repetitive else None branches that are really just noise here.
Another use can be seen in this alternative approach to implementing fizzBuzz using active patterns, where Option.thenSome makes the active pattern function implementations a bit cleaner:
let (|Fizzy|_|) n =
n % 3 = 0 |> Option.thenSome "Fizz"
let (|Buzzy|_|) n =
n % 5 = 0 |> Option.thenSome "Buzz"
let fizzBuzz'' n =
match n with
| Fizzy f & Buzzy b -> f + b
| Fizzy f -> f
| Buzzy b -> b
| _ -> string n
An example of using Option.thenSomeWith to avoid evaluation when the condition is false:
type Classification =
| Perfect
| Abundant
| Deficient
let fromCompare =
function
| 1 -> Deficient
| 0 -> Perfect
| -1 -> Abundant
| _ -> failwith "Invalid comparison result"
let classify n =
n > 0
|> Option.thenSomeWith (fun () ->
let n = int64 n
seq {
for i in 1L .. n - 1L do
if n % i = 0 then i
}
|> Seq.sum
|> compare n
|> fromCompare)
Here's classify with if ... then ... else:
let classify n =
if n <= 0 then
None
else
let n = int64 n
seq {
for i in 1L .. n - 1L do
if n % i = 0 then i
}
|> Seq.sum
|> compare n
|> fromCompare
|> Some
Again the difference is fairly minor but we eliminate some noise with Nones and Somes.
The disadvantages of making this adjustment to F# are ...
This is a minor improvement and easily implemented in user code rather than in the library.
Extra information
Estimated cost (XS, S, M, L, XL, XXL):
S
Related suggestions: (put links to related suggestions here)
The Option.thenSome function is a simpler way to get some of the benefits of issue 1041 for active patterns that are based on a simple boolean condition.
Affidavit (please submit!)
Please tick this by placing a cross in the box:
This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.
Please tick all that apply:
This is not a breaking change to the F# language design
I or my company would be willing to help implement and/or test this
For Readers
If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.
The text was updated successfully, but these errors were encountered:
If you really want functions like this, just add them in an auxiliary module
module Option =
let thenSome (value: 'T) (cond: bool) : 'T option =
if cond then Some value else None
let thenSomeWith (thunk: unit -> 'T) (cond: bool) : 'T option =
if cond then Some (thunk()) else None
I propose we ...
Add functions similar to
then()
andthen_some()
onbool
in Rust which take a bool and return an option which isNone
if thebool
isfalse
andSome f()
orSome x
if the bool is true.Alternative names:
Option.fromBool
/Option.fromBoolWith
The existing way of approaching this problem in F# is ...
let opt = if x < 10 then Some x else None
Which becomes:
let opt' = x < 10 |> Option.thenSome x
Pros and Cons
The advantages of making this adjustment to F# are ...
It makes it a bit nicer to write pipelined code that needs to convert a bool value to an option. An example:
The alternative way to write this using
if ... then ... else
:I suggest that the version using
Option.thenSome
emphasizes the important part of the logic and gets rid of the repetitiveelse None
branches that are really just noise here.Another use can be seen in this alternative approach to implementing
fizzBuzz
using active patterns, whereOption.thenSome
makes the active pattern function implementations a bit cleaner:An example of using
Option.thenSomeWith
to avoid evaluation when the condition is false:Here's classify with
if ... then ... else
:Again the difference is fairly minor but we eliminate some noise with
None
s andSome
s.The disadvantages of making this adjustment to F# are ...
This is a minor improvement and easily implemented in user code rather than in the library.
Extra information
Estimated cost (XS, S, M, L, XL, XXL):
S
Related suggestions: (put links to related suggestions here)
#1041
The
Option.thenSome
function is a simpler way to get some of the benefits of issue 1041 for active patterns that are based on a simple boolean condition.Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.
The text was updated successfully, but these errors were encountered: