    {-# LANGUAGE BangPatterns #-}

    -- |
    -- == Point and vector arithmetic
    --
    -- Vectors aren't numbers according to Haskell, because they don't
    -- support all numeric operations sensibly. We define component-wise
    -- addition, subtraction, and negation along with scalar multiplication
    -- in this module, which is intended to be imported qualified.
    module Graphics.Gloss.Data.Point.Arithmetic
      (
        Point
      , (+)
      , (-)
      , (*)
      , negate
      ) where
    import Prelude (Float)
    import qualified Prelude as P
    import Graphics.Gloss.Rendering (Point)

    infixl 6 +, -
    infixl 7 *

    -- | Add two vectors, or add a vector to a point.
    (+) :: Point -> Point -> Point
    (Float
    x1, Float
    y1) + :: Point -> Point -> Point
    + (Float
    x2, Float
    y2) =
      let
        !x :: Float
    x = Float
    x1 Float -> Float -> Float
    forall a. Num a => a -> a -> a
    P.+ Float
    x2
        !y :: Float
    y = Float
    y1 Float -> Float -> Float
    forall a. Num a => a -> a -> a
    P.+ Float
    y2
      in (Float
    x, Float
    y)

    -- | Subtract two vectors, or subtract a vector from a point.
    (-) :: Point -> Point -> Point
    (Float
    x1, Float
    y1) - :: Point -> Point -> Point
    - (Float
    x2, Float
    y2) =
      let
        !x :: Float
    x = Float
    x1 Float -> Float -> Float
    forall a. Num a => a -> a -> a
    P.- Float
    x2
        !y :: Float
    y = Float
    y1 Float -> Float -> Float
    forall a. Num a => a -> a -> a
    P.- Float
    y2
      in (Float
    x, Float
    y)

    -- | Negate a vector.
    negate :: Point -> Point
    negate :: Point -> Point
    negate (Float
    x, Float
    y) =
      let
        !x' :: Float
    x' = Float -> Float
    forall a. Num a => a -> a
    P.negate Float
    x
        !y' :: Float
    y' = Float -> Float
    forall a. Num a => a -> a
    P.negate Float
    y
      in (Float
    x', Float
    y')

    -- | Multiply a scalar by a vector.
    (*) :: Float -> Point -> Point
    * :: Float -> Point -> Point
    (*) Float
    s (Float
    x, Float
    y) =
      let
        !x' :: Float
    x' = Float
    s Float -> Float -> Float
    forall a. Num a => a -> a -> a
    P.* Float
    x
        !y' :: Float
    y' = Float
    s Float -> Float -> Float
    forall a. Num a => a -> a -> a
    P.* Float
    y
      in (Float
    x', Float
    y')