Random Haskell Ephiphany: Using the liftM function

I’ve been tinkering with some monadic code and it just dawned on me that the often-used liftM function is just a shortcut (less typing) for a common use scenario which arises whenever you need to use a pure function along with an impure one.

For example, consider the following pseudocode:

randoms :: IO [Int]

Calling randoms generates a list of random Int values. Suppose we want just the first value from this list, so we naively write the following:

main :: IO ()
main = do
    rs <- randoms
    let r = head rs
    ...

But then you realize that you will only use just a single random Int, and that the variable rs is useless. So, you remember what return in Haskell means and then write this instead:

main :: IO ()
main = do
    r <- return . head =<< randoms
    ...

But this looks a bit awkward. This is where liftM comes in:

main :: IO ()
main = do
    r <- liftM head $ randoms
    ...

The code is now much simpler and cleaner. What’s not to like?

UPDATE July 15, 2012: I just realized that there is even a shorter solution, using the (<$>) function from the very useful Control.Applicative module:

main :: IO ()
main = do
    r <- head <$> randoms
    ...
Advertisements

One thought on “Random Haskell Ephiphany: Using the liftM function

Comments are closed.