# Comprehension - Nested if-conditions in Haskell

i try to become familiar with the if-condition statements in haskell

assume that i´ve an argument x and i try the following in haskell

``````functionname x = if x > 0 then x-5
if x-5 == 0 then 1
else if x-5 /= 0 then functionname x-5
else if x-5 <  then 0
``````

so, the idea was to subtract 5 from x, check if the result is 0, if yes, then give a 1. If not then invoke the function again with the expression x-5. If the result of x-5 is negative then give a 0.

so, my questions: Would that be correct? Because when i try that, i´ve got a message like parse error on input 'functionname'.

how can i fix that problem? Are the if-else conditions wrong ?

``````programm :: Int -> Bool

programm x |  x > 0 =
if z == 0 then True
else if z < 0 then False
else programm z
where
z = z-2

programm x |  x < 0 =
if z == 0 then True
else if z > 0 then False
else programm z
where
z = z+2
``````

so, i wanted to have the possibility to decide of a given number is even. So, i modify your solution a little bit. its the same but, at the beginning of the two declarations i said : x > 0 = .... and x < 0 =... Because i want to say that for example -4 is also even. for that reason: the first declarations should handle the positive even numbers and the second declarations handles the negative even numbers.

when i give that to the compiler, then the message : Exception appears. Where i ve made the mistake?

-
Unlike in some other languages, every `if` in Haskell needs an `else`. – n.m.

Use guards to make things clear:

``````functionname x
| x > 0      = x - 5
| x - 5 == 0 = 1
| x - 5 /= 0 = functionname (x - 5)
| x - 5 < 0  = 0
``````
-
Thanks for your answer. But when i do that, then the compiler complain that the result from the first line (| x > 0 = x - 5) should be a boolean. – user3097712
@user3097712 where? ideone.com/hXdWDn – n.m.

Every `if` needs to have an `else` clause associated with it.

The very first one doesn't and the very last one doesn't either. This works just fine:

``````functionname x = if x > 0 then x-5
else if x-5 == 0 then 1
else if x-5 /= 0 then functionname x-5
else if x-5 < 0 then 0 else 1
``````
-
Thanks for your answer. But when i do that, then the compiler complain that the result from the first line (| x > 0 = x - 5) should be a boolean. – user3097712

so, the idea was to subtract 5 from x, check if the result is 0, if yes, then give a 1. If not then invoke the function again with the expression x-5. If the result of x-5 is negative then give a 0.

That might be written like this:

``````functionname x =
if x' == 0 then 1
else if x' < 0 then 0
else functionname x'
where
x' = x - 5
``````

Here, I use a `where` clause to locally define `x'` as `x - 5` and then use it for the tests and the recursive call. Your first branch, `if x > 0 then x-5`, does not appear in your description of what function should do (it gives `x - 5` results as result whenever x is larger than zero, which is probably not what you want). Also, note that every `if` needs an `else` as well as a `then`.

so, i wanted to have the possibility to decide of a given number is even. So, i modify your solution a little bit. its the same but, at the beginning of the two declarations i said : x > 0 = .... and x < 0 =... Because i want to say that for example -4 is also even. for that reason: the first declarations should handle the positive even numbers and the second declarations handles the negative even numbers.

First of all, in the second version of your function the definition in the `where` clause should be `z = x + 2`, as `z = z + 2` will not terminate. This being an evenness test, you also want to perform the tests on `x` rather than `z`. With that fixed, your solution with nested conditionals should work fine (note, however, that you are not treating the `x == 0` case; the first guard should be `x >= 0`). There is a more elegant way of writing the function, though:

``````myEven :: Int -> Bool
myEven x = myEven' (abs x)
where
myEven' x
| x == 0    = True
| x < 0     = False
| otherwise = myEven' (x - 2)
``````

`abs` is the familiar absolute value function, while `myEven'` amounts to the `x > 0` branch of your original definition. Taking the absolute value of `x` is the easiest way to avoid writing two nearly equal branches to handle the negative and non-negative cases.

N.B.: While this is probably just a learning exercise, if you ever need to find whether a number is even there is an `even` function available from the Prelude. There is also `mod` if you need to test divisibility for other numbers.

-
@user3097712 I updated the answer to match the edited question. – duplode