New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add option module to Belt #2622
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Left some comments
jscomp/others/belt_Option.ml
Outdated
@@ -0,0 +1,27 @@ | |||
let getExn = function | |||
| Some x -> x | |||
| None -> assert false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe @bobzhang uses [%assert "getExn"]
for some reason
jscomp/others/belt_Option.ml
Outdated
| Some x -> x | ||
| None -> assert false | ||
|
||
let fold opt default f = match opt with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name will need some thinking
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
People from the JS world probably know this as reduce
or something along those lines at least for Lists/Arrays. We use fold internally because we're used to it from Scala/Haskell.
jscomp/others/belt_Option.ml
Outdated
| Some x -> f x | ||
| None -> default | ||
|
||
let map opt f = match opt with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we'd also expose some mapU
like other modules for consistency. But those can wait after this PR
jscomp/others/belt_Option.ml
Outdated
| Some x -> Some (f x) | ||
| None -> None | ||
|
||
let flatMap opt f = match opt with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same with fold
regarding naming
jscomp/others/belt_Option.ml
Outdated
| Some x -> x | ||
| None -> default | ||
|
||
let exists = function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Belt.List uses has
. cc @bobzhang another thing we should unify around. has
vs contains
vs exists
. First one is easier for non-english speakers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, not sure why Belt.List.has
exists
jscomp/others/belt_Option.ml
Outdated
| Some _ -> true | ||
| None -> false | ||
|
||
let empty = function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be isEmpty
I've addressed most of your comments @chenglou. I haven't changed the names for fold and flatMap. Added uncurried versions of all the functions where that applies. |
jscomp/others/belt_Option.mli
Outdated
val flatMapU : 'a option -> ('a -> 'b option [@bs]) -> 'b option | ||
val flatMap : 'a option -> ('a -> 'b option) -> 'b option | ||
val getOrElse : 'a option -> 'a -> 'a | ||
val has : 'a option -> bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
has
is redundant?
jscomp/others/belt_Option.mli
Outdated
val map : 'a option -> ('a -> 'b) -> 'b option | ||
val flatMapU : 'a option -> ('a -> 'b option [@bs]) -> 'b option | ||
val flatMap : 'a option -> ('a -> 'b option) -> 'b option | ||
val getOrElse : 'a option -> 'a -> 'a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getWithDefault
?
jscomp/others/belt_Option.mli
Outdated
val mapU : 'a option -> ('a -> 'b [@bs]) -> 'b option | ||
val map : 'a option -> ('a -> 'b) -> 'b option | ||
val flatMapU : 'a option -> ('a -> 'b option [@bs]) -> 'b option | ||
val flatMap : 'a option -> ('a -> 'b option) -> 'b option |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bind
or andThen
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flatmap. It makes much more sense when you need to explain it to newcommers
jscomp/others/belt_Option.mli
Outdated
|
||
val getExn : 'a option -> 'a | ||
val foldU : 'a option -> 'b -> ('a -> 'b [@bs]) -> 'b | ||
val fold : 'a option -> 'b -> ('a -> 'b) -> 'b |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is fold
common enough to be included?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We at least use it pretty often internally when dealing with a CLI tool we're writing. It's nice to have it to set defaults for missing arguments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this name does not sound meaningful to me, mapWithDefault
looks better?
jscomp/others/belt_Option.mli
Outdated
val flatMap : 'a option -> ('a -> 'b option) -> 'b option | ||
val getOrElse : 'a option -> 'a -> 'a | ||
val has : 'a option -> bool | ||
val isEmpty : 'a option -> bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kinda feel x = None
looks shorter than isEmpty
and more efficient.
Some missed functionalities, eq
, cmp
?
@arnarthor @bobzhang How about a
and an array version
|
I don't really see a usecase for it to be honest. This is just a specialized version of something like |
@arnarthor It's useful if you have collections of computations that can potentially fail, then you get the successful ones. It's a common function in the stdlibs of other functional programming languages like Haskell, Scala, Purescript, etc. |
jscomp/others/belt_Option.ml
Outdated
| None -> default | ||
|
||
let has = function | ||
| Some _ -> true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about naming these isSome
and isNone
like Rust? I think they convey what the function actually does better than has
/isEmpty
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed. In addition to isSome
isNone
:
Option.unwrap(Some(A))
vs Option.get(Some(A))
Option.unwrapOr(Some(A), B)
vs Option.getOrElse(Some(A), B)
vs Option.getWithDefault(Some(A), B)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isSome
and isNone
are nice, but @bobzhang pointed out that x == None
is more performant so they actually might not be needed.
I'd say that we should keep getExn
and getWithDefault
as is for consistency with other Belt modules which have get
, getExn
, getBy
etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with suffix consistency there but Option.get
doesn't communicate to me that we are unwrapping / moving / extracting the value contained in the Option
. unwrapExn
unwrapWithDefault
imo are more clear, but I don't feel super strongly about it
@bobzhang I've added I also kept Anyways feel free to leave some more comments if you would like me to change something 👍 |
Lets see if we can make it for release, see my comments about the naming of |
Yeah I think |
Since List already has map and flatten it would kinda make sense to call the combination flatMap... |
Done @bobzhang. Think it's ready for merge 👍 |
I can't run a rebuild on travis, the instance stalled which caused the error. |
Restarted for you. Related: #2564 |
I'm iffy on the name flatMap/bind/andThen, since it causes so much drama. Maybe we should leave it out for one version? |
This adds the following utility functions for the option data type to belt.