Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meaning of underscore in case ()

So I've seen the syntax around for

case () of _
   | someBool ->
   | someOtherBool ->

I understand what it does, e.g. toggle a case completely independently of the thing being evaluated by case (which makes sense, as in this case that would be unit, and it will always be unit).

I also understand that this can and (should) work independently of the thing being checked with case (eg (1 == 1) (someComplexFunction)), but that obviously unit is the fastest.

What I don't quite understand, is how the underscore works. It clearly informs the case to completely ignore the contents of the operand and just check for booleans. But where does this operator come from? And in what other contexts can I use it?

like image 961
Abraham P Avatar asked Aug 01 '16 09:08

Abraham P


1 Answers

As @Rhymoid said in the comment, it is just a pattern match with nothing being bound and it could be replaced by a name (which would be bound). It might be more clear to write it like this:

case () of
  _ | someBool -> ...
    | somOtherBool -> ...

This could also be written (more or less equivalently) as

case () of
  () | someBool -> ...
     | someOtherBool -> ...

These are guards. You can also have guards in a more complex case match:

case m of
  Just x
    | someBool -> ...
    | someOtherBool -> ...
  Nothing
    | someThirdBool -> ...
    | someFourthBool -> ...

with as many guards as you want in each match.

The reason to write the code you have given is a trick to get a succinct if-then-else style thing with several possibilities. The original code can be better written with the MultiWayIf extension enabled:

{-# LANGUAGE MultiWayIf #-}
...
  if | someBool -> ...
     | someOtherBool -> ...

MultiWayIf can also be used with any number of Boolean "cases," like the original code.

An underscore can be used in any pattern match for any pattern where you don't need the value later. For example:

andBool True True = True
andBool _    _    = False

or

f (Just _) = 'J'
f _        = 'N'
like image 128
David Young Avatar answered Oct 02 '22 15:10

David Young