Network.firstSuccesful: 'throw' vs 'throwIO' usage
marlowsd at gmail.com
Thu Sep 6 13:35:52 CEST 2012
On 06/09/2012 11:05, Roman Cheplyaka wrote:
> * Herbert Valerio Riedel <hvr at gnu.org> [2012-09-06 11:40:23+0200]
>> while reading over the source code of network, 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`?
>> : http://hackage.haskell.org/packages/archive/network/188.8.131.52/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
> However, I agree with you that throwIO would be somewhat more idiomatic
> here. (And IIRC I wrote this code, so you can blame me.)
Here is some background reading:
The bottom line is that it's hard to tell what will happen if you use
throw here. Always use throwIO if you can.
More information about the Libraries