如何使用putStrLn的后卫?

Sim*_*tha 1 haskell

我正在尝试编写一个函数来执行2种不同的游戏模式,这些游戏模式被定义为tictactoe :: IO ()main :: IO ().我输入'|'时出现解析错误.我不明白我做错了什么.有人可以向我解释一下吗?

tictac :: IO()
tictac = do 
       putStrLn "Would you like to play against the computer or 
                 another player? Enter: 2 Player or Computer"
       choice <- getLine
         |choice == "Computer" = main
         |choice == "2 Player" = tictactoe
         |otherwise = putStrLn "That's not a choice!"
Run Code Online (Sandbox Code Playgroud)

hne*_*atl 5

有一组有限的地方你可以使用警卫 - 它们最常用于功能定义.在这种情况下,您可能正在寻找case声明:

choice <- getLine
case choice of
     "Computer" -> main
     "2 Player" -> tictactoe
      _         -> putStrLn "That's not a choice!"
Run Code Online (Sandbox Code Playgroud)

_模式匹配任何东西,"删除"剩余的模式.它在这里使用是类似的otherwise,虽然otherwise实际上只是语法糖,true因为在警卫中的表达是boolean.

它与守卫不完全相同,因为守卫在case模式匹配时评估布尔表达式,但它有效.一个更准确的双重守卫就是if表达式,但是case当你可以使用它时语法更好.有关更多示例,请查看Wiki 上的控制结构页面.


正如评论中指出的那样,也可以在case表达式中使用保护- 你可以在规范这个问题/答案中看到这一点.它确实需要至少一个模式匹配,这在这里很难看 - 您可以使用此处描述"hack"来执行以下操作:

case () of
 _ | choice == "Computer" -> main
   | choice == "2 Player" -> tictactoe
   | otherwise            -> putStrLn "That's not a choice!"
Run Code Online (Sandbox Code Playgroud)

但这样做没有任何好处.

  • _ |的case()选择=="计算机" - > ... | 选择=="2球员" - > ... | ......`可以替换为`if | 选择=="计算机" - > ... | 选择=="2球员" - > ... | ...`使用`MultiWayIf`扩展,自GHC 7.6起可用. (2认同)