Search code examples
haskellmonadsio-monadtraversable

Order of execution with Haskell's `mapM`


Consider the following Haskell statement:

mapM print ["1", "2", "3"]

Indeed, this prints "1", "2", and "3" in order.

Question: How do you know that mapM will first print "1", and then print "2", and finally print "3". Is there any guarantee that it will do this? Or is it a coincidence of how it is implemented deep within GHC?


Solution

  • If you evaluate mapM print ["1", "2", "3"] by expanding the definition of mapM you will arrive at (ignoring some irrelevant details)

    print "1" >> print "2" >> print "3"
    

    You can think of print and >> as abstract constructors of IO actions that cannot be evaluated any further, just as a data constructor like Just cannot be evaluated any further.

    The interpretation of print s is the action of printing s, and the interpretation of a >> b is the action that first performs a and then performs b. So, the interpretation of

    mapM print ["1", "2", "3"] = print "1" >> print "2" >> print "3"
    

    is to first print 1, then print 2, and finally print 3.

    How this is actually implemented in GHC is entirely a different matter which you shouldn't worry about for a long time.