-- Ex1 type Radius = Double type Width = Double type Height = Double type SideA = Double type SideB = Double type SideC = Double data Shape = Circle Radius | Rectangle Width Height | Triangle SideA SideB SideC deriving (Eq, Ord) instance Show Shape where show (Circle r) = "Circle: " ++ show r show (Rectangle w h) = "Rectangle: " ++ show w ++ " " ++ show h show (Triangle a b c) = "Triangle: " ++ show a ++ " " ++ show b ++ " " ++ show c -- Ex2 perimeter :: Shape -> Double perimeter (Circle r) = 2 * pi * r perimeter (Rectangle w h) = 2 * w + 2 * h perimeter (Triangle a b c) = a + b + c area :: Shape -> Double area (Circle r) = pi * r * r area (Rectangle w h) = w * h area (Triangle a b c) = let s = (perimeter (Triangle a b c)) / 2 in sqrt(s * (s - a) * (s - b) * (s - c)) -- Ex3 sumArea :: [Shape] -> Double sumArea sa = foldr (\s acc -> acc + area s) 0 sa -- Ex4 data Point = Point2D Double Double | Point3D Double Double Double instance Eq Point where (Point2D x1 y1) == (Point2D x2 y2) = (x1 == x2) && (y1 == y2) (Point3D x1 y1 z1) == (Point3D x2 y2 z2) = (x1 == x2) && (y1 == y2) && (z1 == z2) -- Ex5 distance :: Point -> Point -> Double distance (Point2D x1 y1) (Point2D x2 y2) = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) distance (Point3D x1 y1 z1) (Point3D x2 y2 z2) = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1)) distance (Point2D _ _) (Point3D _ _ _) = error "Cannot find distance between a 2D and 3D point" distance (Point3D _ _ _) (Point2D _ _) = error "Cannot find distance between a 2D and 3D point" -- Ex6 instance Show Point where show (Point2D x y) = "Point 2D: " ++ show x ++ " " ++ show y show (Point3D x y z) = "Point 3D: " ++ show x ++ " " ++ show y ++ " " ++ show z getClosestPoint :: [Point] -> Point -> Point getClosestPoint pa p = foldr (\pc acc -> if (distance p pc) < (distance p acc) then pc else acc) (head pa) (tail pa) -- Ex7 fstt (a,_,_) = a sndt (_,a,_) = a getClosestDistance :: [Point] -> (Double, Point, Point) getClosestDistance ps = foldr (\pc acc -> foldr (\pc1 acc1 -> if pc == pc1 then acc1 else minVal acc1 (distance pc pc1, pc, pc1)) acc ps) (distance (ps!!0) (ps!!1), ps!!0, ps!!1) ps where minVal :: (Double, Point, Point) -> (Double, Point, Point) -> (Double, Point, Point) minVal va vb | fstt va < fstt vb = va | otherwise = vb main:: IO() main = do print(Triangle 0.1 0.2 0.3) print(perimeter (Rectangle 1 2)) print(area (Triangle 4 13 15)) print(sumArea [Triangle 4 13 15, Rectangle 2 3, Circle 4]) print((Point3D 1 2 3) == (Point3D 1 2 3)) print(distance (Point2D 0 0) (Point2D 1 1)) print(getClosestPoint [Point2D 1 2, Point2D 5 6, Point2D 0.5 10, Point2D 0.1 0.1, Point2D 10 10] (Point2D 0 0)) print(getClosestDistance [Point2D 0 0, Point2D 103 4, Point2D 7 5, Point2D 0.1 0.1, Point2D 7.1 5.2, Point2D 99 0])