Как правило, вы используете аккумулятор для увеличения результата, как вы go. В этом случае вы хотите накапливать каждый элемент ввода в пару списков. Эта пара списков передается от одного вызова к другому. Как только вы дойдете до своего базового случая, аккумулятор является (более или менее) вашим окончательным ответом: вам, возможно, потребуется сначала выполнить некоторую окончательную обработку для него, однако.
В этом случае вы хотите создать пару списков, и отправной точкой для создания любого списка является пустой список.
dup :: [a] -> ([a], [a])
dup xs = dup' xs ([], [])
where dup' :: [a] -> ([a], [a]) -> ([a], [a])
dup' [] acc = ...
dup' (x:xs) acc = ...
Подумайте, что вы хотите сделать с парой списков в каждом случае, прежде чем создавать рекурсивный вызов dup'
.
Обратите внимание, что аккумулятор не должен иметь тот же тип, что и конечное возвращаемое значение, или даже быть единственным аргументом. Вы также можете определить хвостовую рекурсивную версию, например
dup' :: [a] -> [a] -> [a] -> ([a], [a])
dup' [] accA accB = ...
dup' (x:xs) accA accB = ...