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.
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.
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.
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.
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"
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 if
s. The compiler complains because of the missing else
s. When you fix it, your Haskell code will look a lot like a if...else if...else
chain from other programming languages.
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.
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 if
s 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."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With