Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct syntax for if statements in Haskell

The only input you need is the grade number that you get. This is what I have so far.

myScore x = if x > 90
    then let x = "You got a A"
if 80 < x < 90 
    then let x = "you got a B"
if 70 < x < 80
    then let x = "You got a C"
if 60 < x < 90
    then let x = "you got a D"
else let x = "You got a F"

This gives me an error "parse error on input `if' ", I also tried:

myScore x = (if x > 90 then "You got an A" | if 80 < x < 90 then "You got a B" | if 70 < x < 80 then "You got a D" | if 60 < x < 70 then "You got a D"  else "You got a F")

but that didn't work either.

like image 846
Bob Bobington Avatar asked Mar 10 '13 01:03

Bob Bobington


People also ask

Does Haskell have if statements?

In Haskell, multiple lines of if will be used by separating each of the if statement with its corresponding else statement. In the above example, we have introduced multiple conditions in one function. Depending on the function inputs, it will provide us different outputs.

How do you write if/then else in Haskell?

Branching conditionals can be written straightforwardly using the if - then - else syntax in Haskell. Note that all three are keywords and that each branch of an if - then - else expression must return the same type. The condition in the if clause must evaluate to a Boolean.

What is && in Haskell?

The Haskell Report gives a full listing of the Prelude which serves as a spec. And it's perfectly alright to care about this, since (&&) can be used to combine a simple & quick test with one that requires intensive computation.


Video Answer


4 Answers

You can't have the let inside the conditionals, otherwise the variable x won't be available in the following expression that needs it.

In your case, you don't even need the let-binding because you just want to return the string immediately, so you can just do:

myScore x = 
    if x > 90 then "You got a A"
    else if 80 < x && x < 90 then "you got a B"
    else if 70 < x && x < 80 then "You got a C"
    else if 60 < x && x < 70 then "you got a D"
    else "You got a F"

Also note, you can't do 80<x<90 - you have to combine two expressions with the && operator..

The above can be further simplified syntactically, using guards:

myScore x
    | x > 90 = "You got a A"
    | x > 80 = "you got a B"
    | x > 70 = "You got a C"
    | x > 60 = "you got a D"
    | otherwise = "You got a F"
like image 121
Peter Hall Avatar answered Oct 04 '22 21:10

Peter Hall


You need to add else before each if. Recall that in Haskell, every expression must evaluate to a value. This means that every if expression must have a matching then clause and a matching else clause. Your code only has one else with four ifs. The compiler complains because of the missing elses. When you fix it, your Haskell code will look a lot like a if...else if...else chain from other programming languages.

like image 31
Code-Apprentice Avatar answered Oct 04 '22 21:10

Code-Apprentice


For completeness, here the guard syntax suggested by @hammar:

myScore x
   | x > 90 = "A"
   | x > 80 = "B"
   | x > 70 = "C"
   | x > 60 = "D"
   | otherwise = "F"

(How about "E"?)

Note that it is not needed to check x > 80 && x < 90 here, because when it passes the first guard, it must be that x <= 90. And so for all the following guards: all preceding guards are guaranteed to be false, whenever a guard is tried.

This also corrects the logical error to score an 'F' if x == 90.

like image 37
Ingo Avatar answered Oct 04 '22 20:10

Ingo


Defining x won't define it out of its lexical scope -- in this case, x won't be accessible to anything. Instead, use the syntax

let x = 
      if 5 < 4
      then "Hmm"
      else "Better"
in "Here's what x is: " ++ x

Also, using all of those ifs is not the best way in Haskell. Instead, you can use the guard syntax:

insideText x
   | elem x [2,3,7] = "Best"
   | elem x [8,9,0] = "Better"
   | otherwise      = "Ok." 
like image 26
amindfv Avatar answered Oct 04 '22 20:10

amindfv