{-# LANGUAGE DeriveFunctor #-}
module Geometry
(
Point (..)
, origin
, translate
, (.+.)
, Shape (..)
, circle
, rectangle
, Measurable (..)
) where
data Point = Point
{ Point -> Double
px :: !Double
, Point -> Double
py :: !Double
}
deriving (Point -> Point -> Bool
(Point -> Point -> Bool) -> (Point -> Point -> Bool) -> Eq Point
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Point -> Point -> Bool
== :: Point -> Point -> Bool
$c/= :: Point -> Point -> Bool
/= :: Point -> Point -> Bool
Eq, Int -> Point -> ShowS
[Point] -> ShowS
Point -> String
(Int -> Point -> ShowS)
-> (Point -> String) -> ([Point] -> ShowS) -> Show Point
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Point -> ShowS
showsPrec :: Int -> Point -> ShowS
$cshow :: Point -> String
show :: Point -> String
$cshowList :: [Point] -> ShowS
showList :: [Point] -> ShowS
Show)
origin :: Point
origin :: Point
origin = Double -> Double -> Point
Point Double
0 Double
0
translate :: Point -> Point -> Point
translate :: Point -> Point -> Point
translate (Point Double
dx Double
dy) (Point Double
x Double
y) = Double -> Double -> Point
Point (Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
dx) (Double
y Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
dy)
(.+.) :: Point -> Point -> Point
.+. :: Point -> Point -> Point
(.+.) = Point -> Point -> Point
translate
infixl 6 .+.
data Shape
=
Circle Point Double
|
Rectangle Point Point
deriving (Shape -> Shape -> Bool
(Shape -> Shape -> Bool) -> (Shape -> Shape -> Bool) -> Eq Shape
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Shape -> Shape -> Bool
== :: Shape -> Shape -> Bool
$c/= :: Shape -> Shape -> Bool
/= :: Shape -> Shape -> Bool
Eq, Int -> Shape -> ShowS
[Shape] -> ShowS
Shape -> String
(Int -> Shape -> ShowS)
-> (Shape -> String) -> ([Shape] -> ShowS) -> Show Shape
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Shape -> ShowS
showsPrec :: Int -> Shape -> ShowS
$cshow :: Shape -> String
show :: Shape -> String
$cshowList :: [Shape] -> ShowS
showList :: [Shape] -> ShowS
Show)
circle :: Point -> Double -> Shape
circle :: Point -> Double -> Shape
circle = Point -> Double -> Shape
Circle
rectangle :: Double -> Double -> Shape
rectangle :: Double -> Double -> Shape
rectangle Double
w Double
h = Point -> Point -> Shape
Rectangle Point
origin (Double -> Double -> Point
Point Double
w Double
h)
class Measurable a where
area :: a -> Double
perimeter :: a -> Double
instance Measurable Shape where
area :: Shape -> Double
area (Circle Point
_ Double
r) = Double
forall a. Floating a => a
pi Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
r Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
r
area (Rectangle (Point Double
x0 Double
y0) (Point Double
x1 Double
y1)) = Double -> Double
forall a. Num a => a -> a
abs (Double
x1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
x0) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Num a => a -> a
abs (Double
y1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
y0)
perimeter :: Shape -> Double
perimeter (Circle Point
_ Double
r) = Double
2 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
forall a. Floating a => a
pi Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
r
perimeter (Rectangle (Point Double
x0 Double
y0) (Point Double
x1 Double
y1)) =
Double
2 Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Num a => a -> a
abs (Double
x1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
x0) Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
forall a. Num a => a -> a
abs (Double
y1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
y0))