エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

四元数

四元数が扱えるわけでないのだけれど、書いてみた。
意外と簡単だったんだけど、本当にこれでいいのだろうか?

module Quaternion where

data (RealFloat a) => Qtn a = Qtn { x::a, y::a, z::a, w::a } deriving Eq

instance (RealFloat a) => Show (Qtn a) where
  show (Qtn x y z w) = (show x) ++ (sign y) ++ (show y) ++ "i" ++ (sign z) ++ (show z) ++ "j" ++ (sign w) ++ (show w) ++ "k"
                         where
                           sign n
                             | n < 0     = ""
                             | otherwise = "+"

instance (RealFloat a) => Num (Qtn a) where
  (Qtn x1 y1 z1 w1) + (Qtn x2 y2 z2 w2) = Qtn (x1 + x2) (y1 + y2) (z1 + z2) (w1 + w2)
  (Qtn x1 y1 z1 w1) * (Qtn x2 y2 z2 w2) = Qtn (x1*x2 - y1*y2 - z1*z2 - w1*w2)
                                              (x1*y2 + y1*x2 + z1*w2 - w1*z2)
                                              (x1*z2 - y1*w2 + z1*x2 + w1*y2)
                                              (x1*w2 + y1*z2 - z1*y2 + w1*x2)
  abs (Qtn x y z w)    = Qtn (sqrt (x*x + y*y + z*z + w*w)) 0 0 0
  signum (Qtn x y z w) = Qtn (x/a) (y/a) (z/a) (w/a) where a = sqrt (x*x + y*y + z*z + w*w)
  fromInteger n        = Qtn (fromInteger n) 0 0 0

conjugate (Qtn x y z w) = Qtn x (-y) (-z) (-w)