{-| This module provides a @'Vector'@ datatype as described below. -} module FRP.Spice.Math.Vector where -------------------- -- Global Imports -- import Control.Applicative import Data.Default import Data.Monoid ---------- -- Code -- {-| A datatype that houses two values of a given type. It is provided with a @'Num'@ instance so that, when used with number types it can function similarly (though not exactly) to a mathematical vector. -} data Vector a = Vector a a {-| The default for the @'Vector'@. -} instance Default a => Default (Vector a) where def = Vector def def {-| Displaying the @'Vector'@. -} instance Show a => Show (Vector a) where show (Vector x y) = mconcat ["Vector ", show x, " ", show y] {-| Performs operations on the matching fields of the other @'Vector'@. -} instance Num a => Num (Vector a) where (Vector x1 y1) + (Vector x2 y2) = Vector (x1 + x2) (y1 + y2) (Vector x1 y1) * (Vector x2 y2) = Vector (x1 * x2) (y1 * y2) fromInteger n = Vector (fromInteger n) (fromInteger n) abs (Vector x y) = Vector (abs x) (abs y) signum (Vector x y) = Vector (signum x) (signum y) negate (Vector x y) = Vector (negate x) (negate y) {-| Maps over both values in the @'Vector'@. -} instance Functor Vector where fmap fn (Vector x y) = Vector (fn x) (fn y) {-| Applicative instance for @'Vector'@. -} instance Applicative Vector where pure a = Vector a a (Vector fn _) <*> (Vector x y) = Vector (fn x) (fn y) {-| Multiplying @'Vector'@ by a scalar value. -} scalar :: Num a => Vector a -> a -> Vector a scalar (Vector x y) n = Vector (x * n) (y * n)