I have the following defined that displays a menu and would like 'r' to return to main :: IO.
displayMenu is of type IO BaseProduct and main of type IO so cannot have
"r" -> do return main
displayMenu :: IO BaseProduct
displayMenu = do
putStrLn "\n--- Choose and Item ---"
putStrLn "1 - Basic\n2 - Super\n3 - Supreme\n4 - SoftDrink\n5 - Breadsticks\nr - Return"
line <- getLine
case line of
"1" -> do
return basicPizza
"2" -> do
return superPizza
"r" -> do
return ???
Also : is the rest of my code for displayMenu fine? note - first app I am writing based on alvin alexanders post
CodePudding user response:
A function cannot choose a function it's returning to. Whoever calls displayMenu
will regain the flow after it returns. I think, what you mean, is how to tell apart a choice of a product (has value) from a Return
menu choice (no value). One way to do that is with Maybe
type:
displayMenu :: IO (Maybe BaseProduct)
displayMenu = do
putStrLn "\n--- Choose and Item ---"
putStrLn "1 - Basic\n2 - Super\n3 - Supreme\n4 - SoftDrink\n5 - Breadsticks\nr - Return"
line <- getLine
case line of
"1" -> do
return $ Just basicPizza
"2" -> do
return $ Just superPizza
"r" -> do
return Nothing
Alternatively (and I would prefer that way), you can create a custom type for the menu action:
data MenuAction = Choice BaseProduct | Back
displayMenu :: IO MenuAction
displayMenu = do
putStrLn "\n--- Choose and Item ---"
putStrLn "1 - Basic\n2 - Super\n3 - Supreme\n4 - SoftDrink\n5 - Breadsticks\nr - Return"
line <- getLine
case line of
"1" -> do
return $ Choice basicPizza
"2" -> do
return $ Choice superPizza
"r" -> do
return Back
In both cases, the caller should be changed to handle the result accordingly.