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.

### Like this:

Like Loading...

*Related*

Tags: arithmetic, bonsai, code, Haskell, interval, kata, praxis, programming

This entry was posted on December 21, 2010 at 11:52 am and is filed under Programming Praxis. You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.

December 26, 2010 at 5:36 am |

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).

December 26, 2010 at 12:39 pm |

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