Reputation: 41541
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?
Upvotes: 10
Views: 2038
Reputation: 4249
How are bind and return clutter?
main = getArgs >>= (return.head) >>= print
or
main = liftM head getArgs >>= print
Upvotes: 1
Reputation: 202655
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
.
Upvotes: 16
Reputation: 19642
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
Upvotes: 6
Reputation: 3835
How about this?
import Control.Monad
main = do
first <- liftM head getArgs
print first
Upvotes: 9