I am basically making a task manager where a user can add a task or print out all tasks entered. my main function contains the options of what users do...
main = do
putStrLn "Below are the Options:\n\tadd\n\tprint\n\tsearch\nEnter Option:"
input <- getLine
if input == "add" then
buildList []
else if input == "print" then
putStrLn "printing"
else if input == "search" then
putStrLn "searching"
else
putStrLn "Please Enter add, print, search"
main
I am working on a function called buildList where the creation of the task happens:
buildList tasks = do
putStrLn "Enter a Task:"
input <- getLine
let mytask = input
putStrLn mytask --here to prevent an error
..and I assume I would need a global list since I will need it if I want to print out or search within it.
mytasklist = []
I have been stuck on this for a while as I am new to functional programming and Haskell. I understand that I can add two list together with or just do : to add at the start of the list, but I cant seem to figure out how to achieve this without an error.
update1: so would something like this work?
buildList tasks = do
putStrLn "Enter a Task:"
input <- getLine
let updatedTasks = tasks [input]
main
main = do
putStrLn "Below are the Options:\n\tadd\n\tprint\n\tsearch\nEnter Option:"
input <- getLine
if input == "add" then do
buildList []
else if input == "print" then
putStrLn "searchiwng"
else if input == "search" then
putStrLn "searching"
else
putStrLn "Please Enter add, print, search"
main
CodePudding user response:
You need to rename your main
function to something else, lets say go
(seems to be the traditional name for this pattern) and pass your task list as a parameter to go
. In the case of "add" the list you pass is the old list plus the new entry.
(Obviously this is a toy problem for learning, and this is a toy solution. Real programs have more sophisticated approaches. But this will do for now).
CodePudding user response:
Here is a simpler example, where you can increase or print an integer. You could try to adapt it to your task.
The trick is the recursive function loop
, which calls itself with the updated integer.
main :: IO ()
main = do
let loop :: Int -> IO ()
loop n = do
putStrLn "print/inc/quit?"
opt <- getLine
case opt of
"print" -> do print n; loop n -- recurse with the same n
"inc" -> loop (n 1) -- recurse with updated n
"quit" -> putStrLn "bye!" -- don't recurse to stop
_ -> do putStrLn "invalid option, try again"; loop n
-- call loop prividing the intial value
loop 0
You can also make loop
into a top-level function, and simply define main = loop 0
, if you prefer.
There are, of course, several other more advanced options in Haskell to do this, but I'd recommend you start with the above basic approach.
When you are more familiar with the language, you could try the following alternative options:
- the
StateT Int IO
monad allows IO operations and reading/writing to anInt
state IORef
s can also be used to model mutable data