    {-# 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 forall a. Num a => a -> a -> a
    * Int
    x forall a. Num a => a -> a -> a
    + Int
    y forall a. Num a => a -> a -> a
    * Int
    y

    lengthSqr' :: Point -> Int
    lengthSqr' :: Point -> Int
    lengthSqr' (Point { Int
    x :: Int
    x :: Point -> Int
    x, Int
    y :: Int
    y :: Point -> Int
    y }) = Int
    y forall a. Num a => a -> a -> a
    * Int
    y forall a. Num a => a -> a -> a
    + Int
    x 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 :: Int
    x = Point -> Int
    x Point
    p forall a. Num a => a -> a -> a
    + Int
    d }
    translateY :: Point -> Int -> Point
    translateY Point
    p Int
    d = Point
    p { y :: Int
    y = Point -> Int
    y Point
    p forall a. Num a => a -> a -> a
    + Int
    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
    y :: Int
    x :: Int
    y :: Point -> Int
    x :: Point -> Int
    ..} = Point
    p { x :: Int
    x = Int
    x forall a. Num a => a -> a -> a
    + Int
    dx, y :: Int
    y = Int
    y forall a. Num a => a -> a -> a
    + Int
    dy }