```-- | An incomplete implementation of interval aritrhmetic.
module Data.Number.Interval(Interval, ival, getIval) where

data Interval a = I a a

ival :: (Ord a) => a -> a -> Interval a
ival l h | l <= h = I l h
| otherwise = error "Interval.ival: low > high"

getIval :: Interval a -> (a, a)
getIval (I l h) = (l, h)

instance (Ord a) => Eq (Interval a) where
I l h == I l' h'  =  l == h' && h == l'
I l h /= I l' h'  =  h < l' || h' < l

instance (Ord a) => Ord (Interval a) where
I l h <  I l' h'  =  h <  l'
I l h <= I l' h'  =  h <= l'
I l h >  I l' h'  =  l >  h'
I l h >= I l' h'  =  l >= h'
-- These funcions are partial, so we just leave them out.
compare _ _ = error "Interval compare"
max _ _ = error "Interval max"
min _ _ = error "Interval min"

instance (Eq a, Show a) => Show (Interval a) where
showsPrec p (I l h) | l == h = showsPrec p l
| otherwise = showsPrec p l . showString ".." . showsPrec p h

instance (Ord a, Num a) => Num (Interval a) where
I l h + I l' h'  =  I (l + l') (h + h')
I l h - I l' h'  =  I (l - h') (h - l')
I l h * I l' h'  =  I (minimum xs) (maximum xs) where xs = [l*l', l*h', h*l', h*h']
negate (I l h)   =  I (-h) (-l)
-- leave out abs and signum
abs _ = error "Interval abs"
signum _ = error "Interval signum"
fromInteger i    =  I l l where l = fromInteger i

instance (Ord a, Fractional a) => Fractional (Interval a) where
I l h / I l' h' | signum l' == signum h' && l' /= 0 =  I (minimum xs) (maximum xs)
| otherwise = error "Interval: division by 0"
where xs = [l/l', l/h', h/l', h/h']
fromRational r   =  I l l where l = fromRational r
```