I'm reading Real World Haskell, and this is my first try with the language.This is the result of the exercises of chapter 3:Consider three two-dimensional points a, b, and c. If we look at the angle formed by the line segment from a to b and the line segment from b to c, it either turns left, turns right, or forms a straight line. Define a Direction data type that lets you represent these possibilities.     Write a function that calculates the turn made by three 2D points and returns a Direction. Define a function that takes a list of 2D points and computes the direction of each successive triple. Given a list of points [a,b,c,d,e], it should begin by computing the turn made by [a,b,c], then the turn made by [b,c,d], then [c,d,e]. Your function should return a list of Direction.Using the code from the preceding three exercises, implement Graham's scan algorithm for the convex hull of a set of 2D points. You can find good description of what a convex hull is, and how the Graham scan algorithm should work.For short, the Graham scan algorithm is:find the point \$P\$ with the smallest \$y\$sort the points \$A\$ according to the angle \$(Ox, PA)\$ and add P at the endin the sorted list, form the turns \$(A_{i-1}, A_i, A_{i+1})\$ andremove the points \$A_i\$ for which it is a turn right.Now my code is the following:import Data.List-- 9data Direction = TurnLeft               | TurnRight               | StraightLine                 deriving (Show, Eq)-- 10data Point = Point {      x :: Float    , y :: Float    } deriving (Show, Eq)turn :: Point -> Point -> Point -> Directionturn a b c      | z > 0     = TurnLeft      | z < 0     = TurnRight      | otherwise = StraightLine    where      bax = x a - x b      bay = y a - y b -- coordinates of b->a      bcx = x c - x b      bcy = y c - y b -- coordinates of b->c      z   = bax * bcy - bcx * bay-- 11turns :: [Point] -> [Direction]turns []         = []turns [_]        = []turns [_,_]      = []turns (x:y:z:zs) = (turn x y z) : (turns (y:z:zs))-- 12angle :: Point -> Point -> Point -> Floatangle a b c = - (bax * bcx + bay * bcy) /              (sqrt ((bax * bax + bay * bay) * (bcx * bcx + bcy * bcy)))    -- more efficient than acos for the algorithm and is the same for sorting    where      bax = x a - x b      bay = y a - y b -- coordinates of b->a      bcx = x c - x b      bcy = y c - y b -- coordinates of b->cargmin :: Ord b => (a -> b) -> [a] -> aargmin _ []  = error empty listargmin f (x:xs)    | null xs = x    | (f x) < (f argminrest) = x    | otherwise              = argminrest    where argminrest = argmin f xshull :: [Point] -> [Point]hull pts =    origin : ((map snd (filter keepPt results)) ++ [origin])     where origin  = argmin y pts           oxaxis  = Point (1 + x origin) (y origin)           oxangle = angle oxaxis origin           compare_angle pt1 pt2 = compare (oxangle pt1) (oxangle pt2)           list    = reverse (sortBy compare_angle pts)           -- origin is the first element of the list           results = zip (turns (list ++ [origin])) (drop 1 list)           keepPt (dir, _) = dir /= TurnRightIt works, at least according to the following unit test:hull [(Point (-3) 1),(Point (-4) 1),(Point (-1) 4),(Point 0 0),(Point 2 2),(Point (-1) 3),(Point (-1) 2),(Point 1 0),(Point 3 (-1)),(Point (-1) (-1))]which gives[Point {x = -1.0, y = -1.0},Point {x = -3.0, y = 1.0},Point {x = -1.0, y = 2.0},Point {x = -1.0, y = 3.0},Point {x = -1.0, y = 4.0},Point {x = 2.0, y = 2.0},Point {x = 3.0, y = -1.0},Point {x = -1.0, y = -1.0}]Is it an idiomatic code? How would you improve it?
2D Convex hull exercise
beginner;haskell;computational geometry