Я пишу программу в Haskell для имитации боя между двумя игроками в D & D. Метод, который я использую, заключается в том, чтобы хранить игроков как Карты, а затем выполнять «атакующие» функции, которые принимают Player и вернуть IO Player с обновленным здоровьем, исходя из того, связана ли атака или нет. Весь мой код, кажется, работает по назначению, вплоть до последней функции, combat
. combat
должен взять двух игроков, первым атаковать второй, проверить, мертв ли второй, а если нет, повторите попытку с изменением порядка игроков. Вместо этого он, кажется, чередуется бесконечно.Haskell бесконечный цикл в блоке do
Сама функция выглядит следующим образом -
combat :: Player -> Player -> IO String
combat a b = do
damaged <- a `attacks` b
nextRound <- combat damaged a
return $ if (victor a damaged) /= "No victor yet" then (victor a damaged) else nextRound
attacks
функция принимает два игрока, проверяет идентификатор первого, и применяет соответствующую последовательность атак на второй. Он отлично работает, когда я использую его самостоятельно в GHCi, поэтому я не думаю, что там есть проблема.
Функция victor
принимает двух игроков, проверяет, является ли кто-либо из них мертвым (определяется как HP < = 0) и возвращает строку, описывающую результат. Когда я написал игрушечную версию combat
без какой-либо рекурсии, которая только что вернула «тест», когда условие не было выполнено, оно возвращало комбинацию «Player 1 выигрывает!». и «тест», поэтому я не думаю, что там есть проблема.
я наткнулся на подобный взгляд вопрос с LET привязок, где кто-то работает в бесконечном цикле, когда они имели такой код let n = n + 1
, но я не уверен, что если <-
работает таким же образом (или, если это было , как еще я мог бы написать его).
Этот код никогда не дойдет до строки 'return'.Каждый раз, когда вы вызываете «битву», он будет называть себя аргументами в обратном порядке, но никогда не будет завершен, потому что он снова вызовет себя, прежде чем сможет пройти мимо этой линии. –
@PeterHall Хорошо, это имеет смысл. Но, я получаю ошибку типа, когда я поместил «боевое повреждение» исключительно в оператор else (он хочет регулярную String, но он получает строку IO), которая является проблемой, которую я пытался решить, когда я положил рекурсию выше оператор if. – Kumarbis