<p>Everything stays the same except the handler, which we modified to only catch a certain group of I/O exceptions. Here we used two new functions from <span class="fixed">System.IO.Error</span> — <span class="label function">isDoesNotExistError</span> and <span class="label function">ioError</span>. <span class="fixed">isDoesNotExistError</span> is a predicate over <span class="fixed">IOError</span>s, which means that it's a function that takes an <span class="fixed">IOError</span> and returns a <span class="fixed">True</span> or <span class="fixed">False</span>, meaning it has a type of <span class="fixed">isDoesNotExistError :: IOError -> Bool</span>. We use it on the exception that gets passed to our handler to see if it's an error caused by a file not existing. We use <a href="syntax-in-functions.html#guards-guards">guard</a> syntax here, but we could have also used an <i>if else</i>. If it's not caused by a file not existing, we re-throw the exception that was passed by the handler with the <span class="fixed">ioError</span> function. It has a type of <span class="fixed">ioError :: IOException -> IO a</span>, so it takes an <span class="fixed">IOError</span> and produces an I/O action that will throw it. The I/O action has a type of <span class="fixed">IO a</span>, because it never actually yields a result, so it can act as <span class="fixed">IO <i>anything</i></span>.</p>
0 commit comments