функция отображения, рекурсивно

#haskell #recursion #map-function

Вопрос:

Итак, у меня есть функция, которая принимает три переменные. Переменная y вызывается другой функцией, которая превратит ее в список.

Я хочу применить карту к этому списку переменных. Чтобы я мог выполнять рекурсию через функцию, используя все элементы списка по одному за раз.

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

 search :: State -> Int -> Int -> Int 
search state n1 n2 = case n1 of 
  0 -> 1 * n2
  num -> average( map (search s) n1-1 n2)
     where s = turnStateToList s
 

я не включил состояние поворота в список, но я не думаю, что это необходимо для ответа на вопрос. в основном это приведет к созданию списка новых государств. думайте об этом как о дереве.

ошибки, которые я получаю, следующие

 * map is applied to too many functions 
* y has been given arguments however yy takes in 0 arguments 
 

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

Комментарии:

1. where y = anotherfunc y не имеет смысла, так как вы определяете y в терминах y , поэтому рекурсивное определение.

2. Честно говоря, все это не имеет особого смысла. Пожалуйста, приведите пример того, как вы на самом деле надеетесь использовать func на практике. (И, кстати, не вызывайте функции func !)

3. «Я хочу применить сопоставление к переменной y, чтобы каждый раз, когда я вызываю функцию, задавалось другое значение y из списка y». Я изо всех сил пытаюсь понять, что это на самом деле значит. Можете ли вы показать несколько примеров ввода функций и желаемого вывода?

4. Я обновил вопрос. Спасибо за помощь и обратную связь.

5. не могли бы вы, пожалуйста, включить некоторые входные данные и ожидаемые результаты? Нам трудно понять, что вы на самом деле хотите сделать, и это, вероятно, может очень помочь. Как бы то ни было, я действительно старался, но понятия не имею, чего вы здесь пытаетесь достичь.

Ответ №1:

Как упоминалось в комментариях к вашему вопросу, в Haskell вы можете определять переменные рекурсивно, поэтому s = turnStateToList s это не означает, что вы создаете новое s , которое получает значение turnStateToList старого s. Вместо этого он определяет s рекурсивно в терминах самого себя, что приводит к бесконечному выражению s = turnStateToList (turnStateToList (turnStateToList ... , которое, вероятно, не то, что вы хотите.

Чтобы map заполнить список, сохраняя некоторые аргументы фиксированными, вы можете ввести анонимную функцию, в этом случае, я думаю, вы хотите s'' -> search s'' (n1 - 1) n2 (круглые скобки вокруг n1 - 1 необходимы!).

О, и я думаю, что вы перепутали state и s случайно.

Итак, с минимальными изменениями в вашем стиле, я думаю, вам нужен этот код:

 search :: State -> Int -> Int -> Int 
search s n1 n2 = case n1 of 
  0 -> 1 * n2
  num -> average( map (s'' -> search s'' (n1 - 1) n2) s')
     where s' = turnStateToList s
 

Я думаю, что более идиоматично избегать оператора case и избегать привязки turnStateToList s к переменной, тогда вы получите этот код:

 search :: State -> Int -> Int -> Int
search _ 0  n2 = n2
search s n1 n2 = average $ map (s' -> search s' (n1 - 1) n2) (turnStateToList s)