Home > database >  Haskell: How would I add input value from a function to a global list?
Haskell: How would I add input value from a function to a global list?

Time:10-19

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 an Int state
  • IORefs can also be used to model mutable data
  • Related