Haskell Syntax case expression in a do block

By : witkamp
Source: Stackoverflow.com
Question!

I can't quite figure out this syntax problem with a case expression in a do block.

What is the correct syntax?

If you could correct my example and explain it that would be the best.

Thanks

module Main where 

main = do   
     putStrLn "This is a test"
     s <- foo
     putStrLn s  

foo = do
    args <- getArgs 
    return case args of
                [] -> "No Args"
                [s]-> "Some Args"

A little update. My source file was a mix of spaces and tabs and it was causing all kinds of problems. Just a tip for any one else starting in Haskell. If you are having problems check for tabs and spaces in your source code.

It will save you a lot of grief.

By : witkamp


Answers

Equivalently:

foo = do
  args <- getArgs 
  case args of
        [] -> return "No Args"
        [s]-> return "Some Args"

It's probably preferable to do as wnoise suggests, but this might help someone understand a bit better.



return is an (overloaded) function, and it's not expecting its first argument to be a keyword. You can either parenthesize:

module Main where 
import System(getArgs)

main = do   
     putStrLn "This is a test"
     s <- foo
     putStrLn s  

foo = do
    args <- getArgs 
    return (case args of
                [] -> "No Args"
                [s]-> "Some Args")

or use the handy application operator ($):

foo = do
    args <- getArgs 
    return $ case args of
                [] -> "No Args"
                [s]-> "Some Args"

Stylewise, I'd break it out into another function:

foo = do
    args <- getArgs 
    return (has_args args)

has_args [] = "No Args"
has_args _  = "Some Args"

but you still need to parenthesize or use ($), because return takes one argument, and function application is the highest precedence.

By : wnoise


A simple one-liner is

perl -nae 'print "$F[0] $F[1]\n";'

you can change the delimiter with -F



This video can help you solving your question :)
By: admin