Как кодировать блок дела в Haskell, который работает с Int и Char - PullRequest
0 голосов
/ 01 ноября 2019

Я работаю над кодом на Haskell и наткнулся на проблему. В основном, я кодирую случай блока, чтобы проверить ввод, данный пользователем, который проверяет, является ли ввод любым из принятых символов, а также целыми числами

Я пытался кодировать другой блок случая после первого, но я не мог решить это. Я попытался закодировать блок if-else, который проверяет, является ли входное значение int даже раньше, чем блок case, но это также не удалось

Этот блок кода взят из середины функции:

if player == 1 then
           do newline
              putStr "Nim: r a / ? / q > "
              inp <- getLine
              let inputs = words inp
                  h = head inputs
              case h of
                 "q" -> do
                    play
                 "?" -> do
                    putStrLn "r is the row and a is amount to remove"
                    putStrLn "The person to remove the last piece wins"
                    play board player

                 -- The case below is the one that I can't seem to make work
                 -- Wrote Int -> do now just to make it clear what I'm looking to do 
                 Int -> do
                    let row = (read(inputs !! 0) :: Int)
                    let row = (read(inputs !! 1) :: Int)
                    if valid board row num then
                       play (move board row num) (next player)
                    else
                       do newline
                          putStrLn "ERROR: Invalid move"
                          play board player

Ожидаемые сценарии:

Nim: r a / ? / q > q
>> "quits game"

Nim: r a / ? / q > ?
>> r is the row and a is amount to remove
>> etc etc...

Nim: r a / ? / q > 2 2
>> "Perform move 2 2"

Первые два сценария работают. Моя единственная проблема состоит в том, чтобы интегрировать способ проверки, являются ли входные значения целыми числами в блоке case.

Любая помощь приветствуется

1 Ответ

7 голосов
/ 01 ноября 2019

Вводом будет всегда строка. Эта строка может содержать десятичное представление целого числа, но это ничего не меняет в типе.

Итак, вы хотите проверить, есть ли строка , которая может быть проанализирована как целое число. Хороший способ сделать это с помощью readMaybe. Однако это означает, что вы проверяете не саму h, а, скорее, readMaybe h, а на самом деле mapM readMaybe inputs (то есть пытаетесь прочитать все входных данных, проверить, все ли успешно). Но мы все еще можем использовать тот же блок case, нам просто нужно ввести модифицированное выражение для сопоставления с pattern guard . Пока мы в этом, давайте избавимся от h полностью, просто поместим inputs в выражение case:

          case inputs of
             ["q"] -> do
                play
             ["?"] -> do
                putStrLn "r is the row and a is amount to remove"
                putStrLn "The person to remove the last piece wins"
                play board player

             -- The case below is the one that I can't seem to make work
             -- Wrote Int -> do now just to make it clear what I'm looking to do 
             _ | Just [row, num] <- mapM readMaybe inputs
               -> if valid board row num then
                   ...
...