Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8979737
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T19:54:53+00:00 2026-06-15T19:54:53+00:00

I want to use the Haskell function readFile :: FilePath -> IO String to

  • 0

I want to use the Haskell function

readFile :: FilePath -> IO String

to read the content of a file into a string. In the documentation I have read that “The file is read lazily, on demand, as with getContents.”

I am not sure I understand this completely. For example, suppose that I write

s <- readFile "t.txt"

When this action is executed:

  • The file is opened.
  • The characters in s are actually read from the file as soon as (but not sooner) they are needed to evaluate some expression (e.g. if I evaluate length s all the content of the file will be read and the file will be closed).
  • As soon as the last character has been read, the file handle associated to this call to readFile is closed (automatically).

Is my third statement correct? So, can I just invoke readFile without closing the file handle myself? Will the handle stay open as long as I have not consumed (visited) the whole result string?

EDIT

Here is some more information regarding my doubts. Suppose I have the following:

foo :: String -> IO String
foo filename = do
                  s <- readFile "t.txt"
                  putStrLn "File has been read."
                  return s

When the putStrLn is executed, I would (intuitively) expect that

  1. s contains the whole content of file t.txt,
  2. The handle used to read the file has been closed.

If this is not the case:

  • What does s contain when putStrLn is executed?
  • In what state is the file handle when putStrLn is executed?
  • If when putStrLn is executed s does not contain the whole content of the file, when will this content actually be read, and when will the file be closed?
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T19:54:54+00:00Added an answer on June 15, 2026 at 7:54 pm

    Is my third statement correct?

    Not quite, the file is not closed "As soon as the last character has been read", at least not usually, it lingers in the semi-closed state it was in during the read for a few moments, the IO-manager/runtime will close it when it next performs such actions. If you’re rapidly opening and reading files, that lag may cause you to run out of file handles if the OS limit isn’t too high.

    For most use cases (in my limited experience), however, the closing of the file handle is timely enough. [There are people who disagree and view lazy IO as extremely dangerous in all cases. It definitely has pitfalls, but IMO its dangers are often overstated.]

    So, can I just invoke readFile without closing the file handle myself?

    Yes, when you’re using readFile, the file handle is closed automatically when the file contents has been entirely read or when it is noticed that the file handle is not referenced anymore.

    Will the handle stay open as long as I have not consumed (visited) the whole result string?

    Not quite, readFile puts the file handle in a semi-closed state, described in the docs for hGetContents:

    Computation hGetContents hdl returns the list of characters corresponding to the unread portion of the channel or file managed by hdl, which is put into an intermediate state, semi-closed. In this state, hdl is effectively closed, but items are read from hdl on demand and accumulated in a special list returned by hGetContents hdl.


    foo :: String -> IO String
    foo filename = do
                  s <- readFile "t.txt"
                  putStrLn "File has been read."
                  return s
    

    Ah, that’s one of the pitfalls of lazy IO on the other end. Here the file is closed before its contents have been read. When foo returns, the file handle isn’t referenced anymore, and then closed. The consumer of foos result will then find that s is an empty string, because when hGetContents tries to actually read from the file, the handle is already closed.

    I confused the behaviour of readFile with that of

    bracket (openFile file ReadMode) hClose hGetContents
    

    there. readFile only closes the file handle after s is not referenced anymore, so it behaves correctly as expected here.

    When the putStrLn is executed, I would (intuitively) expect that

    1. s contains the whole content of file t.txt,
    2. The handle used to read the file has been closed.

    No, s does not contain anything yet but a recipe to maybe get some characters from the file handle. The file handle is semi-closed, but not closed. It will be closed when the file contents has been entirely read, or s goes out of scope.

    If this is not the case:

    • What does s contain when putStrLn is executed?
    • In what state is the file handle when putStrLn is executed?
    • If when putStrLn is executed s does not contain the whole content of the file, when will this content actually be read, and when will the file be closed?

    The first two questions have been answered, the answer to the third is "the file will be read when the contents is consumed", and it will be closed when the entire contents has been read or when it is no longer referenced.

    That would be different with the above bracket invocation – bracket guarantees that the final operation, here the hClose will be run even if the other actions throw an exception, therefore its use is often recommended. However, the hClose is run when bracket returns, and then the hGetContents can’t get any contents from the now really closed file handle. But readFile would not necessarily close the file handle if an exception occurs.

    That is one of the dangers or quirks of lazy IO, files are not read until their contents is demanded, and if you use lazy IO wrongly, that will be too late and you don’t get any contents.

    It’s a trap many (or even most) fall into one time or another, but after having been bitten by it, one quickly learns when IO needs to be non-lazy and do it non-lazily in those cases.

    The alternatives (iteratees, enumerators, conduits, pipes, …) avoid those traps [unless the implementer made a mistake], but are considerably less nice to use in those cases where lazy IO is perfectly fine. On the other hand, they treat the cases where laziness is not desired much better.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I want to use a Haskell function with the following type :: string ->
I want to define a Haskell function that removes from a list of strings
I am teaching myself Haskell. I want to write a function that recursively finds
I've started experimenting with Haskell and have a problem. qqq is a function that
I want use Haskell higher order function Foldr to calculate the length of a
I read this: http://hackage.haskell.org/trac/ghc/wiki/ViewPatterns I like the idea, want to use the extension. I
I want use javascript setInterval function to achieve a box rotate animate effect, I
I want use a single php file to handle all of my voting requests.
i want use some data from a website with web service. i have a
We have a powerbuilder application and we want use a scanner through this application

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.