I’m trying to figure out if Rescript’s API already has a generic map. Currently I thought about using Option.map but seems to verbose for non-option values.
Is there any official way to do this? or should I just create my own utility map?
I’m trying to figure out if Rescript’s API already has a generic map. Currently I thought about using Option.map but seems to verbose for non-option values.
Is there any official way to do this? or should I just create my own utility map?
Why did you choose mapWithDefault for example 1 and not Belt.Option.map?
A
good point, I tried it wit Option.map and works as well… a little less verbose
In your example, “Option 2” seems like the the most natural, easiest, and obvious choice. “Option 1” just seems bizarre, and both it and “Option 3” add unnecessary levels of indirection and make the code more complicated.
The Option.map
function exists to, well, map option
types. Just like Result.map
, Array.map
, etc each exist to map their respective types. If you want a map
function for your custom type, then you’ll need to provide it yourself.
So I think the real question here is: what are you trying to solve? Your “Option 3” map function has this signature: ('a, 'a => 'b) => 'b
which is really too generic to be useful. Again, it just adds a level of indirection around the 'a => 'b
callback function. Why not just use the callback directly?
Instead of this:
let map = (x, mapper) => mapper(x)
let result3 = getQuantity()->map(qty =>
switch itemType {
| Piece => qty
| Roll => qty *. 1000.
}
)
Why not just this?
let map = qty =>
switch itemType {
| Piece => qty
| Roll => qty *. 1000.
}
let result3 = getQuantity()->map
(As an aside, this doesn’t fit the usual definition of a “map” function, but the naming isn’t as important here.)
Jorge you can also use partial application if you really want a specific mapper… it will be specific to the [functor] and maybe the internal types:
let mapper = (~itemType) => {
Option.map(_, (qty) => {
switch itemType {
...
}
})
}
@johnj @mouton
I think Belt.Float and Belt.Int should also have map
methods such as Belt.Option and Belt.Result
so we could do
let result4 = getQuantity()->Belt.Float.map(qty =>
switch itemType {
| Piece => qty
| Roll => qty *. 1000.
}
)
In case of a custom type sounds fair to use a custom mapper.
Well I would like to write an inline function on the pipe instead of declaring a map function out of the pipe, just like the same fashion of methods like Array.map
and Option.map
.
Maybe there is a way to inline a function in a pipe that I don’t know of
Actually I could also use a tuple switch
let result5 = switch (getQuantity(), itemType) {
| (qty, Piece) => qty
| (qty, Roll) => qty *. 1000.
}
Whats the signature of that Float.map?
You can use parenthesis
let a = 2->(x => x * 2)->(x => x + 3)
If you really like the pattern you use for other data types like option result array etc but without a context (nullability, error, sequence etc) theres a data type called identity functor. You can define it as a variant with only one member holding value of type 'a. The main operation defined on identity functor is map.
I made it up, but I think it would be float => float
ooh this is very helpful, thanks!