52700.fb2 Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 230

Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 230

parseQuery = un

wrongMove :: IO ()

wrongMove = putStrLn ”Не могу распознать ход.” >> remindMoves

showAsk :: IO ()

showAsk = un

remindMoves :: IO ()

remindMoves = un

Механизм распознавания похож на случай с распознаванием числа. Значение завёрнуто в тип Maybe. И в

самом деле функция определена лишь частично, ведь не все строки кодируют то, что нам нужно.

Функции parseQuery и remindMoves тесно связаны. В первой мы распознаём ввод пользователя, а во вто-

рой напоминаем пользователю как мы закодировали его запросы. Тут стоит остановиться и серьёзно поду-

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

отвлечёмся от этой задачи, она слишком серьёзная. Оставим её на потом, а пока проверим не ушли ли мы

слишком далеко, возможно наша программа потеряла смысл. Проверим типы!

*Loop> :r

[1 of 2] Compiling Game

( Game. hs, interpreted )

[2 of 2] Compiling Loop

( Loop. hs, interpreted )

Ok, modules loaded: Game, Loop.

Пятнашки | 207

Приведём код в порядок

Нам осталось дописать функции распознавания запросов и несколько маленьких функций с фразами и

модуль Loop будет готов. Но перед тем как сделать это давайте упорядочим функции. Видно, что у нас выде-

лилось несколько задач по типу общения с пользователем. У нас есть задачи, в которых мы что-то показываем

пользователю, меняем состояние экрана и есть задачи, в которых мы просим от пользователя какие-то дан-

ные, ожидаем запросы функцией getLine. Также в самом верху выражения программы у нас расположены

функции, которые координируют действия остальных, это третья группа. Сгруппируем функции по этому

принципу.

Основные функции

play :: IO ()

play = greetings >> setup >>= gameLoop

gameLoop :: Game -> IO ()

gameLoop game

| isGameOver game

= showResults game >> setup >>= gameLoop

| otherwise

= showGame game >> askForMove >>= reactOnMove game

setup :: IO Game

setup = putStrLn ”Начнём новую игру?” >>

putStrLn ”Укажите сложность (положительное целое число): ” >>

getLine >>= maybe setup shuffle . readInt

Запросы от пользователя (getLine)

reactOnMove :: Game -> Query -> IO ()

reactOnMove game query = case query of

Quit

-> quit

NewGame n

-> gameLoop =<< shuffle n

Play