One way to do this is to handle each constructor for a `Region` (and a `Shape` for those cases) and reflect those in the x-axis, i.e.

```
flipX :: Region -> Region
flipX (Translate (a,b) r) = Translate (a,-b) (flipX r)
flipX (Scale (a,b) r) = Scale (a,-b) (flipX r)
flipX (Complement r) = Complement (flipX r)
flipX (r1 `Union` r2) = (flipX r1) `Union` (flipX r2)
flipX (r1 `Intersect` r2) = (flipX r1) `Intersect` (flipX r2)
flipX (HalfPlane (x1,y1) (x2,y2)) = HalfPlane (x2,-y2) (x1,-y1)
flipX Empty = Empty
flipX (Shape s) = Shape (flipXShape s)
where flipXShape (RtTriangle a b) = RtTriangle a (-b)
flipXShape (Polygon vs) = Polygon (map ((x,y) -> (x,-y)) vs)
flipXShape s = s
```

And similarly (negating the x-coordinate) for `flipY`. Note that the order of points must change in `HalfPlane`, and should also be reversed in flipping a `Polygon` if we had the clockwise ordering constraint. Another way to solve this exercise is to use the `Scale` constructor on a `Region`:

```
flipX :: Region -> Region
flipX r = Scale (1, -1) r
flipY :: Region -> Region
flipY r = Scale (-1, 1) r
```

## 2 responses to “Exercise 8.7”

Wow, that Scale solution is really good one.

2 minor errors in the first solution:

> flipX (Scale (a,b) r) = Scale (a,-b) (flipX r)

flipX (Scale (a,b) r) = Scale (a,b) (flipX r)

> flipXShape (Polygon vs) = Polygon (map ((x,y) -> (x,-y)) vs)

flipXShape (Polygon vs) = Polygon (map (\ (x,y) -> (x,-y)) vs)