Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it ok to write most of the code using IO monads

Tags:

haskell

monads

I am trying to develop a chat server using Haskell.

There are a lot of useful tools like TChan, TSkiplist, forkIO ...etc, but it turns out that most of my code is written inside the IO monads and unsafePerformIO, which sounds very inefficient.

Is it ok to do this, or is haskell not the right tool for this purpose?

like image 915
user1748906 Avatar asked Oct 16 '12 04:10

user1748906


2 Answers

As a general rule, try to first write code as just pure functions without worrying where the data comes from - just assume it's there.

Next wrap that pure functionality in IO to feed your pure functions data and put the results somewhere. It's OK that there's a lot of this going on in a chat application! The IO monad isn't inefficient at all, it's just that we prefer to keep as much code as we can out of it since that's good design - keep the data crunching apart from the IO. A chat application doesn't do a lot of calculation with the data it gets, so it's OK to have loads of IO code.

I think it's definitely better to stick in the IO monad than use unsafePerformIO, because unsafePerformIO is kind of presenting its result as pure data. I might be tempted to use it to get constants from a configuation file, but I've never actually done so, and there's no point if you're heavily in the IO monad anyway. There's a reason it's called unsafe! Petr Pudlák has good advice in the comment below.

I've heard Haskell's monads described as the best imperative programming language in the world. I could split hairs over that description, but I agree with the sentiment, and yes, stick with Haskell. Haskell is good at at the programming you're using it for.

like image 76
AndrewC Avatar answered Sep 21 '22 15:09

AndrewC


Whenever you notice that you have a long function that resides inside the IO monad, it pays off to pause and take a look at the computations that take place. In my experience, it's (almost) always the case that some non-IO related stuff is going on that doesn't need access to input output and can be encapsulated in pure functions.

This has the big advantage that it forces you to find proper abstractions and separate (pure) algorithms from input/output handling. Moreover, it's much easier to verify and test pure functions. Of course, you will still call these pure functions from within some IO a function (e.g. main) but that's perfectly fine.

like image 40
Peter Avatar answered Sep 18 '22 15:09

Peter