Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'catch' from within MonadIO

I have a MonadIO instance in my program and I want to throw/catch exceptions(from Control.Exception module in base package) from withing that MonadIO.

A quick Google search returned lots of discussions(dating 2003) and complex soulutions(like implementing MonadControlIO, MonadBase etc. instances), I was wondering if there is an easy/accepted/widely-used solution for that,

If there is not, what would be a nice solution for this problem? As far as I can see there are several packages in Hackage addressing this problem, which one should I use?

(as an aside, recommended readings about why we don't have catch in MonadIO would also be appreciated)

Thanks,


EDIT: So Thomas's answer works fine but I also wondering what are other alternatives, my main purpose to use IO exceptions instead of ErrorT was performance, and I gain some performance after Control.Monad.IO.Control (443389 ticks vs. 318552 ticks), are there any better alternatives to Control.Monad.IO.Control?

like image 831
sinan Avatar asked Jul 08 '13 05:07

sinan


1 Answers

There are two common solutions: monad-control and MonadCatchIO-transformers. And both of them has a set of disadvantages. For example with monad-control you always need to define MonadBaseControl manually because it can't be derived. MonadCatchIO-transformers is not under development now, doesn't works with GHC 7.7, and according to this issue "Looks like the author of MonadCatchIO-transformers is about to deprecate the package.".

But some weeks ago new exceptions packages was released. It has better(more similar to Control.Exception) API than MonadCatchIO-transformers, supports pure exceptions and it's mtl friendly.


Update:

I did a benchmark between lifted-base that uses monad-control and exceptions, I use this benchmark and just replace monad-peel with exceptions. Result:

| benchmark | exceptions | lifted-base |
+-----------+------------+-------------+
| bracket   | 148.38 ns  | 182.28 ns   |
| bracket_  | 47.30 ns   | 112.37 ns   |
| catch     | 62.85 ns   | 156.30 ns   |
| try       | 54.70 ns   | 77.84 ns    |

Deviation is about several ns.

like image 168
Fedor Gogolev Avatar answered Nov 03 '22 05:11

Fedor Gogolev