[Haskell-beginners] Re: how to implement accesor function for given data type

Brent Yorgey byorgey at seas.upenn.edu
Mon Sep 13 14:57:32 EDT 2010


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


More information about the Beginners mailing list