Patrik Bašo
Patrik Bašo

Reputation: 147

Haskell - Elegant code for detecting if number is in range

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

Answers (2)

oisdk
oisdk

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

bereal
bereal

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

Related Questions