Рекурсия индексирования без использования параметра индекса

#haskell #recursion

#haskell #рекурсия

Вопрос:

Я пытаюсь написать рекурсивную функцию, чтобы что-то сделать, но на каждом шаге я хотел бы знать текущую глубину / индекс в дереве. Итак, как я могу добиться этого без использования параметра индекса в сигнатуре функции?

Что-то вроде:

 rec_fn n = do print index
              do_something n
              if n > 0
                then rec_fn (n-1)
                else print "end"
  

итак, как мне получить index , не делая что-то вроде:

 rec_fn n i = do print i
                do_something n
                if n > 0
                  then rec_fn (n-1) (i 1)
                  else print "end"
  

Ответ №1:

Ну, если ваша функция зависит от текущего индекса, она должна получить его в качестве аргумента. В противном случае вы нарушаете многие приятные функции чистых функций, такие как ссылочная прозрачность.

Если речь идет об избавлении от дополнительного параметра при вызове функции, вы можете использовать вспомогательную функцию, подобную следующей:

 rec_fn n = go n 0
    where go n i = do print i
                      do_something n
                      if n > 0
                         then go (n-1) (n 1)
                         else print "end"
  

Это шаблон, который довольно часто используется в Haskell.

Ответ №2:

Это действительно зависит от того, что именно не так с аргументом index. Вы хотите избавиться от него, потому что не хотите постоянно передавать его? Тогда ответ таков: вы не должны этого делать, потому что это затруднит понимание вашего кода. Однако, если вы настаиваете, вы можете использовать монаду состояния. Опять же: если ваша причина в удобстве, действительно не делайте этого. Почти во всех случаях, и особенно в вашем случае, это будет менее удобно в конце.

Законная причина для избавления от аргумента — это когда он избыточен, как в функции длины списка, которая всегда инициализирует свой накопитель с 0. В этом случае см. Ответ bzn.