compiler
compiler copied to clipboard
Unwrap Maybe in if statements
In Rust there is a type called Option
similar to Elm's Maybe
.
Rust let you unwrap the Option
in a if statment like this:
if let Some(a) = Some(1) {
// Do something with a
}
Would it be possible to do something similar in Elm? Maybe like this? Or maybe another way that works better for Elm?
if let Just a = Just 1 then
-- Do something with a
Now it seems like the only option I have is to use case of
like this.
case Just 1 of
Just a ->
-- Do something with a
Nothing ->
-- Return something that represents nothing
This would e.g come in handy for error handling
div [] [
if let Just error = hasError form FieldName then
p [ class "has-error" ] [ text error ]
-- else Return something that represents nothing
]
Thanks for reporting this! To set expectations:
- Issues are reviewed in batches, so it can take some time to get a response.
- Ask questions a community forum. You will get an answer quicker that way!
- If you experience something similar, open a new issue. We like duplicates.
Finally, please be patient with the core team. They are trying their best with limited resources.
Interesting - I think it highlights a difference with rust and elm, perhaps. Your if let
example is a rust expression that results in a () type - it lacks an else clause, so () is implied if the let fails. Therefore the other clause must return () as well. As a whole the expression returns no information, therefore its only useful as a side effect, like this:
if let Some(i) = number {
println!("Matched {:?}!", i);
}
In elm side effects are not allowed, so there's no reason to have an expression like this.
If you have an else clause, then if let can return something besides ():
if let Some(i) = number {
true
}
else
{
false
}
This example would return a boolean because the implied clause is there if the let fails. But at that point, why not just use a case?
I highly recommend this talk about working with Maybes:
https://youtu.be/43eM4kNbb6c
You could use Maybe.andThen, Maybe.map and Maybe.withDefault
It seems like it might be impossible to handle this in the same manner in a functional language like Elm.
Elm functions always have to return a type that you can use. While Rust returns an empty type ()
(which you cannot use for anything) unless you specify otherwise. Rust lets you compile as long as you don't explicitly set a return value (returning ()
).
if let Some(a) = Some(1) {
println!("{}", a);
};
But will not let you comple if you have a return value other than ()
.
if let Some(a) = Some(1) {
a
};
// ^ expected `()`, found integer
Unless you handle the other case with the else statement.
if let Some(a) = Some(1) {
a
} else {
0
};
However, I found a quite simple solution to my problem that I am satisfied with.
I created myself a helper function with an empty default value.
div [] [
Just "error message"
|> justOrNothing (\error -> p [ class "has-error" ] [ text error ])
]
justOrNothing : (a -> Html msg) -> Maybe a -> Html msg
justOrNothing callback maybe =
case maybe of
Just a -> callback a
Nothing -> text ""
I created myself a helper function with an empty default value.
For others finding this issue in the future, check out the elm-community/html-extra
package for some nice helpers for conditionals and Maybes in view code, including one that is equivalent to justOrNothing above, Html.Extra.viewMaybe
.