问题
I need to use pattern matching techniques, in order to recursively swap every pair of elements in a list. So, [1, 2, 3, 4, 5] would return [2, 1, 4, 3, 5].
Two things I have found:
List.length: to return the length. Which is helpful to deal with even/odd lists.List.nth: to return a value at the designated spot in the list.drop.(list, i): to return the values after the first i elements are dropped.
Using those three things, I can sort of figure out some recursion methods, but I don't understand the pattern matching aspect. Below is some pseudocode without any pattern matching.
function(list):
var a = first on list
var b = second on list
// odd case
if(b = null | "")
{
list = drop.(list, 1) @ a
}
// even case
else if(b = "" & a = "")
{
list = list
}
// recursive case
else
{
list = function(drop.(list, 2) @ b @ a)
}
This could essentially, start looping through the list, swapping the pairs, placing(concatenating) them at the end of the list, and recursively repeating this until it has gone through all pairs.
回答1:
The functions List.length, List.nth and List.drop seem like they might solve your task, but this is counterproductive to your goal of using pattern matching. With pattern matching you're using that lists are algebraic data types declared sort of like
datatype 'a list = [] | :: of 'a * 'a list
which produces value constructors [] for empty list and the infix :: operator for cons'ing an element in front of an existing list (that is either empty or created in the same way), but also pattern constructors for recognizing what kind of list you're dealing with.
Example: A function that takes a list of integers and sums them:
fun sum [] = 0
| sum (x::xs) = x + sum xs
Example: A function that takes a list of 2-tuples and returns a similar list of 2-tuples but with the elements in each 2-tuple swapped:
fun swap [] = []
| swap ((x,y)::xys) = (y,x)::swap xys
Example: A function that takes an even-sized list of integers and returns a list where they've been added together in pairs:
fun addpairs (x::y::xys) = x + y :: addpairs xys
| addpairs [_x] = raise Fail "Odd-sized list"
| addpairs [] = []
In particular, patterns can be nested ((x,y)::xys ~~ "the list with at least one element where the first element is a 2-tuple with the first part of it named x and the second part named y" and x::y::xys ~~ "the list with at least two elements in it with the first element named x and the second element named y"), and order (matching from top to bottom) might matter if patterns overlap (which they don't in any of the above).
来源:https://stackoverflow.com/questions/47824609/swap-pairs-of-elements-in-a-list-using-pattern-matching