(Haven't really had much time for Haskell this week – I had set myself the task of comparing some versions of SOE exercises, but will get back to that as soon as I can. In the mean time, another (shortish) post in the regular series…)

The first part is straight forward enough. We create a sub-module

â€œPerimeterâ€, that builds on Shape. The perimeters for Rectangle and

Triangle are easy enough. The one for polygon has a cute trick with zip

> sides::[Vertex]->[Side]

> sides vs=zipWith distBetween vs (tail vs ++[head vs])

The cool trick is that `(tail vs ++ [head vs])` is the list

cycled back, with the head on the end. So if you had the list [1..5],

you'd be zipping

[1,2,3,4,5]

[2,3,4,5,1]

This means that we can do the distBetween in a circular way. Very cute.

Hudak hints that `zip` can be written in terms of zipWith.

> zip::[a]->[b]->[(a, b)]

so we need a function that does

> aux::a->b->(a,b)

Like so

> zip a b=zipWith aux a b

> where aux::a->b->(a,b)

> aux a b=(a,b)

Which, checking the â€œTour of the preludeâ€, is how it is defined, only

with a much better name for the auxiliary function: `pair`.

### Ellipses

OK, here's some scary mathematics with nasty hints about integration and

then the off-handed â€œOh, we'll just do it as an infinite summation!â€

Luckily I've seen this notation, about 12 years ago, and I'm moderately

comfortable with the idea of summing a sequence that converges on zero,

so I think I can proceed without having to run and cower in the woods.

Defining the infinite sequence in terms of `scanl` is strange

though.

> s=let aux s i=nextEl e s i

> in scanl aux (0.25 * e^2)[2..]

Rather than defining that the base case s(1) is (0.25 * e^2) we're using

it as the `init` argument to scanl. `scanl` is like foldl

except that it returns the intermediate results. So, taking Hudak's

advice to the slow and confused, and working through the first few

iterations:

> s=let aux s i=nextEl e s i

> in scanl aux (0.25 * e^2)[2..]

So, something like:

s = scanl aux s1 [2..]

= scanl aux s1 (2 : [3..])

= s1 : scanl aux (aux s1 2) [3..]

= s1 : scanl aux s2 [3..]

= s1 : s2 : scanl aux s3 [4..]

Cute. Typing in the definition of `perimter (Ellipse r1 r2)`

though, ghci refused to parse it with the always handy

parse error (possibly incorrect indentation)

I eventually managed to appease it by entering a newline after the

`where` thusly:

> perimeter (Ellipse r1 r2)

>|r1 > r2=ellipsePerim r1 r2

>|otherwise=ellipsePerim r2 r1

> where

> ellipsePerim r1 r2

I guess the layout rules for `where` might have changed since the

publication of the book, or have I made a stupid mistake?