I am trying to read the contents of a file, turn the text to upper-case and then write it back.
Here is the code I had written:
import System.IO
import Data.Char
main = do
handle <- openFile "file.txt" ReadWriteMode
contents <- hGetContents handle
hClose handle
writeFile "file.txt" (map toUpper contents)
return ()
However, this writes nothing to the file, in fact, it even clears it.
I made some changes:
main = do
handle <- openFile "file.txt" ReadWriteMode
contents <- hGetContents handle
writeFile "file.txt" (map toUpper contents)
hClose handle
return ()
However, I get the error resource busy (file is locked)
. How can I get this working and why it didn't work in both cases?
The syntax for importing modules in a Haskell script is import <module name>. This must be done before defining any functions, so imports are usually done at the top of the file. One script can, of course, import several modules. Just put each import statement into a separate line.
Start Haskell If you have installed the Haskell Platform, open a terminal and type ghci (the name of the executable of the GHC interpreter) at the command prompt. Alternatively, if you are on Windows, you may choose WinGHCi in the Start menu.
Lazy IO is bad, and this is generally considered to be a pain point in Haskell. Basically the contents
isn't evaluated until you go to write it back to disk, at which point it can't be evaluated because the file is already closed. You can fix this in several ways, without resorting to extra libraries you can use the readFile
function and then check the length before writing back out:
import Control.Monad (when)
main = do
contents <- readFile "file.txt"
let newContents = map toUpper contents
when (length newContents > 0) $
writeFile "file.txt" newContents
I would say this code is actually better anyway because you don't write back out to a file that is already empty, a pointless operation.
Another way would be to use a streaming library, pipes
is a popular choice with some good tutorials and a solid mathematical foundation, and that would be my choice as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With