非详尽的模式匹配只是因为我离开了 `otherwise =`?
Non-exhaustive pattern matches only because I left off `otherwise =`?
我在 Haskell 中写了一个简单的程序来播放 the guessing game described in The Rust Programming Language book:
Here’s how it works: the program will generate a random integer between 1 and 100. It will then prompt the player to enter a guess. After entering a guess, it will indicate whether the guess is too low or too high. If the guess is correct, the game will print congratulations and exit.
这是我写的:
import Control.Monad (when)
import System.Random (randomRIO)
-- | Check if the guess is correct, otherwise provide a hint
respond :: Int -> Int -> String
respond correct guess
| guess > correct = "Smaller than " ++ show guess
| guess < correct = "Larger than " ++ show guess
| guess == correct = "Correct! " ++ show correct
-- | Main game loop; prompt for input and repeat until guessed correctly
play :: Int -> IO ()
play x = do
putStr "Guess: "
guess <- read <$> getLine
putStrLn $ respond x guess
when (guess /= x) $ play x
-- | Start the game with a random number between 1 and 100
main :: IO ()
main = play =<< randomRIO (1, 100)
代码有效,但 GHC 警告我 "Pattern match(es) are non exhaustive. In an equation for 'respond': Patterns not matched: _ _"
我用这两个下划线来表示我作为 respond
函数参数的两个 Ints
。我不明白的是我没有涵盖哪种情况。这些不是 Maybe Int
或任何特殊的东西 — 函数 需要 两个有效的 Ints
,所以我只需要处理整数 — 我不认为有任何数字不能被视为大于、小于或等于另一个吗?
这只是 GHC 假设我没有涵盖所有情况,因为我没有添加最后的 otherwise =
守卫吗?尽管它在逻辑上涵盖了所有情况。
此外,如果您有任何关于如何写得更地道的提示 Haskell,我将不胜感激。我还在学习基础知识。
编译器只进行静态语义分析。这无法看出这三种情况涵盖了所有可能的输入,因为运算符的含义是在运行时确定的。
你的代码被证明是正确的。如果想避免GHC的warning,可以将final条件改为otherwise
.
GHC 根本不知道 a > b
、a < b
或 a == b
之一必须计算为 True
。 (事实上 ,有可能编写一个违反此假设的 Ord
实例——尽管大多数程序员不会考虑这样做,当然 Int
的实例在这方面表现得很好。)
您可以通过使用完整的模式匹配来使 GHC 显而易见您已经涵盖了所有情况,例如
respond correct guess = case compare guess correct of
GT -> ...
LT -> ...
EQ -> ...
GHC 在其针对守卫 otherwise
和 True
的详尽检查器中也有一个特例,因此您可以添加(或替换)其中一个守卫作为替代解决方案。
respond correct guess
| guess > correct = ...
| guess < correct = ...
| otherwise = ...
我在 Haskell 中写了一个简单的程序来播放 the guessing game described in The Rust Programming Language book:
Here’s how it works: the program will generate a random integer between 1 and 100. It will then prompt the player to enter a guess. After entering a guess, it will indicate whether the guess is too low or too high. If the guess is correct, the game will print congratulations and exit.
这是我写的:
import Control.Monad (when)
import System.Random (randomRIO)
-- | Check if the guess is correct, otherwise provide a hint
respond :: Int -> Int -> String
respond correct guess
| guess > correct = "Smaller than " ++ show guess
| guess < correct = "Larger than " ++ show guess
| guess == correct = "Correct! " ++ show correct
-- | Main game loop; prompt for input and repeat until guessed correctly
play :: Int -> IO ()
play x = do
putStr "Guess: "
guess <- read <$> getLine
putStrLn $ respond x guess
when (guess /= x) $ play x
-- | Start the game with a random number between 1 and 100
main :: IO ()
main = play =<< randomRIO (1, 100)
代码有效,但 GHC 警告我 "Pattern match(es) are non exhaustive. In an equation for 'respond': Patterns not matched: _ _"
我用这两个下划线来表示我作为 respond
函数参数的两个 Ints
。我不明白的是我没有涵盖哪种情况。这些不是 Maybe Int
或任何特殊的东西 — 函数 需要 两个有效的 Ints
,所以我只需要处理整数 — 我不认为有任何数字不能被视为大于、小于或等于另一个吗?
这只是 GHC 假设我没有涵盖所有情况,因为我没有添加最后的 otherwise =
守卫吗?尽管它在逻辑上涵盖了所有情况。
此外,如果您有任何关于如何写得更地道的提示 Haskell,我将不胜感激。我还在学习基础知识。
编译器只进行静态语义分析。这无法看出这三种情况涵盖了所有可能的输入,因为运算符的含义是在运行时确定的。
你的代码被证明是正确的。如果想避免GHC的warning,可以将final条件改为otherwise
.
GHC 根本不知道 a > b
、a < b
或 a == b
之一必须计算为 True
。 (事实上 ,有可能编写一个违反此假设的 Ord
实例——尽管大多数程序员不会考虑这样做,当然 Int
的实例在这方面表现得很好。)
您可以通过使用完整的模式匹配来使 GHC 显而易见您已经涵盖了所有情况,例如
respond correct guess = case compare guess correct of
GT -> ...
LT -> ...
EQ -> ...
GHC 在其针对守卫 otherwise
和 True
的详尽检查器中也有一个特例,因此您可以添加(或替换)其中一个守卫作为替代解决方案。
respond correct guess
| guess > correct = ...
| guess < correct = ...
| otherwise = ...