eva*_*elf 3 haskell pattern-matching ghc
我在Haskell中编写了一个简单的程序,它播放了The Rust Programming Language一书中描述的猜谜游戏:
以下是它的工作原理:程序将生成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)
Run Code Online (Sandbox Code Playgroud)
代码有效,但GHC给了我一个警告 "Pattern match(es) are non exhaustive. In an equation for 'respond': Patterns not matched: _ _"
我用这两个下划线来表示Ints我作为函数参数的两个下划线respond.我不明白的是我没有涉及哪种情况.那些不是Maybe Ints或者什么特别的 - 函数需要两个有效的Ints,所以我只需要处理整数 - 我不认为有任何数字不能被视为大于,小于或等于另一个?
这只是GHC假设我没有涵盖所有情况因为我没有添加最后的otherwise =后卫吗?即使它在逻辑上涵盖所有情况.
另外,如果您有关于如何编写更多惯用Haskell的任何提示,我会很感激.我还在学习基础知识.
GHC根本不知道的一个a > b,a < b或者a == b必须求True.(实际上,有可能编写一个Ord违反这个假设的实例 - 尽管大多数程序员都不会考虑这样做,而且Int在这方面肯定会表现得很好.)
您可以通过使用完整的模式匹配来明确GHC明确表示已覆盖所有情况,例如
respond correct guess = case compare guess correct of
GT -> ...
LT -> ...
EQ -> ...
Run Code Online (Sandbox Code Playgroud)
GHC也有它的全面性检查的警卫的特殊情况otherwise和True,所以您可以添加(或更换)一名守卫这个作为一种替代解决方案.
respond correct guess
| guess > correct = ...
| guess < correct = ...
| otherwise = ...
Run Code Online (Sandbox Code Playgroud)