{- |
  4-dimensional vectors with vector arithmetic.
-}

module Data.Vector.V4 where

import Data.Vector.Class

data Vector4 = Vector4 {Vector4 -> Scalar
v4x, Vector4 -> Scalar
v4y, Vector4 -> Scalar
v4z, Vector4 -> Scalar
v4w :: {-# UNPACK #-} !Scalar} deriving (Vector4 -> Vector4 -> Bool
(Vector4 -> Vector4 -> Bool)
-> (Vector4 -> Vector4 -> Bool) -> Eq Vector4
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Vector4 -> Vector4 -> Bool
== :: Vector4 -> Vector4 -> Bool
$c/= :: Vector4 -> Vector4 -> Bool
/= :: Vector4 -> Vector4 -> Bool
Eq, Int -> Vector4 -> ShowS
[Vector4] -> ShowS
Vector4 -> String
(Int -> Vector4 -> ShowS)
-> (Vector4 -> String) -> ([Vector4] -> ShowS) -> Show Vector4
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Vector4 -> ShowS
showsPrec :: Int -> Vector4 -> ShowS
$cshow :: Vector4 -> String
show :: Vector4 -> String
$cshowList :: [Vector4] -> ShowS
showList :: [Vector4] -> ShowS
Show)

instance BasicVector Vector4 where
  vmap :: (Scalar -> Scalar) -> Vector4 -> Vector4
vmap  Scalar -> Scalar
f (Vector4 Scalar
x  Scalar
y  Scalar
z  Scalar
w )                       = Scalar -> Scalar -> Scalar -> Scalar -> Vector4
Vector4 (Scalar -> Scalar
f Scalar
x)     (Scalar -> Scalar
f Scalar
y)     (Scalar -> Scalar
f Scalar
z)     (Scalar -> Scalar
f Scalar
w)
  vzip :: (Scalar -> Scalar -> Scalar) -> Vector4 -> Vector4 -> Vector4
vzip  Scalar -> Scalar -> Scalar
f (Vector4 Scalar
x1 Scalar
y1 Scalar
z1 Scalar
w1) (Vector4 Scalar
x2 Scalar
y2 Scalar
z2 Scalar
w2) = Scalar -> Scalar -> Scalar -> Scalar -> Vector4
Vector4 (Scalar -> Scalar -> Scalar
f Scalar
x1 Scalar
x2) (Scalar -> Scalar -> Scalar
f Scalar
y1 Scalar
y2) (Scalar -> Scalar -> Scalar
f Scalar
z1 Scalar
z2) (Scalar -> Scalar -> Scalar
f Scalar
w1 Scalar
w2)
  vfold :: (Scalar -> Scalar -> Scalar) -> Vector4 -> Scalar
vfold Scalar -> Scalar -> Scalar
f (Vector4 Scalar
x  Scalar
y  Scalar
z  Scalar
w )                       = Scalar -> Scalar -> Scalar
f (Scalar -> Scalar -> Scalar
f Scalar
x Scalar
y) (Scalar -> Scalar -> Scalar
f Scalar
z Scalar
w)

  vpack :: [Scalar] -> Maybe Vector4
vpack (Scalar
x:Scalar
y:Scalar
z:Scalar
w:[Scalar]
_) = Vector4 -> Maybe Vector4
forall a. a -> Maybe a
Just (Vector4 -> Maybe Vector4) -> Vector4 -> Maybe Vector4
forall a b. (a -> b) -> a -> b
$ Scalar -> Scalar -> Scalar -> Scalar -> Vector4
Vector4 Scalar
x Scalar
y Scalar
z Scalar
w
  vpack [Scalar]
_           = Maybe Vector4
forall a. Maybe a
Nothing

  vunpack :: Vector4 -> [Scalar]
vunpack (Vector4 Scalar
x Scalar
y Scalar
z Scalar
w) = [Scalar
x,Scalar
y,Scalar
z,Scalar
w]

  vpromote :: Scalar -> Vector4
vpromote Scalar
x = Scalar -> Scalar -> Scalar -> Scalar -> Vector4
Vector4 Scalar
x Scalar
x Scalar
x Scalar
x

instance Num Vector4 where
  + :: Vector4 -> Vector4 -> Vector4
(+) = (Scalar -> Scalar -> Scalar) -> Vector4 -> Vector4 -> Vector4
forall v.
BasicVector v =>
(Scalar -> Scalar -> Scalar) -> v -> v -> v
vzip Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
(+)
  (-) = (Scalar -> Scalar -> Scalar) -> Vector4 -> Vector4 -> Vector4
forall v.
BasicVector v =>
(Scalar -> Scalar -> Scalar) -> v -> v -> v
vzip (-)
  * :: Vector4 -> Vector4 -> Vector4
(*) = (Scalar -> Scalar -> Scalar) -> Vector4 -> Vector4 -> Vector4
forall v.
BasicVector v =>
(Scalar -> Scalar -> Scalar) -> v -> v -> v
vzip Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
(*)
  abs :: Vector4 -> Vector4
abs = (Scalar -> Scalar) -> Vector4 -> Vector4
forall v. BasicVector v => (Scalar -> Scalar) -> v -> v
vmap Scalar -> Scalar
forall a. Num a => a -> a
abs
  signum :: Vector4 -> Vector4
signum = (Scalar -> Scalar) -> Vector4 -> Vector4
forall v. BasicVector v => (Scalar -> Scalar) -> v -> v
vmap Scalar -> Scalar
forall a. Num a => a -> a
signum
  fromInteger :: Integer -> Vector4
fromInteger = Scalar -> Vector4
forall v. BasicVector v => Scalar -> v
vpromote (Scalar -> Vector4) -> (Integer -> Scalar) -> Integer -> Vector4
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Scalar
forall a. Num a => Integer -> a
fromInteger

instance Fractional Vector4 where
  / :: Vector4 -> Vector4 -> Vector4
(/) = (Scalar -> Scalar -> Scalar) -> Vector4 -> Vector4 -> Vector4
forall v.
BasicVector v =>
(Scalar -> Scalar -> Scalar) -> v -> v -> v
vzip Scalar -> Scalar -> Scalar
forall a. Fractional a => a -> a -> a
(/)
  recip :: Vector4 -> Vector4
recip = (Scalar -> Scalar) -> Vector4 -> Vector4
forall v. BasicVector v => (Scalar -> Scalar) -> v -> v
vmap Scalar -> Scalar
forall a. Fractional a => a -> a
recip
  fromRational :: Rational -> Vector4
fromRational = Scalar -> Vector4
forall v. BasicVector v => Scalar -> v
vpromote (Scalar -> Vector4) -> (Rational -> Scalar) -> Rational -> Vector4
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Scalar
forall a. Fractional a => Rational -> a
fromRational

instance Vector Vector4 where