## Programming Praxis – Interval Arithmetic

In today’s Programming Praxis exercise, our goal is to implement some functions to do interval arithmetic. Let’s get started, shall we?

The plus and minus functions are trivial.

```plus :: (Num a, Num b) => (a, b) -> (a, b) -> (a, b)
plus (a,b) (c,d) = (a+c, b+d)

minus :: (Num a, Num b) => (a, b) -> (b, a) -> (a, b)
minus (a,b) (c,d) = (a-d, b-c)```

As Chun Kin Lee pointed out, my initial attempt at removing duplication doesn’t work for ranges with negative numbers, so I had to go back to way mentioned in the original algorithm.

```times :: (Num a, Ord a) => (a, a) -> (a, a) -> (a, a)
times (a,b) (c,d) = let x = [a*c,a*d,b*c,b*d] in (minimum x, maximum x)

divide :: (Fractional a, Ord a) => (a, a) -> (a, a) -> (a, a)
divide (a,b) (c,d) = if c < 0 && d > 0 then error "divide by 0"
else let x = [a/c,a/d,b/c,b/d] in (minimum x, maximum x)```

Converting between bounded and centered intervals is also trivial.

```toCenter :: Fractional a => (a, a) -> (a, a)
toCenter (a,b) = ((a+b) / 2, (b-a) / 2)

fromCenter :: Num a => (a, a) -> (a, a)
fromCenter (a,b) = (a-b, a+b)```

Some tests to see if everything is working properly:

```main :: IO ()
main = do let x = (1,2)
y = (3,4)
print \$ plus x y == (4,6)
print \$ minus x y == (-3,-1)
print \$ times x y == (3,8)
print \$ divide x y == (1/4,2/3)
print \$ divide x x == (1/2, 2)
print \$ toCenter x == (3/2,1/2)
print \$ fromCenter (3/2,1/2) == x```

Everything seems to be working fine.

### 2 Responses to “Programming Praxis – Interval Arithmetic”

1. LEE, Chun Kin Says:

times (a,b) (c,d) = (min a b * min c d, max a b * max c d)

It doesn’t work for negative numbers.
For example, (times (-1, 10) (-10, 1)) should be (-100, 10), but your function returns (10, 10).

2. Remco Niemeijer Says:

Thanks for the bug report. I’ve updated the algorithm.