Haskell getLine в функции в противном случае - PullRequest
0 голосов
/ 29 октября 2018

Я действительно новичок в Haskell и пытаюсь выучить некоторые простые функции.

Я сделал несколько опций с помощью таких функций:

displayOptions :: Int -> String
displayOptions option
    | option == 0 = "1 - Shop\n2 - Fight Monsters\n3 - Inn\n4 - Monk"
    | otherwise = "invalid"

Затем я получаю пользовательский ввод с getLine

choice <- getLine

А затем я отображаю второй вариант, например,

playerChoice :: String -> String
playerChoice option
    | option == "1" = "Sword - 50gp\nShield - 100gp"
    | option == "2" = "You go fight some monsters outside town."
    | option == "3" = "You go to the town Inn."
    | option == "4" = "You go see the holy monk."
    | otherwise = "You entered invalid information...\n" ++ displayOptions(0)

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

Итак, моя основная программа будет выглядеть примерно так:

main = do
    putStrLn "The king has sent you on the journey to become a master."
    putStrLn $ "What would you like to do?"
    putStrLn $ displayOptions(0)
    choice <- getLine
    putStrLn $ playerChoice(choice)

Ответы [ 2 ]

0 голосов
/ 29 октября 2018
  1. Вам следует изменить тип возвращаемого значения на Either String String, чтобы получить сообщение об ошибке. Для получения более подробной информации, смотрите документы для типа Either.

  2. В Haskell у нас нет традиционных циклических структур, таких как for или while, вместо этого мы используем рекурсивные вызовы. См., Например, цикл while в Haskell с условием .

0 голосов
/ 29 октября 2018

Вы должны изменить тип возвращаемого значения на IO String вместо String.

Однако, возможно, вы хотите вернуть либо String String, чтобы функция указала, что он вернул текст прогресса игры Right "You do something", либо произошел сбой с объяснением ошибки Left "Not an option".

Затем вы вызываете цикл до тех пор, пока не получите значение Right, и каждый раз, когда вы получаете значение Left, вы печатаете текст и спрашиваете снова.

Я уверен, что есть немного лучший способ, но вот небольшой исправленный код:

module Main where

playerChoice :: String -> Either String String
playerChoice option
    | option == "1" = Right "Sword - 50gp\nShield - 100gp"
    | option == "2" = Right "You go fight some monsters outside town."
    | option == "3" = Right "You go to the town Inn."
    | option == "4" = Right "You go see the holy monk."
    | otherwise = Left "You entered invalid information..."

displayOptions :: Int -> String
displayOptions option
    | option == 0 = "1 - Shop\n2 - Fight Monsters\n3 - Inn\n4 - Monk\n"
    | otherwise = "invalid"

main = do
    let progress whathappens = do
        putStrLn whathappens
        let tryAsk prompt = do
            putStrLn prompt
            choice <- getLine
            either tryAsk progress $ playerChoice(choice)
        tryAsk $ displayOptions(0) ++ "What would you like to do?"
    progress "The king has sent you on the journey to become a master."

если вы import Data.Function, то вы также можете написать это следующим образом - что в этом случае, вероятно, не лучше, но это хороший мелкий шаг в увлекательную часть haskell:

fix (\moreProgress whathappens -> do
    putStrLn whathappens
    fix (\askAgain prompt -> do
        putStrLn prompt
        choice <- getLine
        either askAgain moreProgress $ playerChoice(choice))
        $ displayOptions(0) ++ "What would you like to do?")
    $ "The king has sent you on the journey to become a master."
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...