In a file I am saving a file path. I want to read the file path from a file and then convert it to a variable, so everytime I run a function it gets the current file path from the file and then I can use this String in another function. I know variables are immutable but is there a way I can do it?
Here as you can see I am trying to read the file path from the file and then check if it is correct:
checksForCdCommand dir = checkIfPathExists constructedPath $ concat' $ paths sample2 where
constructedPath = do
let file = "abc.txt"
contents <- readFile file
return (if contents /= "/" then contents ++ "/" ++ dir else contents ++ dir)
Here if the contents is "/" it means that its my root dir so thats why I have this if else clause. But this way the code wont compile due to the following:
* Couldn't match expected type `[Char]'
with actual type `IO [Char]'
* In the first argument of `checkIfPathExists', namely
`constructedPath'
In the expression: checkIfPathExists constructedPath
In the expression:
checkIfPathExists constructedPath $ concat' $ paths sample2
I want to do something like this:
checksForCdCommand dir = checkIfPathExists constructedPath $ concat' $ paths sample2 where
constructedPath = if currDir /= "/" then currDir ++ "/" ++ dir else currDir ++ dir
where currDir
always has the value from the file.
The idea is that I have a tree that represents a file system and with the func paths I get all of the paths to the children, with checkIfPathExists
I pass a String as an argument to see if it's part of all the paths and I am doing a command that is like the cd unix command and when I change directories I save the current dir in the file.
I need this current directory for other things and that's why I need to read it from a file and then change the variable currDir
so I can use it for other functions.
This is the thing you can't do. All the rest is distracting window-dressing. If your approach relies fundamentally on doing this, you need a new approach. At some point, in an IO action, you need to read the contents of this
abc.txt
file, and save that result into a variable. Then you pass that variable (whose value will not change!) to other functions. If at some point you want to "refresh" that variable, you will need to re-read it and use that new variable.For example:
This program is not very well written, but it demonstrates the basic idea. It assumes abc.txt exists; if not, you get some error. But assuming it does, it prints error messages very quickly until you (in another process) modify abc.txt to contain a number.
You will have to structure your program in a similar way: some IO action, probably in
main
or close to it, reads the relevant file. Then it's passed to some other function, which makes decisions about what to do based on the file contents. Later, you re-read the file inmain
and continue the loop.There are tools that make this process simpler; for example, you can use Reader to plumb the contents of abc.txt through the pure parts of your program. It's not really much simpler in isolation, but it combines more cleanly with other bookkeeping you may have to do, like plumbing the results of additional IO actions through. But fundamentally it's no different: you have to do IO in IO actions, and variables don't change.