Reputation: 21
I need to ask user for input, do something with it, ask for next input and do something with it but I still need to take the previous input into account.
I was thinking(in an OOP way) of saving all the input <- getLine
s into a list and then be able to make changes to that list(and store them), but I can't do that because stuff immutable in haskell.
main = do
args <- getArgs
contents <- readFile $ head args
putStrLn contents
let inputs = [] --THIS
forever $ do
putStrLn $ "Filtering: " ++ appendFilters inputs
input <- getLine
let inputs = updateInputs inputs input --THIS
newInput <- getUserInputs inputs input
putStrLn $ unlines (filterContent (lines contents) newInput)
How do I do this right in the eyes of functional programming?
Edit:
So what my program is supposed to do is:
input == "pop"
then delete last filter, otherwise add to the list of filtering wordsUpvotes: 0
Views: 80
Reputation: 120711
First off, you can have mutable values in Haskell, you just need to make all the updates in the IO monad. We usually avoid that, but if your code is all about IO interactivity anyway then it may be the most straightforward solution.
import Data.IORef
main = do
args <- getArgs
contents <- readFile $ head args
putStrLn contents
inputs <- newIORef []
forever $ do
currentInputs <- readIORef inputs
putStrLn $ "Filtering: " ++ appendFilters currentInputs
input <- getLine
updateInputs inputs input
newInput <- getUserInputs inputs input
putStrLn $ unlines (filterContent (lines contents) newInput)
The more functional alternative is generally to explicitly pass updated versions of the stateful variables through the recursion “loops”. You won't be able to use forever
then, but it's easy to change that to manual recursion:
main = do
args <- getArgs
contents <- readFile $ head args
putStrLn contents
let loop inputs = do
putStrLn $ "Filtering: " ++ appendFilters inputs
input <- getLine
newInput <- getUserInputs inputs input
putStrLn $ unlines (filterContent (lines contents) newInput)
loop $ updateInputs inputs input
loop []
Upvotes: 3