Написание циклов для интерактивного ввода-вывода: проблемы с do-notation и layout

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

В настоящее время я пытаюсь получить ввод пользователя, проверить, действителен ли он, если нет: распечатать ошибку и снова получить ввод; если действителен: произвести из него логическое значение.

Чтобы быть более точным, я хочу вводить да / нет, где 'y' будет давать True, 'n' даст False, а любой другой ввод будет печатать сообщение в в командной строке и попросите снова ввести y / n.

Например:

Continue? y/n:
> assd
Invalid input.
Continue? y/n:
> y
(something happens)
Continue? y/n:
> n
(Close program)

Запись в привычном формате, функция вроде этой:

boolean inputBool() {
    while(True) {
       str = input("Continue? y/n: ");
       if (str == "y") {
           return True;
       } else if (str == "n") {
           return False;
       } else {
           print("Invalid input");
       }
}

--main program--

while(inputBool()) {
    doSomething();
}

Так как я только начал haskell (на самом деле сегодня), у меня мало идеи, что я могу или не могу делать. Я думал о чем-то похожем на:

yesno :: Bool
yesno = do
        putStr "Continue? y/n: " 
        str <- readLn
        if (str == "y") then True else (
            if (str == "n") then False else (
                do
                putStrLn "Invalid input."
                yesno
            )    
        )

Что не работает по многим причинам. Моя главная проблема в том, что я не знаю, что делает это «делать». Я просто прочитал, что он используется, когда нужны операции io, и каким-то образом выполняет следующие выражения. Что для меня не имеет смысла после того, как я прочитал, что в haskell все оценивается как значение. Что значит "делать"? Кроме того, какой отступ ожидается? Вроде бы случайно. Я знаю, что функция должна вычислить мое логическое значение, что, похоже, невозможно с использованием этой операции «do». Но тогда как мне распечатать что-то на консоли и при этом сделать это частью выражения, которое оценивается как True или False?

Спасибо за любую помощь.

(Кстати, есть ли какие-нибудь активные форумы haskell в Интернете? Я не удалось найти = /)

12
задан Don Stewart 17 April 2011 в 19:11
поделиться