我正在学习Haskell的入门材料,尝试完成命令行上愚蠢的石头剪刀布实现。
我认为在输入上使用类型保护就足以让编译器相信输入是RPS
类型,但不幸的是,它并不是这样。
如何告诉编译器输入数据是某种类型呢?
data RPS = Rock | Paper | Scissors
_shoot :: RPS -> RPS -> String
_shoot Rock Paper = "Paper beats rock, you win!"
_shoot Paper Rock = "Paper beats rock, you loose."
_shoot Rock Scissors = "Rock beats scissors, you loose."
_shoot Scissors Rock = "Rock beats scissors, you win!"
_shoot Paper Scissors = "Scissors beats paper, you win!"
_shoot Scissors Paper = "Scissors beats paper, you loose!"
_shoot Rock Rock = "Tie!"
_shoot Scissors Scissors = "Tie!"
_shoot Paper Paper = "Tie!"
isRPS :: String -> Bool
isRPS s = elem s ["Rock", "Paper", "Scissors"]
main :: IO ()
main = do
putStrLn "Rock, Paper, or Scissors?"
choice <- getLine
if isRPS choice -- this was my idea but is apparently not good enough
then putStrLn (_shoot choice Rock)
-- ^^^^^^
-- Couldn't match type ‘[Char]’ with ‘RPS’ Expected type: RPS Actual type: String
else putStrLn "Invalid choice."
isRPS
返回一个布尔值(包含 true 或 false),而不是更具信息量的类型(包含 RPS 值或错误)。在这种情况下,Maybe RPS
就足够了。如果你有多个错误需要返回,有时候你会想要使用Either SomeError RPS
。在 Haskell 中,Bool
没有像其他一些语言那样频繁使用。 - chi