<p dir="ltr">The catchJust and handleJust functions seem a bit weird and unidiomatic.</p>
<p dir="ltr">catchJust<br>
        :: Exception e<br>
        => (e -> Maybe b)         -- ^ Predicate to select exceptions<br>
        -> IO a                   -- ^ Computation to run<br>
        -> (b -> IO a)            -- ^ Handler<br>
        -> IO a<br>
catchJust p a handler = catch a handler'<br>
  where handler' e = case p e of<br>
                        Nothing -> throwIO e<br>
                        Just b  -> handler b</p>
<p dir="ltr">This takes two functions and then puts them together. I would think the more natural API would be</p>
<p dir="ltr">catchMaybe :: Exception e => IO a -> (e -> Maybe (IO a)) -> IO a<br>
catchMaybe m handler = catch m handler' where<br>
  handler' e = fromMaybe (throwIO e) (handler e)</p>
<p dir="ltr">This is exactly as powerful as catchJust:</p>
<p dir="ltr">catchMaybe m handler = catchJust handler m id<br>
catchJust p m handler = catchMaybe m $ fmap handler . p</p>
<p dir="ltr">But catchMaybe doesn't enforce the arbitrary separation between "selection" and "handling".</p>