On Mar 17, 2010, at 10:27 PM, Darrin Chandler wrote:
Let's go back to your original code:
data Point = Cartesian (Cartesian_coord, Cartesian_coord)
| Spherical (Latitude, Longitude)
type Center = Point
type Radius = Float
data Shape = Circle Center Radius
| Polygon [Point]
normalize_shape :: Shape -> Shape
normalize_shape Circle c r = Circle c r
normalize_shape Polygon ps = Polygon $ fmap normalize_point ps where
normalize_point = something appropriate for the function.
In fact, you could lift this into a higher order function, that takes
a normalize_point function as an argument:
normalize_shape :: (Point -> Point) -> Shape -> Shape
normalize_shape f (Circle c r)= Circle (f c) r
normalize_shape f (Polygon ps) = Polygon $ fmap f ps
Now, I'm not suggesting that you should always normalize shapes, as I
had with normalize_point before. But this combinator captures some
nice, generic logic. For example, you can do stuff like:
cartesian_shape :: Shape -> Shape
cartesian_shape = normalize_shape cartesian_point where ...
normalize_shape is the sort of function you would use while defining a
function, and possibly provide function specific behavior in the
function's where clause.
double_shape :: Shape -> Shape
double_shape (Circle c r) = Circle c (2 * r)
double_shape (Polygon ps) = Polygon $ normalize_shape (double_point .
cartesian_point) ps where
double_point Cartesian (x, y) = Cartesian (sqrt(2) * x, sqrt(2) * y)
Haskell-Cafe mailing list