Reputation: 147
I'm writing my homework and I found piece of code I don't think is elegant enought..
Exactly :
if n >= min && n <= max
then ...
else ...
I want to ask if there is any more elegant way to write this code for checking if number is in range (min, max)
Upvotes: 2
Views: 3441
Reputation: 10091
(The answer below is just a cute trick, I wouldn't actually recommend using it!)
With some tricks, you can actually make operators that act kind of like ternary operators, so you get nice code to say "in range". Here's the operators in question:
infixr 4 <=!
infixr 4 !<=
(<=!) :: Ord a => a -> (Bool,a) -> Bool
lb <=! (iub, x) = iub && (lb <= x)
(!<=) :: Ord a => a -> a -> (Bool,a)
x !<= ub = (x <= ub, x)
You can use them like this:
>>> 1 <=! 3 !<= 5
True
>>> 1 <=! 0 !<= 5
False
You can even add strict relation operators:
infixr 4 <!
infixr 4 !<
(<!) :: Ord a => a -> (Bool,a) -> Bool
lb <! (iub, x) = iub && (lb < x)
(!<) :: Ord a => a -> a -> (Bool,a)
x !< ub = (x < ub, x)
And mix and match:
>>> 0 <=! 2 !<= 2
True
>>> 0 <=! 2 !< 2
False
Upvotes: 1
Reputation: 34252
I think this is as short as it can get out of the box. If this problem appears too often in your code to become annoying, you can extract it to a function, as suggested here:
(<?) :: Ord a => a -> (a,a) -> Bool
(<?) x (min, max) = x >= min && x <= max
And then use as:
if x <? (min, max)
then ...
else...
Update: it turns out, there's also a function inRange
in the base package.
Upvotes: 3