So far in this chapter, you’ve seen examples of fairly traditional I/O. Each line, or block of data, is requested and processed individually.
Haskell has another approach available to you as well. Since Haskell is a lazy language, meaning that any given piece of data is only evaluated when its value must be known, there are some novel ways of approaching I/O.
One novel way to approach I/O is with the
hGetContents has the
Handle -> IO String. The
String it returns represents all of
the data in the file given by the
In a strictly evaluated language, using such a function is often a bad idea. It may be fine to read the entire contents of a 2 KB file, but if you try to read the entire contents of a 500 GB file, you are likely to crash due to lack of RAM to store all that data. In these languages, you would traditionally use mechanisms such as loops to process the file’s entire data.
hGetContents is different. The
String it returns is evaluated lazily. At the moment you call
hGetContents, nothing is actually read. Data
is only read from the
Handle as the
elements (characters) of the list are processed. As elements of the
String are no longer used,
Haskell’s garbage collector automatically frees that memory. All of
this happens completely transparently to you. And since you have what
looks like (and, really, is) a pure
String, you can pass it to pure
Let’s take a quick look at an example. Back in Working with ...