Home > OS >  Haskell : how to return from ( func :: IO a ) to main::IO
Haskell : how to return from ( func :: IO a ) to main::IO

Time:11-27

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 enter image description here

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.

  • Related