Я не совсем уверен, что вы пытаетесь сделать с вашим кодом. Я бы рекомендовал создать хвост рекурсивной вспомогательную функцию, которая передается три аргумента:
1) The list of lists you are trying to build up
2) The current list you are building up
3) The list you are processing
В вашем примере, типичный вызов где-то в середине расчета будет выглядеть так:
helper([[1,1,1,1]], [2,2],[2,3,3,3])
рекурсия будет работая, посмотрев на заголовок последнего аргумента ([2,3,3,3]
), а также возглавляющий список, который в настоящее время строится ([2,2]
), и, поскольку они одинаковы - 2 в конце последнего аргумента шунтируются к списку:
helper([[1,1,1,1]], [2,2,2],[3,3,3])
в следующем шаге рекурсии головки затем сравниваются и оказываются разными (2 = 3!), Поэтому функция помощника будет поставить средний список в начале списка списков:
helper([[2,2,2], [1,1,1,1]], [3],[3,3])
средний список повторно инициализируется [3], поэтому она начнет расти
в конце концов вы достигнете что-то вроде этого:
помощник ([[2,2,2], [1,1 , 1,1]], [3,3,3], [])
[3,3,3] затем прикрепляется к списку списков, и возвращается обратный этого списка.
Как только такая вспомогательная функция определена, основной метод проверяет пустой список и, если не пуст, инициализирует первый вызов вспомогательной функции. Следующий код выводит эти идеи - используя стиль сопоставления шаблонов, а не hd
и tl
(я не очень люблю использовать эти функции явно - это делает код слишком похожим на Lisp).Если это домашнее задание, вы должны, вероятно, основательно понять, как это работает, а затем перевести его на код с участием hd
и tl
, так как ваш профессор будет рассматривать его как плагиат, если вы используете вещи, которые еще не изучили, и не сделали это своей собственной работой :
fun helper (xs, ys, []) = rev (ys::xs)
| helper (xs, y::ys, z::zs) =
if y = z
then helper(xs, z :: y :: ys, zs)
else helper((y::ys)::xs,[z],zs);
fun method [] = []
| method (x::xs) = helper([],[x],xs);