Is this efficient for checking multiple statements in Haskell? Or this there a better way?
case ((x > -10) && (x < 20),x /= 9,(x `mod` 2) == 0,x) of
(False,_,_,_) -> error "Not in range"
(_,False,_,_) -> error "Must not be 9"
(_,_,False,_) -> error "Must be even"
(True,True,True,10) -> stuff ()
(True,True,True,20) -> stuff ()
_ -> error "Error Message"
It's sometimes difficult to come up with small examples of this problem which don't look contrived, but they do happen. Sometimes you need a bunch of computed results to figure out how to split a function into its cases.
So yes, I often find it's cleanest to use case
on a tuple of things-I-might-care-about to build complex decision processes. I trust laziness to compute the minimum required to resolve which branch to invoke.
It's worth trying to express your tests via Boolean guards (or even pattern guards), but sometimes there's nothing to beat tabulating the computed values you need in a big tuple and then writing a row for each interesting combination of circumstances.
Assuming that caring about efficiency is really important, and is not premature optimization, you should optimize for the case which is most common; I think that even in Haskell, it means that you want to have the True,True,True
cases on top.
Actually, in the given case, if x == 10
or x == 20
you don't need to do the other tests - you don't even need to build thunk computing them; and the compiler cannot know (without profile-guided optimization) which is the code path which will be executed the most, while you should have a reasonable guess (in general you need profiling to verify that).
So what you want is something like the following (untested):
case x of
10 -> stuff ()
20 -> stuff ()
_ -> case ((x > -10) && (x < 20),x /= 9,(x `mod` 2) == 0) of
(False,_,_) -> error "Not in range"
(_,False,_) -> error "Must not be 9"
(_,_,False) -> error "Must be even"
_ -> error "Error Message"
Disclaimer: I did not verify what happens to this code and to the original one after all optimizations.
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