<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>