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.

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.

Was it helpful?

Solution

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.

OTHER TIPS

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.

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