Reputation: 958
I am making a simple Haskell todo list and I want to call a function "prompt" recursively and show different menu options based on user input. The problem is that upon initial call, prompt should expect to receive a function as one of the arguments that does NOT expect any arguments itself. Any following calls of "prompt" may need to call a function that DOES expect an argument passed to the function that is being passed to prompt.
Here is my code:
mainMenuOptions :: IO ()
mainMenuOptions = do
putStrLn ""
putStrLn "What would you like to do?"
putStrLn ""
putStrLn "OPTIONS"
putStrLn ""
putStrLn "'+' : add items | '-' : remove items"
subMenuOptions :: [String] -> String -> IO ()
subMenuOptions todos operation = do
putStrLn ""
if operation == "add"
then do putStrLn ("Type in the TASK you'd like to " ++ operation ++ ", then hit ENTER")
addListItemOptions todos
else do
putStrLn ("Type in the NUMBER of the task you'd like to " ++ operation ++ ", then hit ENTER")
putStrLn "('r' : return to the main menu)"
prompt :: [String] -> IO () -> IO ()
prompt todos showOptions = do
showTasks todos
showOptions
input <- getLine
interpret input todos
interpret :: String -> [String] -> IO ()
interpret input todos
| input == "r" = prompt todos mainMenuOptions
| input == "+" = prompt todos subMenuOptions "add"
| input == "-" = prompt todos subMenuOptions "remove"
| otherwise = do
putStrLn ""
putStrLn "SORRY, did not get that! Please enter a valid option."
prompt todos mainMenuOptions
main :: IO ()
main = do
putStrLn "Haskell ToDo List"
prompt [] mainMenuOptions
The error I get when I try to do this is:
Couldn't match expected type ‘[Char] -> IO ()’ with actual type ‘IO ()’ • The function ‘prompt’ is applied to three arguments, but its type ‘[String] -> IO () -> IO ()’ has only two
Upvotes: 4
Views: 1074
Reputation: 60463
On this line
| input == "+" = prompt todos subMenuOptions "add"
First of all, prompt
only takes 2 arguments, and we're passing it three, like the error said. For the second argument of prompt
we want to pass it an IO ()
using subMenuOptions
subMenuOptions :: [String] -> String -> IO ()
which says that if we give it a list of strings and a string, it will give us the IO ()
we are looking for. So:
| input == "+" = prompt todos (subMenuOptions todos "add")
We need the parentheses because
prompt todos subMenuOptions todos "add"
would mean we are passing 4 arguments to prompt
.
Upvotes: 5