[Haskell-cafe] Abstraction in data types

Alexander Solla ajs at 2piix.com
Thu Mar 18 02:36:37 EDT 2010

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)

More information about the Haskell-Cafe mailing list