I am a completely newbie to Haskell, and I wanted to find out about concurrency. After the usual rounds of being completely baffled as to why my program won’t compile, a managed to come up with a very simple multi-threaded program:

import Control.Concurrent import Control.Concurrent.Async calc x = do d<- threadDelay (round (x * 1000000.0)) -- x seconds return (10.0 + x) main = do let m1 = map calc [3.5, 3.2, 3.6] t3 <- mapM async m1 t4 <- mapM wait t3 print(t4)

It’s pretty much a case of “what could be simpler?”. I have a function calc which I want to apply concurrently to some list, in this case [3.5, 3.2, 3.6]. In this particular case, my function calc takes a float as an argument, x. It delays for x seconds, and returns x+10 as a result. It then collect the results in the order of the original list, and print them out.

If I ‘runhaskell’ on the above program, I obtain the expected result: [13.5,13.2,13.6] Running ‘time runhaskell foo.hs’ gives me the following output:

real 0m3.940s user 0m0.302s sys 0m0.056s

So it is clearly running the threads concurrently, rather than sequentially.

I am very happy with the simplicity of this code. It abstracts things so beautifully.

My next goal is to use it to perform concurrent downloads of urls. ‘calc’ will become something like ‘getUrl’, and the list will be replaced by a list of urls.

An easy-to-overlook part of the code is the line: let m1 = map calc [3.5, 3.2, 3.6] The really cool bit is that Haskell is LAZY, so it will only try to perform the mapping as it needs to. If the mapping had been eager, as in most languages, then the program would have taken over 10 seconds to execute (being the cumulative delay time of 10.3). Although Haskell is not the easiest language to get to grips with, it has some really really cool stuff that makes for some very terse code. I am very encouraged by my experiments with Haskell.

/projects/repos/cerbo/ssah/multi.hs

Update 09-Mar-2015: Apparently the good folks writing the Haskell libraries already anticipated my requirement in the form of mapConcurrently .

Update 25-Mar-2015: There is also a discussion of this post over on Reddit.