Friedrich wrote (to the Haskell mailing list):
> o_array :: Shape -> Float
> o_array (Polygon (v1:vs)) =
> let ph = phelp vs
> in
> foldr (+) 0.0 (map triangleArea ph)
> where phelp :: [Vertex] -> [[Vertex]]
> phelp (v2:v3:vs) = (v1:v2:v3:[]):phelp (v3:vs)
> phelp _ = []
>
> what I want is to replace the recursive phelp function with a function
> using higher order functions.
In situations like this where you need both an element and the next element
it can be simpler to pass two lists: the original list and its tail.
For example:
o_array :: Shape -> Float
o_array (Polygon (v1:vs))
= sum [triangleArea [v1, v2, v3] | (v2, v3) <- zip vs (tail vs) ]
> My base idea is splitting up List of Vertices into a list of exactly
> three vertices calculating that area and adding them all.
As Ralf mentioned you can compute the area of the triangle without
using square roots:
triangleArea :: [Vertex] -> Float
triangleArea [Vertex x1 y1, Vertex x2 y2, Vertex x3 y3]
= 0.5 * ((x2*y1-x1*y2) + (x3*y2-x2*y3) + (x1*y3-x3*y1))
This can give an negative area, depending on the direction of the
vertices. See for example <http://www.seanet.com/~ksbrown/kmath201.htm>.
Here's implementation of the original problem without using triangles:
area :: Shape -> Float
area (Polygon vertices)
= 0.5 * sum [(x1-x2)*(y1+y2)
| (Vertex x1 y1, Vertex x2 y2)
<- zip vertices (tail vertices ++ [head vertices])]
which is equivalent to your o_array function with the modified triangleArea
(I think).
Cheers,
Ronny Wichers Schreur