Network.firstSuccesful: 'throw' vs 'throwIO' usage
Roman Cheplyaka
roma at ro-che.info
Thu Sep 6 15:07:03 CEST 2012
* Simon Marlow <marlowsd at gmail.com> [2012-09-06 12:35:52+0100]
> On 06/09/2012 11:05, Roman Cheplyaka wrote:
> >* 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.)
>
> Here is some background reading:
>
> http://hackage.haskell.org/trac/ghc/ticket/1171
>
> The bottom line is that it's hard to tell what will happen if you use
> throw here. Always use throwIO if you can.
So, regarding this example, does it mean that, under some circumstances,
`firstSuccessful [a]` can throw `error "firstSuccessful: empty list"`?
Would you also advise changing `error` to `throwIO . ErrorCall` here?
--
Roman I. Cheplyaka :: http://ro-che.info/
More information about the Libraries
mailing list