Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

Yet another possibility:

main = putStr . head =<< getArgs

How about this?

import Control.Monad

main = do
   first <- liftM head getArgs
   print first

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

How are bind and return clutter?

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

or

main = liftM head getArgs >>= print

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top