There are a few ways to test values like this, but the way that’s most similar to what you’ve written is to use the extension called MultiWayIf, available since GHC 7.6 (September 2012). Add the pragma:
{-# LANGUAGE MultiWayIf #-}
To the top of your source file (or use :set -XMultiWayIf in GHCi) and you can write the following:
choice <- getLine
-- Simply add the ‘if’ keyword here.
if
| choice == "Computer" -> main
| choice == "2 Player" -> tictactoe
| otherwise -> putStrLn "That's not a choice!"
Ordinarily, guard syntax | condition only works in two places: in definitions (where a guard goes after the name & arguments, before the = symbol) and in case (where it goes after the pattern, before the -> symbol):
doubleIfEven :: Int -> Int
-- Definition
doubleIfEven x
| even x = x * 2
--------
| otherwise = x
-----------
doubleIfJustEven :: Maybe Int -> Maybe Int
doubleIfJustEven mx
-- Match
= case mx of
Just x
| even x -> Just (x * 2)
--------
| otherwise -> Just x
-----------
Nothing -> Nothing
Here are the alternatives:
case expressions, in this case where you’re only testing for (structural) equality on strings:
case choice of
"Computer" -> main
"2 Player" -> tictactoe
_ -> putStrLn "That's not a choice!"
A local definition in a where clause or let binding:
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
Nested if expressions:
if choice == "Computer" then main
else if choice == "2 Player" then tictactoe
else putStrLn "That's not a choice!"
case with a dummy pattern and guards (an old idiom):
case () of
_ | choice == "Computer" -> main
| choice == "2 Player" -> tictactoe
| otherwise -> putStrLn "That's not a choice!"
#1 is most common for matching; #2 is used if you need guards and either want to avoid MultiWayIf to support old compilers, or simply want to factor out the logic into a separate definition for readability; #3 and #4 aren’t very common or idiomatic, but there’s nothing “wrong” with them.