I am a bit confused as to how to get multiple checks under an else. I freely admit I am a total newbie with Elm and am more used to Python etc.
I have the following construct
If
Else
Case
Nothing ->
Just ->
And this works as expected. However I wish to add a second case under the else (which also works fine on its own) so that both case statements are evaluated and the action performed. This is probably a huge no no but I am amending existing code and this seems like it should be straightforward.
I think we still need more detail about what you mean by âdo actionâ. Elm is a pure language, meaning there are no side effects. An if or case expression alone will not perform any actions in the existing or new code.
case
<checkthing>
|> List.filter (.isActive >> Maybe.withDefault False >> not)
|> List.head
of
Nothing ->
<debug text>
Just
<click a button on screen>
The same idea for the second case except itâs checking a different condition and then using a context menu right click.
In this case the âactionsâ are the interacting with the UI (the mouse click or context menu) and the two case conditions are different but I wish both to happen under that else.
Would it work to return a list of actions instead of a single action? That way you can do:
if
[ <.. stuff ..> ]
else
[ case <...> of
Nothing -> <debug text>
Just _ -> <click a button on screen>
, case <...> of
Nothing -> <debug text>
Just _ -> <right click a button on screen>
]
The 2nd branch of this `if` does not match all the previous branches:
Now, that will be because I didnât wrap the if in to make them both lists but if I do that then it throws another compile error because of the outside wrapping of the if. Again, I am a newbie at Elm but this seems unnecessarily hard. I obviously canât share the code directly or I would have already.
Thanks for the suggestion but I think you may have missed that there is two different things to case.
I need to .
{ a =
if <check something> then
<some stuff>
else
case <another different thing>
Nothing -> <debug text>
Just -> <do some stuff involving a mouse click>
case <check a totally different thing>
Nothing -> <debug text>
Just -> <do some other stuff involving a right click to context menu>
}
Then you can do what @passiomatic suggested and case on a tuple.
However, to clarify, do <some stuff>, <debug text>, <do some stuff involving a mouse click>, <do some other stuff involving a right click to context menu>all return the same Type?
If not youâll need to re-think, or maybe provide more detailed information regarding what the types are.
I believe the misunderstanding comes from the fact that @LusiElm tries to think like in JavaScript, at the level of a view function:
// I assume emailDisplay, warningModal and contextMenu are IDs of elements in the DOM
document.forms[0].addEventListener('submit', (ev) =>
{
const emailInput = ev.target.email
if(/@example.com$/.match(emailInput.value))
// This is View Logic
document.emailDisplay.innerText = 'We\'ve got an email';
else
{
switch(something)
{
case 1:
// This is Control logic and view logic
document.warningModal.show();
document.emailDisplay.innerText = 'We\'ve got no email';
break;
case 2:
// This is Control logic
document.contextMenu.show();
break;
}
}
}
My understanding is that In Elm, you would make that a control function where:
the first branch issue a command that modify the model the emailDisplay view is mirroring
the second branch return two batched commands
the third branch would issue a command to show the context menu
Every time you end up modifying the model so it would be reflected in the view, you never act directly on the DOM.
{ a =
if <check something> then
<some stuff>
else
case <another different thing>
Nothing -> <debug text>
Just -> <do some stuff involving a mouse click>
}
That works. Or if I have
{ a =
if <check something> then
<some stuff>
else
case <check a totally different thing>
Nothing -> <debug text>
Just -> <do some other stuff involving a right click to context menu>
}
That also works. I just canât find a way to have both.
{ a =
if <check something> then
<some stuff>
else
case (<another different thing>,<check a totally different thing>) do
(Nothing, Nothing) ->
<do some stuff when neither match>
(Just _, Just _) ->
<do some stuff when both match>
(Just _, Nothing) ->
<do some stuff when left side matches>
(Nothing, Just _) ->
<do some stuff when right side matches>
}
Hey there, welcome to Elm! If i understand your problem correctly, then itâs a problem with the result type you want to work with and the type the code currently works with. You said itâs currently kind of looking like this?
a : ???
a =
if checkSomething then
someStuff
else
case checkDifferentThing of
Nothing ->
debugText
Just _ ->
rightClickContextMenu
I hope iâm not being too obvious when i say that the three values / functions / whatever you want to call them someStuff, debugText and rightClickContextMenu all have to be of the same type. I wrote ??? above, but you can check in your code what itâs actually called. You make it sound like itâs some kind of Action type, so i will continue with that.
Now your problem is, that you want your else-Branch to not return a single Action now, but instead a List Action - and thatâs not compatible with whoever is calling this a-thing. You would have to change your caller to work with that.