public static void StrokePolygon (Context cr, List<PointD> points)
{
DrawPolygon (cr, points);
cr.Stroke ();
}
public static void DrawPolygon (Context cr, List<PointD> points)
{
cr.NewPath ();
bool first = true;
foreach (PointD p in points) {
if (first) {
first = false;
cr.MoveTo (p.X, p.Y);
} else {
cr.LineTo (p.X, p.Y);
}
}
}
And its Haskell equivalent:
strokePolygon = strokeWith drawPolygon
drawPolygon p = do { newPath; drawSubPolygon p }
drawSubPolygon (x:xs) = do { moveToP x; addToPolygon xs }
addToPolygon = mapM_ lineToP
strokeWith = doWith stroke
doWith g f x = do { f x; g }
moveToP = uncurry moveTo
lineToP = uncurry lineTo
The C# version is 379 characters long. The Haskell version is 283 characters long. The C# version defines two reusable functions. The Haskell version defines eight.
In the same amount of characters it takes to write a single function in C#, you can (and usually will) write a whole library in Haskell.
To really make the comparison, consider adding functions to draw filled polygons and filled and stroked circles.
public static void FillPolygon (Context cr, List<PointD> points)
{
DrawPolygon (cr, points);
cr.Fill ();
}
public static void FillCircle (Context cr, PointD c, double r)
{
DrawCircle (c, r);
cr.Fill ();
}
public static void StrokeCircle (Context cr, PointD c, double r)
{
DrawCircle (c, r);
cr.Stroke ();
}
public static void DrawCircle (Context cr, PointD c, double r)
{
cr.NewPath ();
cr.Arc (c.X, c.Y, r, 0, Math.PI*2);
}
And the Haskell version:
fillPolygon = fillWith drawPolygon
fillCircle c = fillWith (drawCircle c)
strokeCircle c = strokeWith (drawCircle c)
drawCircle c r = do { newPath; addCircle c r }
addCircle (x,y) r = arc x y r 0 (pi*2)
fillWith = doWith fill
444 characters in C#, 226 in Haskell. Six functions in Haskell, four in C#. The thing holding back C#'s character count is the heavy function signature boilerplate. In each of the four C# functions above, the function signature has more characters than the function body.
No comments:
Post a Comment