1

Is there any way to create nested control structure? For example I tried this. But I got error.

bmiTell :: (RealFloat a) => a -> String  

bmiTell bmi  = if bmi <= 18.5  then if bmi==16.0 then "asdasdasdsad"
           else if bmi <= 25.0 then "You're supposedly normal. Pffft, I bet  you're ugly!"  
           else if bmi <= 30.0 then "You're fat! Lose some weight, fatty!"  
           else    "You're a whale, congratulations!"  
2
  • I think you need to add some curly braces to get that to work. Commented Mar 6, 2013 at 19:41
  • 2
    @pubby braces, while syntactically legal, are not required for or even very commonly seen in Haskell if-then-else statements. Commented Mar 6, 2013 at 20:25

2 Answers 2

12

The if expression is parsed as

if bmi <= 18.5   -- no else!
  then if bmi==16.0
         then "asdasdasdsad"
         else if bmi <= 25.0
                then "You're supposedly normal. Pffft, I bet  you're ugly!"  
                else if bmi <= 30.0
                       then "You're fat! Lose some weight, fatty!"  
                       else "You're a whale, congratulations!"

Note that the first if has a then branch but no else branch.

In Haskell, every if expression must have a then branch and an else branch. So that's your problem.

I second bchurchill's suggestion of using guards rather than nested if expressions.

Sign up to request clarification or add additional context in comments.

2 Comments

This is also gives error. The same:Syntax error in expression (unexpected `}', possibly due to bad layout)
@molten What do you want to happen if bmi is less than 18.5 but not equal to 16.0? That is basically the missing else branch.
9

Yeah, you just need to indent things properly. ghc probably doesn't like being told it's fat either. In either case, the indenting determines what branches correspond to what statements, and I might have messed up the order a bit:

bmiTell bmi  = if bmi <= 18.5  
               then if bmi==16.0 
                    then "asdasdasdsad"
                    else if bmi <= 25.0 
                         then "You're supposedly normal. Pffft, I bet  you're ugly!"  
                         else if bmi <= 30.0 
                              then "You're fat! Lose some weight, fatty!"  
                              else    "You're a whale, congratulations!"  
               else "foobar"

The better way to do this is with a guarded conditional, e.g.

bmiTell bmi
  | bmi < 18.5 = "foo"
  | bmi < 25.0 = "bar"
  | bmi < 30.0 = "buzz"

4 Comments

It gives this error:Syntax error in expression (unexpected `}', possibly due to bad layout). By the way I'm using hugs. How can I handle this?
But the function with guards doesn't include nested structure.
@molten The function with guards had a mistake in it. Fixed now.
Indentation of if-then-else is irrelevant as far as the compiler is concerned (although of course it can make it more understandable for humans).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.