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