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 offcloseis not used, sofcloseis not evaluated. Because of this,fwriteidoes 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
*finstead of aString, so that this unique value is not lost. As long as the result is used, then, thefwriteiis evaluated. You can potentially make the*fargument 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,
wis 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
appendNumInEndOfVmFilesneeds to have a type context| FileSystem fto resolve overloading offopenandfclose.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).