-- | Implement ordered pairs all over again for fun (and to make sure -- that we can manipulate them algebraically). Also require (as -- opposed to the built-in ordered pairs) that the elements have -- matching types. -- module TwoTuple where import Vector data TwoTuple a = TwoTuple a a deriving (Eq) instance (Show a) => Show (TwoTuple a) where show (TwoTuple x y) = "(" ++ (show x) ++ ", " ++ (show y) ++ ")" instance Functor TwoTuple where f `fmap` (TwoTuple x1 y1) = TwoTuple (f x1) (f y1) instance (RealFloat a) => Vector (TwoTuple a) where -- The standard Euclidean 2-norm. We need RealFloat for the square -- root. norm_2 (TwoTuple x y) = fromRational $ toRational (sqrt(x^2 + y^2)) -- The infinity norm, i.e. the maximum entry. norm_infty (TwoTuple x y) = fromRational $ max absx absy where absx = abs (toRational x) absy = abs (toRational y) -- | It's not correct to use Num here, but I really don't want to have -- to define my own addition and subtraction. instance Num a => Num (TwoTuple a) where -- Standard componentwise addition. (TwoTuple x1 y1) + (TwoTuple x2 y2) = TwoTuple (x1 + x2) (y1 + y2) -- Standard componentwise subtraction. (TwoTuple x1 y1) - (TwoTuple x2 y2) = TwoTuple (x1 - x2) (y1 - y2) -- Left undefined to prevent mistakes. One sane definition -- would be componentwise multiplication. (*) _ _ = error "multiplication of vectors is undefined" abs _ = error "absolute value of vectors is undefined" signum _ = error "signum of vectors is undefined" fromInteger x = TwoTuple (fromInteger x) (fromInteger x)