【发布时间】:2019-06-09 10:13:29
【问题描述】:
我正在阅读一些有关 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返回一个布尔值(携带真或假)而不是更多信息类型(携带 RPS 值或错误)。在这种情况下,Maybe RPS就足够了。有时你想要Either SomeError RPS,如果你有多个错误要返回。Bool在 Haskell 中不像在其他一些语言中那样频繁使用。
标签: haskell io typechecking