Haskell 如何使用带putStrLn的防护装置?

Haskell 如何使用带putStrLn的防护装置?,haskell,Haskell,我正在尝试编写一个函数,它将执行两种不同的游戏模式,分别定义为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

我正在尝试编写一个函数,它将执行两种不同的游戏模式,分别定义为
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!"
tictac::IO()
tictac=do
putStrLn“你想玩电脑游戏还是
其他玩家?输入:2个玩家或计算机“

choice有一组有限的地方可以使用防护装置-它们只在函数定义中最常用。在这种情况下,您可能会寻找
case
语句:

choice <- getLine
case choice of
     "Computer" -> main
     "2 Player" -> tictactoe
      _         -> putStrLn "That's not a choice!"

但是这样做没有任何好处。

您可以在有限的地方使用防护装置-它们通常只在函数定义中使用。在这种情况下,您可能会寻找
case
语句:

choice <- getLine
case choice of
     "Computer" -> main
     "2 Player" -> tictactoe
      _         -> putStrLn "That's not a choice!"

但是这样做没有任何好处。

有几种方法可以测试这样的值,但最类似于您编写的方法是使用名为
MultiWayIf
的扩展,该扩展自GHC 7.6(2012年9月)起提供。添加pragma:

{-# LANGUAGE MultiWayIf #-}
到源文件的顶部(或在GHCi中使用
:set-xmultivayif
),您可以编写以下内容:

choice <- getLine
-- Simply add the ‘if’ keyword here.
if
  | choice == "Computer" -> main
  | choice == "2 Player" -> tictactoe
  | otherwise -> putStrLn "That's not a choice!"

以下是备选方案:

  • case
    表达式,在这种情况下,您只测试字符串的(结构)相等性:

    case choice of
      "Computer" -> main
      "2 Player" -> tictactoe
      _ -> putStrLn "That's not a choice!"
    
  • where
    子句或
    let
    绑定中的局部定义:

    tictac :: IO ()
    tictac = do 
      putStrLn "Would you like to play against the computer or\
               \ another player? Enter: 2 Player or Computer"
      choice <- getLine
      check choice
    
      where
        check choice
          | choice == "Computer" = main
          | choice == "2 Player" = tictactoe
          | otherwise = putStrLn "That's not a choice!"
    
    ----
    
    tictac :: IO ()
    tictac = do 
      putStrLn "Would you like to play against the computer or\
               \ another player? Enter: 2 Player or Computer"
      let
        check choice
          | choice == "Computer" = main
          | choice == "2 Player" = tictactoe
          | otherwise = putStrLn "That's not a choice!"
      choice <- getLine
      check choice
    
  • case
    带有虚拟图案和防护装置(一个古老的习惯用法):


  • #1是最常见的匹配#如果您需要保护,或者希望避免使用
    MultiWayIf
    来支持旧的编译器,或者只是希望将逻辑分解成一个单独的定义以便于可读,则使用2#3和#4不是很常见或习惯用法,但它们没有“错”。

    有几种方法可以测试这样的值,但最类似于您编写的方法是使用名为
    MultiWayIf
    的扩展,该扩展自GHC 7.6(2012年9月)开始提供。添加pragma:

    {-# LANGUAGE MultiWayIf #-}
    
    到源文件的顶部(或在GHCi中使用
    :set-xmultivayif
    ),您可以编写以下内容:

    choice <- getLine
    -- Simply add the ‘if’ keyword here.
    if
      | choice == "Computer" -> main
      | choice == "2 Player" -> tictactoe
      | otherwise -> putStrLn "That's not a choice!"
    

    以下是备选方案:

  • case
    表达式,在这种情况下,您只测试字符串的(结构)相等性:

    case choice of
      "Computer" -> main
      "2 Player" -> tictactoe
      _ -> putStrLn "That's not a choice!"
    
  • where
    子句或
    let
    绑定中的局部定义:

    tictac :: IO ()
    tictac = do 
      putStrLn "Would you like to play against the computer or\
               \ another player? Enter: 2 Player or Computer"
      choice <- getLine
      check choice
    
      where
        check choice
          | choice == "Computer" = main
          | choice == "2 Player" = tictactoe
          | otherwise = putStrLn "That's not a choice!"
    
    ----
    
    tictac :: IO ()
    tictac = do 
      putStrLn "Would you like to play against the computer or\
               \ another player? Enter: 2 Player or Computer"
      let
        check choice
          | choice == "Computer" = main
          | choice == "2 Player" = tictactoe
          | otherwise = putStrLn "That's not a choice!"
      choice <- getLine
      check choice
    
  • case
    带有虚拟图案和防护装置(一个古老的习惯用法):


  • #1是最常见的匹配#如果您需要保护,或者希望避免使用
    MultiWayIf
    来支持旧的编译器,或者只是希望将逻辑分解成一个单独的定义以便于可读,则使用2#3和#4不是很常见或习惯用法,但它们没有什么“错误”。

    除了顶级功能,您还可以在其他地方使用防护装置
    case
    ,在
    where
    let
    中定义函数,甚至在
    let
    @Potato44中定义不带参数的值。感谢您指出可以在
    case
    中使用保护,我以前从未见过这种语法。我改变了开场白,清楚地表明我谈论的是所有功能,而不仅仅是顶级功能。我还没有找到你最后一个案例的例子,你能给我指一个例子吗?你提到的链接的提问者在
    let
    中使用了它,关于值
    brainiac
    ->…|…
    可以替换为
    if | choice==“Computer”->…| choice==“2 Player”->…|…
    使用扩展名
    MultiWayIf
    ,该扩展名自GHC 7.6以来一直可用。我不喜欢警卫在布尔条件后使用“=”符号。这不是一个等式,而是一个结果,一个箭头。你可以在顶级函数之外的其他地方使用防护
    case
    ,在
    where
    let
    中定义函数,甚至在
    let
    @Potato44中定义不带参数的值。感谢您指出可以在
    case
    中使用保护,我以前从未见过这种语法。我改变了开场白,清楚地表明我谈论的是所有功能,而不仅仅是顶级功能。我还没有找到你最后一个案例的例子,你能给我指一个例子吗?你提到的链接的提问者在
    let
    中使用了它,关于值
    brainiac
    ->…|…可以替换为
    if | choice==“Computer”->…| choice==“2 Player”->…|…
    使用扩展名
    MultiWayIf
    ,该扩展名自GHC 7.6以来一直可用。我不喜欢警卫在布尔条件后使用“=”符号。这不是一个方程式,而是一个结果,一个箭头。