Efficiency of using multiple Haskell statements

Is this effective for checking multiple statements in Haskell? Or is this the best 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" 
+4
source share
3 answers

It is sometimes difficult to come up with small examples of this problem that do not look far-fetched, but they do happen. Sometimes you need a bunch of calculated results to figure out how to break the function down into your cases.

So, yes, I often think that using case on a tuple of things - I can take care of creating complex decision-making processes. I trust laziness to calculate the minimum necessary to resolve which branch causes.

It’s worth trying to express your tests with Boolean guards (or even with template protection), but sometimes there’s nothing that could beat the tabular calculations needed in a large tuple, and then write a line for each interesting combination of circumstances.

+7
source

Assuming that caring for efficiency is really important and not a premature optimization, you should optimize for the case that is most common; I think that even in Haskell, this means that you want to have True,True,True vertices on top.

In fact, in this case, if x == 10 or x == 20 you do not need to perform other tests - you do not even need to build thunk by calculating them; and the compiler cannot know (without profile-based optimization) which is the most traffic code that will be executed the most, while you should have a reasonable guess (in general, you need to profile to make sure).

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 check what happens with this code and the original after all the optimizations.

+1
source

Like this? You check the conditions in order and return something on the first to fail, so make the conditions in the list and search for it.

 fn x = case lookup False conds of Just ohno -> error ohno Nothing | x == 10 -> stuff | x == 20 -> stuff | otherwise -> error "Error Message" where conds = [ (x > -10 && x < 20, "Not in range"), (x /= 9, "Must not be 9"), (even x, "Must be even")] 
0
source

All Articles