Шаг за шагом:
list2 = list of numbers
Мы примем это как данность, поэтому list2
- это просто список чисел.
for i from 0 to N // N being a positive integer
Правильный способ сделать это в Хаскеле, как правило, с помощью списка. Ленивость означает, что значения будут вычисляться только при использовании, поэтому обход списка от 0 до N заканчивается тем же, что и цикл, который у вас здесь есть. Итак, просто [0..n]
сделает свое дело; нам просто нужно выяснить, что с этим делать.
for each number in list2
Учитывая "для каждого", мы можем сделать вывод, что нам нужно пройти здесь по полноте list2
; что мы с ним делаем, пока не знаем.
if number == i, add to list1
Мы строим list1
на ходу, поэтому в идеале мы хотим, чтобы это был конечный результат выражения. Это также означает, что на каждом рекурсивном шаге мы хотим, чтобы результат был list1
, который мы имеем «до сих пор». Чтобы сделать это, нам нужно убедиться, что мы передаем результат каждого шага по ходу.
Итак, приступим к мясу:
Функция filter
находит все элементы в списке, соответствующие некоторому предикату; мы будем использовать filter (== i) list2
здесь, чтобы найти то, что нам нужно, затем добавим это к результату предыдущего шага. Поэтому каждый шаг будет выглядеть так:
step :: (Num a) => [a] -> a -> [a]
step list1 i = list1 ++ filter (== i) list2
Это обрабатывает внутренний цикл. Возвращаясь назад, нам нужно запустить это для каждого значения i
из списка [0..n]
, причем значение list1
передается на каждом шаге. Это как раз то, для чего нужны функции сгиба, и в этом случае step
это именно то, что нам нужно для левого сгиба:
list2 :: (Num a) => [a]
list2 = -- whatever goes here...
step :: (Num a) => [a] -> a -> [a]
step list1 i = list1 ++ filter (== i) list2
list1 :: (Num a) => a -> [a]
list1 n = foldl step [] [0..n]
Если вам интересно, где находится рекурсия, то и filter
, и foldl
делают это для нас. Как правило, лучше избегать прямой рекурсии, когда для этого есть функции более высокого уровня.
Тем не менее, алгоритм здесь глупый во многих отношениях, но я не хотел вдаваться в подробности, потому что казалось, что это отвлечет вас от вашего реального вопроса больше, чем поможет.