Skip to content

Conversation

@JadAbouHawili
Copy link

@JadAbouHawili JadAbouHawili commented Jun 18, 2025

catch is imported from Control.Exception , not System.IO.Error

Should import Control.Exception , not System.IO.Error

Signed-off-by: JadAbouHawili <[email protected]>
need Control.Exception for catch , System.IO.Error for IOError

Signed-off-by: JadAbouHawili <[email protected]>
Signed-off-by: JadAbouHawili <[email protected]>
Copy link
Collaborator

@ulysses4ever ulysses4ever left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @JadAbouHawili! We have just switched from HTML to Markdown. Could you please rebase (possibly re-do) you change on top of the current main branch?

@ulysses4ever ulysses4ever added blocked enhancement New content or edit request bug Something isn't working and removed enhancement New content or edit request labels Dec 17, 2025
<p>We did <span class="fixed">fileExists &lt;- doesFileExist fileName</span> because <span class="fixed">doesFileExist</span> has a type of <span class="fixed">doesFileExist :: FilePath -&gt; IO Bool</span>, which means that it returns an I/O action that has as its result a boolean value which tells us if the file exists. We can't just use <span class="fixed">doesFileExist</span> in an <i>if</i> expression directly.</p>
<p>Another solution here would be to use exceptions. It's perfectly acceptable to use them in this context. A file not existing is an exception that arises from I/O, so catching it in I/O is fine and dandy.</p>
<p>To deal with this by using exceptions, we're going to take advantage of the <span class="label function">catch</span> function from <span class="fixed">System.IO.Error</span>. Its type is <span class="fixed">catch :: IO a -&gt; (IOError -&gt; IO a) -&gt; IO a</span>. It takes two parameters. The first one is an I/O action. For instance, it could be an I/O action that tries to open a file. The second one is the so-called handler. If the first I/O action passed to <span class="fixed">catch</span> throws an I/O exception, that exception gets passed to the handler, which then decides what to do. So the final result is an I/O action that will either act the same as the first parameter or it will do what the handler tells it if the first I/O action throws an exception.</p>
<p>To deal with this by using exceptions, we're going to take advantage of the <span class="label function">catch</span> function from <span class="fixed">Control.Exception</span>. Its type is <span class="fixed">catch :: IO a -&gt; (IOError -&gt; IO a) -&gt; IO a</span>. It takes two parameters. The first one is an I/O action. For instance, it could be an I/O action that tries to open a file. The second one is the so-called handler. If the first I/O action passed to <span class="fixed">catch</span> throws an I/O exception, that exception gets passed to the handler, which then decides what to do. So the final result is an I/O action that will either act the same as the first parameter or it will do what the handler tells it if the first I/O action throws an exception.</p>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we use Control.Exception.catch, the type needs to be changed to Exception e => IO a -> (e -> IO a) -> IO a. Alternatively, System.IO.Error.catchIOError could be used.

The Haskell report defines System.IO.Error.catch :: IO a -> (IOError -> IO a) -> IO a (which is where this issue comes from), which was then renamed to catchIOError in GHC (and MicroHs).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blocked bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants