Reputation: 381
I am trying to stop my program from stopping after the loop in a function ends. Let me first give some background - After a recent failed attempt at Haskell (Here) i have been working through a number of tutorials and have been able to successfully create myself lists containing both a name and priority (Below, working Code - Apologies if the copy/paste has miss-indented it).
module Main where
-- Function Main, gather details, then print
main :: IO ()
main = do info <- gatherInfo
let names = info
putStrLn . unlines . map printDetails $ names
-- Function to Get the Info
gatherInfo :: IO [(String, Int)]
gatherInfo = do putStr "Name: "
name <- getLine
if name == "quit"
then return []
else do priority <- getPri
let info = (name,priority)
otherInfo <- gatherInfo
return $ info : otherInfo
-- Function to get Priority
getPri :: IO Int
getPri = do putStr "Priority: "
input <- getLine
let parsed = reads input
if parsed == []
then do putStrLn "Incorrect Entry, please enter again"
getPri
else return $ fst $ parsed !! 0
--Function to print each detail
printDetails :: (String, Int) -> String
printDetails (name, priorityScore) = "Name: " ++ name ++ "Priority: " ++ show priorityScore
This code will print the following output(incl user input):
Patient Name: test1
Patient Priority: 1
Patient Name: test2
Patient Priority: 2
Patient Name: quit
Patient name: test1 Priority: 1
Patient name: test2 Priority: 2
As you can see, the list items are entered and then upon entering 'quit' the code prints the list contents.
The problem i have is that upon entering 'quit' and printing the list items, when i enter back into the program the items have gone.
What i am trying to achieve is running the gatherInfo function, then printing the list (in its entirety) and then going back to the gatherInfo function to add another item. For example, my output may be like:
Patient Name: test1
Patient Priority: 1
Patient name: test1 Priority: 1
Patient Name: test2
Patient Priority: 2
Patient name: test1 Priority: 1
Patient name: test2 Priority: 2
Patient Name: quit (Quit program, doesn't matter what happens now)
I have made several attempts at implementing this; for example, calling my printDetails function during each gatherInfo loop to print 'info', but with little success. How can i implement this into my design?
Upvotes: 1
Views: 527
Reputation: 1693
I suggest you do this:
Modify your gather info function so it takes info of only one patient.
Then create another function, let's call it main':
main' patients = do patient <- gatherInfo
if (fst patient == "quit")
then return ()
else do
let patients' = patient:patients -- add patient to list of patients
putStrLn . unlines . map printDetails $ patients' -- print list of patients
main' patients' -- continue
What are we doing here is remembering state of your program by passing parameter (this is how it is done in Haskell, as you have no states). Now your main function would look like this:
main = main' [] -- start with empty list of patients
You may notice that I presumed your function gatherInfo will return patient with name "quit" when user inputs "quit", however you can do that some other way
Upvotes: 1