It's not magic. It's pattern matching.
The `[Posn(x, y), ...]` is a pattern that matches a list of positions. The `[Posn(y, x), ...]` is a template that produces a list of positions.
The `[Posn(x, y), ...]` is a pattern that matches a list of positions. The `[Posn(y, x), ...]` is a template that produces a list of positions.
In the template the `Posn(y, x)` is followed by `...` so the same number of positions is produced as the common length of x and y.
If I had to guess:
fun flip_all([Posn(x, y), rest]):
[Posn(y, x), rest]
If I am correct then the only difference between flipping all and flipping just the first is `...` vs `rest` fun flip_first([Posn(x, y), more, ...]):
[Posn(y, x), more, ...] fun flip_all([Posn(x, y), & rest]):
You'd need to amend the logic of the function body to iterate or recurse over the remainder. You'd also ended up with a nested list using your version but you can use & again to splice in the result, so if you wanted a recursive version of that it would be something like (skipping the base case): fun
| flip_all([]): []
| flip_all([Posn(x, y), & rest]):
[Posn(y, x), & flip_all(rest)]
(not tested, don't have Rhombus available on this system but that should be correct)If you really want flip_first it'd be:
fun flip_first([Posn(x, y), & rest]):
[Posn(y, x), & rest] flip_one Posn(a,b) = Posn(b,a)
flip_first p:ps = flip one : ps
flip_all ps = map flip ps
To my taste that's a lot nicer