Network.firstSuccesful: 'throw' vs 'throwIO' usage
Roman Cheplyaka
roma at ro-che.info
Thu Sep 6 12:05:00 CEST 2012
* Herbert Valerio Riedel <hvr at gnu.org> [2012-09-06 11:40:23+0200]
> Hello,
>
> while reading over the source code of network[1], I noticed a use of 'throw' where I'd
> expect 'throwIO':
>
> import qualified Control.Exception as Exception
>
> catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
> catchIO = Exception.catch
>
> -- Returns the first action from a list which does not throw an exception.
> -- If all the actions throw exceptions (and the list of actions is not empty),
> -- the last exception is thrown.
> firstSuccessful :: [IO a] -> IO a
> firstSuccessful [] = error "firstSuccessful: empty list"
> firstSuccessful (p:ps) = catchIO p $ \e ->
> case ps of
> [] -> Exception.throw e
> _ -> firstSuccessful ps
>
>
>
> ...so, is `throw` used properly in the code above, or should it rather
> be `throwIO`?
>
>
> [1]: http://hackage.haskell.org/packages/archive/network/2.3.1.0/doc/html/src/Network.html#firstSuccessful
In this particular situation it doesn't matter.
If you use throwIO, then, if all actions fail, firstSuccesful will
return a proper IO action which, when sequenced, throws an exception.
If you use throw, then in the same situation the result of
firstSuccessful will throw an exception before yielding a proper IO
value.
However, I agree with you that throwIO would be somewhat more idiomatic
here. (And IIRC I wrote this code, so you can blame me.)
--
Roman I. Cheplyaka :: http://ro-che.info/
More information about the Libraries
mailing list