I'm trying to write function that receive [String]
which are names of files, String
which is the name of the files directory and *f
. The function will append to each file an integer in the end.
Here is what I got so far:
import StdEnv
import StdFile
import FileManipulation
appendNumInEndOfVmFiles :: [String] String *f -> String
appendNumInEndOfVmFiles [] dirname w = "finished"
appendNumInEndOfVmFiles [x:xs] dirname w
# path = dirname +++ "\\\\" +++ x
# (ok,file,files) = fopen path FAppendText w
# file = fwritei 12 file
# (ok2,_) = fclose file w
= appendNumInEndOfVmFiles xs dirname w
Start w
// 1. Receive name of directory from the user.
# (io,w) = stdio w // open stdio
# io = fwrites "Enter name of directory:\n" io // ask for name
# (name,io) = freadline io // read in name
# name = name % (0, size name - 2) // remove \n from name
# (ok,w) = fclose io w // close stdio
| not ok = abort "Couldn't close stdio" // abort in case of failure
// 2. Get a list of all file names in that directory.
# (dir,w) = getDirectoryContents (RelativePath [PathDown name]) w
# fileList = getNamesOfFilesInDirectory (getEntriesList dir)
= appendNumInEndOfVmFiles (getVmFiles fileList) name w
Assume that getVmFiles
is defined in my FileManipulation.dcl
file and in the context of this problem name
is "myDir"
and file list is ["hello.vm","Wiki.vm"]
For some reason, even that I got "finished" message on the screen, the files aren't modified. No matter what kind of integer I give to fopen
, even if its FWriteText
or FWriteData
its still doing nothing... also even if I'm using fwritec
or fwrites
with characters nothing happened.
What I'm missing here? Thanks a lot!
This is due to lazy evaluation. In
appendNumInEndOfVmFiles
, the result offclose
is not used, sofclose
is not evaluated. Because of this,fwritei
does not need to be evaluated either. You can fix this by adding a guard onok2
:However, the typical way to do this would be to rewrite the function to return a
*f
instead of aString
, so that this unique value is not lost. As long as the result is used, then, thefwritei
is evaluated. You can potentially make the*f
argument strict (i.e. add a!
in front). This would make sure that it is evaluated before entering the function, so that all lingering file closes have been performed.There are some more issues with your code:
Here,
w
is used twice, which is illegal because it is of a strict type. You should use(ok2,w)
in the guard to continue with the same environment.The
appendNumInEndOfVmFiles
needs to have a type context| FileSystem f
to resolve overloading offopen
andfclose
.Lastly:
Just so you know: the difference would be that the first would write the integer in an ASCII representation whereas the second would write it binary as 4 or 8 bytes (depending on the bitwidth of your system).