我用 Haskell 写了一个简单的程序来播放《The Rust 编程语言》一书中描述的猜谜游戏:
它的工作原理如下:程序将生成一个 1 到 100 之间的随机整数。然后它会提示玩家输入猜测值。输入猜测后,会显示猜测是否太低或太高。如果猜测正确,游戏将打印祝贺信息并退出。
这是我写的:
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: _ _"
我用这两个下划线代表两个Ints
我有作为论据respond
功能。我不明白的是我没有涵盖哪种情况。那些不是Maybe Int
s 或任何特殊的东西——函数requires两个有效Ints
,所以我只需要处理整数——而且我不认为有任何数字不能被视为大于、小于或等于另一个?
这是否只是 GHC 假设我没有涵盖所有情况,因为我没有添加最终的otherwise =
警卫?尽管它在逻辑上涵盖了所有情况。
另外,如果您有任何关于如何编写更惯用的 Haskell 的提示,我将不胜感激。我仍在学习基础知识。
GHC 根本不知道其中之一a > b
, a < b
, or a == b
必须评估为True
。 (事实上,可以写一个Ord
违反这一假设的实例——尽管大多数程序员不会考虑这样做,当然也不会考虑这样做Int
在这方面会表现得很好。)
您可以通过使用完整的模式匹配来使 GHC 明显看出您已经涵盖了所有情况,例如
respond correct guess = case compare guess correct of
GT -> ...
LT -> ...
EQ -> ...
GHC 的守卫详尽性检查器也有一个特殊情况otherwise
and True
,因此您可以添加(或替换)其中一个防护装置作为替代解决方案。
respond correct guess
| guess > correct = ...
| guess < correct = ...
| otherwise = ...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)