Take the 2-minute tour ×

This is about syntactic sugar in Haskell. A simple Haskell program:

main = do
  args <- getArgs
  let first = head args
  print first

I use binding in the first line (args <- getArgs) and a pure assignment in the second one (let first = ...). Is it possible to merge them together into a readable one-liner?

I understand that I can rewrite binding “de-sugared”:

main = do
  first <- getArgs >>= ( return . head )
  print first

But is there a nicer way, without cluttering the line with (>>=) and return?

share|improve this question
add comment

5 Answers

up vote 12 down vote accepted

liftM and head are all very well, but let us not forget pattern matching:

main = do { arg:_ <- getArgs; print arg }

or if you like layout

main = do
    arg : _ <- getArgs
    print arg

When possible, most Haskellers prefer pattern matching over head and tail.

share|improve this answer
This is really nice and readable. Thanks! –  sastanin Mar 25 '09 at 13:50
~[arg] <- getArgs –  Dario Sep 7 '09 at 17:56
add comment

How about this?

import Control.Monad

main = do
   first <- liftM head getArgs
   print first
share|improve this answer
D'oh! 19 seconds faster than me. –  ephemient Mar 18 '09 at 17:17
and a lot faster than me :) –  Jonas Mar 18 '09 at 17:24
Yes, this is much nicier. Thank you! –  sastanin Mar 18 '09 at 20:04
Even nicer: main = liftM head getArgs >>= print. :) –  Porges Mar 19 '09 at 9:06
add comment

Yet another possibility:

main = putStr . head =<< getArgs
share|improve this answer
Well, it's nice. I didn't think about reversed version. Thank you. –  sastanin Mar 21 '09 at 16:07
add comment

It is also possible to use the ap function (with type Monad m => m (a -> b) -> m a -> m b) like this:

import System
import Control.Monad

main :: IO ()
main = do line <- return head `ap` getArgs
          putStrLn line

This has the simple advantage that if your function requires several arguments you can use ap between each of them and you don't need to use liftM2, liftM3 etc. For a function f::a -> b -> c -> d you write

return f `ap` arg1 `ap` arg2 `ap` arg3
share|improve this answer
Thank you. I did'n know about ap. –  sastanin Mar 18 '09 at 20:07
for those with an applicative taste, ap = <*> and liftM = <$> –  Eli Aug 26 '11 at 3:37
add comment

How are bind and return clutter?

main = getArgs >>= (return.head) >>= print


main = liftM head getArgs >>= print

share|improve this answer
I usually think about return as “wrap into monad”, and (>>=) as “unwrap and substitute”. So reading the code is something like “unwrap and substitute, and wrap again, and unwrap and substitute”. So, liftM is more readable for me, because it is simply “make function monadic”. So, I like option 2. –  sastanin Mar 21 '09 at 16:04
add comment

Your Answer


