如何在 Haskell 中编写与 Int 和 Char 一起使用的 case 块

How to code a case block in Haskell that works with Int and Char

我在编写一些 Haskell 代码时偶然发现了一个问题。基本上我正在编写一个块的案例来检查用户给出的输入,检查输入是否是任何可接受的字符以及 Ints

我试过在第一个 case 块之后编写另一个 case 块,但我无法解决这个问题。我尝试编写一个 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 块中的输入是否为整数。

感谢任何帮助

输入将始终是一个字符串。该字符串可能包含整数的十进制表示形式,但这不会改变类型的任何内容。

所以,你要检查的是它是否是一个字符串可以解析为整数。一个很好的方法是使用 readMaybe。这意味着您不是在检查 h 本身,而是在 readMaybe h 上检查,实际上是在 mapM readMaybe inputs 上检查(即尝试读取 all输入,检查是否全部成功)。但是我们仍然可以使用相同的 case 块,我们只需要引入修改后的表达式来匹配 模式守卫 。当我们这样做的时候,让我们完全摆脱 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
                   ...