Haskell syntax for a case expression in a do block
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.
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.