Today, I found myself typing the following code:
case () of
_ | x < 15 -> ...
_ | x < 25 -> ...
_ | x < 50 -> ...
_ -> ...
The meaning of this is straight-forward enough, but it just feels... wrong to utter case ()
. Does anybody have a better suggestion?
I suppose since I'm branding on x
, I could have written case x
. But that still leaves me with nothing to actually pattern-match on; it's all about the guards. And that still feels weird.
There is nothing wrong with case ()
; it is the best you have for this use-case unless you want to use very recent syntactic and non-standard-extensions like GHC’s multi-way-if.
Others have mentioned that case
if fine and mutli-way if exists, but I'd go for a local function via a where or let statement:
someFunction = do
x <- monadicOp
let f y | y < 5 = expr1
| y < 15 = expr2
| y < 25 = expr3
| True = expr4
f x
This is syntactically cleaner than the case statement solution and more portable than multi-way if.
EDIT:
In case it isn't clear, if the value being compared, x
in this case, is already in scope when you define the guarded function (f
) then you could just define a value instead:
someFunction = do
x <- monadicOp
let r | x < 15 = expr1
| x < 25 = expr2
r
You can exploit lazy evaluation to come up with something like this:
import Data.List
import Data.Maybe
import Control.Applicative
cases :: [(Bool,a)] -> a -> a
cases lst d = snd $ fromJust $ (find fst lst) <|> Just (True,d)
main = do
let x = 20
r = cases [(x < 15, putStr "15"),
(x < 25, putStr "25"),
(x < 50, putStr "50")] $ putStr "None"
in
r
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With