I tried to rewrite that program, which is working:
nameIOite :: IO ()
nameIOite = do
putStrLn "What's your name ?"
name <- getLine
if name `elem` ["Simon","John","Phil"]
--if name == "Simon" || name == "John" || name == "Phil" also works but is ugly.
then putStrLn "I think Haskell is a great programming language."
else if name == "Koen"
then putStrLn "I think debugging Haskell is fun."
else putStrLn "I don't know your name."
This is done using if/then/else (therefore the suffix ite in nameIOite
)
Then I'vs tried using guards:
nameIOg :: IO ()
nameIOg = do
putStrLn "What's your name ?"
name <- getLine
let answer
| name `elem` ["Simon","John","Phil"] = "I think Haskell is a great programming language."
| name == "Koen" = "I think debugging Haskell is fun."
| otherwise = "I don't know your name."
putStrLn answer
This didn't work:
test.hs:6:9: error:
parse error (possibly incorrect indentation or mismatched brackets)
|
6 | | name `elem` ["Simon","John","Phil"] = "I think Haskell is a great programming language."
| ^
Failed, no modules loaded.
After some experimenting, the solution turned out to indent the guards once more (which isn't clear to me at all):
nameIOg :: IO ()
nameIOg = do
putStrLn "What's your name ?"
name <- getLine
let answer
| name `elem` ["Simon","John","Phil"] = "I think Haskell is a great programming language."
| name == "Koen" = "I think debugging Haskell is fun."
| otherwise = "I don't know your name."
putStrLn answer
Ok, one module loaded.
Where does that double indentation come from and is there a way to write this more elegently ?
(By the way, I stumbled across this when reviewing my wikibook.hs files.)
Source of example: there
Solutions: there
let
allows multiple definitions, as inNote the indentation.
y = 2
is not parsed to continue the definitionx = 1
since it starts on the same column.If you want a new line to be parsed as if it continued the previous line, you have to indent it more. E.g.
or, using another line
Indentation rules might seem puzzling at first, but they are actually quite simple.
I think your current code is as elegant as it might be -- it looks fine to me.
If you want more alternatives, you could use
if then else
, even if most Haskellers would prefer guards. (Personally, I don't have a real preference)You could also use another line, e.g. (I'd tend to prefer that)
or even
I'm not claiming a style is overwhelmingly better than another one.