Haskel. Проблема с иммутабельностью в рекурсивной функции
Пишу небольшую консольную игрушку, есть карта вида:
#######
#%....#
#.....#
#######
А также функция вечно вызывающая саму себя, этакий mainloop. Каждый вызов функция запрашивает ввод символа - wasd например, и символ % должен перемещаться по карте в соответствующем направлении. Проблема же возникла с обновлением карты в бесконечной рекурсии, в императивных языках я бы просто всегда менял карту, а вот в haskell`e решение я придумать не могу. Заранее спасибо.
Ответы (1 шт):
Стандартный способ отслеживать состояние алгоритма от одной итерации к другой - это передавать его в качестве параметра:
mainloop currentMap = do
playerCommand <- readLn
let newMap = modifyMap currentMap playerCommand
mainloop newMap
main = mainloop initialMap
Разумеется в Хаскелле также есть поддержка настоящих изменяемых ячеек памяти, которыми можно пользоваться точно так же, как изменяемыми переменными в других языках. Пожалуй самый простой вариант - это IORef:
mainloop mapRef = do
currentMap <- readIORef mapRef
playerCommand <- readLn
let newMap = modifyMap currentMap playerCommand
writeIORef newMap mapRef
mainloop mapRef
main = mainloop =<< newIORef initialMap
Но, конечно же, в данном случае изменяемые ячейки - это из пушки по воробьям. Их вообще следует избегать по мере возможности, ибо изменяемая память - большой источник ошибок. Хаскель не зря весь неизменяемый, не просто так.