
On Mon, Sep 13, 2010 at 05:33:12PM +0200, Martin Tomko wrote:
Hi Brent, thank you for your help. Indeed, I need to be able to distinguish them in terms of single coordinate, tuple or list - that is crucial in order to keep the logic. I am not sure how your second suggestion would help though, because then I would get a function to return the CoordinateSet, but then I would need again to somehow extract the individual vertices out of it for any mathematical processing. And again, I will be faced by the same problem. just one wrapper further, am I right?
No, you won't still have the same problem. The problem before was that you wanted to write a function which could return values of several different types, which is not possible. (Well, technically, it IS possible, but not in a way that would be helpful to you.) This solution allows you to wrap the options up in a single type. Of course, you will later need to extract vertices out of the Coordinates type for processing -- but that's just fine, you can write the processing function by cases on the Coordinates type. However, you might decide that the intermediate step is not all that helpful and just write the mathematical processing directly by cases on Geometry. It depends on what the mathematical processing looks like, I suppose.
This is what I end up with:
type Coordinate = (Float, Float)
data Coordinates = Pt Coordinate | Ls (Coordinate, Coordinate)| Pl [Coordinate] deriving (Show,Eq) -- this is what you called the CoordinateSet
data Geometry = Point FID Coordinates | LineSegment FID Coordinates | Polyline FID Coordinates | Polygon FID Coordinates deriving (Show,Eq)
This looks wrong to me, since this would allow (say) a Point to have a list of coordinates, or a Polygon to have just a single coordinate. I think you want to stick with what you had before.
Then, indeed, the whole Geometry ADT seems redundant, and could be
It doesn't look redundant to me. For example, isn't there a difference between a Polyline and a Polygon (even if they have the same coordinates)?
Let us assume a practical example: I want to find vertices shared by two geometries, using intersect or elem seems to be the way to go, depending if either are lists or soem are single points (not sure this will work on tuples... I would prefer a single solution for all). My thinking is that I need a function to get to the Coordinates of a geometry somehow, and maybe convert the mto a vector, but that sounds like a dirty trick not worthy of Haskell!
Why not: shared :: Geometry -> Geometry -> [Coordinate] shared geo1 geo2 = sharedCoords (getCoords geo1) (getCoords geo2) sharedCoords :: Coordinates -> Coordinates -> [Coordinate] sharedCoords (Pt p1) (Pt p2) = if (p1 == p2) then [p1] else [] sharedCoords (Pt p1) (Ls (x,y)) = ... sharedCoords (Pt p1) (Pl cs) = ... ... and so on. This is what I mean by doing mathematical analysis by cases on Coordinates. -Brent