{-# LANGUAGE Haskell2010 #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}


module Records where


data Point = Point
    { Point -> Int
x :: !Int
    , Point -> Int
y :: !Int
    }


point :: Int -> Int -> Point
point :: Int -> Int -> Point
point Int
x Int
y = Point { x :: Int
x = Int
x, y :: Int
y = Int
y }


lengthSqr :: Point -> Int
lengthSqr :: Point -> Int
lengthSqr (Point { x :: Point -> Int
x = Int
x, y :: Point -> Int
y = Int
y }) = Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
y

lengthSqr' :: Point -> Int
lengthSqr' :: Point -> Int
lengthSqr' (Point { Int
x :: Point -> Int
x :: Int
x, Int
y :: Point -> Int
y :: Int
y }) = Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
x


translateX, translateY :: Point -> Int -> Point
translateX :: Point -> Int -> Point
translateX Point
p Int
d = Point
p { x = x p + d }
translateY :: Point -> Int -> Point
translateY Point
p Int
d = Point
p { y = y p + d }

translate :: Int -> Int -> Point -> Point
translate :: Int -> Int -> Point -> Point
translate Int
x Int
y Point
p =
    Point -> Point
aux Point
p
  where
    (Int
dx, Int
dy) = (Int
x, Int
y)
    aux :: Point -> Point
aux Point{Int
x :: Point -> Int
y :: Point -> Int
x :: Int
y :: Int
..} = Point
p { x = x + dx, y = y + dy }