Reputation: 1
I am having trouble with this simple code as it is giving me an error stating that there is an incorrect Indention.
opMe x y op = if op =="+" let x+y
main=do
op = "+"
x = 8
y = 10
print(opMe (x, y, op))
The return I am looking for is 18. The return I have received is Incorrect Indention.
Upvotes: 0
Views: 74
Reputation: 48572
Lots of problems here. Let's fix them one by one:
opMe x y op = if op =="+" let x+y
main=do
op = "+"
x = 8
y = 10
print(opMe (x, y, op))
q58566673.hs:3:1: error:
parse error (possibly incorrect indentation or mismatched brackets)
|
3 | main=do
| ^
The problem here isn't actually indentation. It's that your if
statement doesn't have a then
or else
, so the parser is expecting it to continue, rather than you starting a new declaration. It looks like you used let
where you meant to use then
, so let's change that. Also, else
is mandatory in Haskell. Since you didn't define any other operations yet, I'll use undefined
for now, which will let your program compile, but crash if you ever end up there.
opMe x y op = if op =="+" then x+y else undefined
main=do
op = "+"
x = 8
y = 10
print(opMe (x, y, op))
q58566673.hs:3:1: error: parse error on input ‘main’
|
3 | main=do
| ^^^^
Still doesn't work. Ironically, now the problem is indentation, but the new error message no longer mentions that as a possibility. Specifically, the problem is the leading space before opMe
. Let's remove that.
opMe x y op = if op =="+" then x+y else undefined
main=do
op = "+"
x = 8
y = 10
print(opMe (x, y, op))
q58566673.hs:4:6: error:
parse error on input ‘=’
Perhaps you need a 'let' in a 'do' block?
e.g. 'let x = 5' instead of 'x = 5'
|
4 | op = "+"
| ^
Here, GHC's suggestion is correct. You need to use let
to declare variables in a do
block.
opMe x y op = if op =="+" then x+y else undefined
main=do
let op = "+"
let x = 8
let y = 10
print(opMe (x, y, op))
q58566673.hs:5:11: error:
• Ambiguous type variable ‘a0’ arising from the literal ‘8’
prevents the constraint ‘(Num a0)’ from being solved.
Relevant bindings include x :: a0 (bound at q58566673.hs:5:7)
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Num Integer -- Defined in ‘GHC.Num’
instance Num Double -- Defined in ‘GHC.Float’
instance Num Float -- Defined in ‘GHC.Float’
...plus two others
...plus one instance involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the expression: 8
In an equation for ‘x’: x = 8
In the expression:
do let op = "+"
let x = 8
let y = 10
print (opMe (x, y, op))
|
5 | let x = 8
| ^
q58566673.hs:6:11: error:
• Ambiguous type variable ‘b0’ arising from the literal ‘10’
prevents the constraint ‘(Num b0)’ from being solved.
Relevant bindings include y :: b0 (bound at q58566673.hs:6:7)
Probable fix: use a type annotation to specify what ‘b0’ should be.
These potential instances exist:
instance Num Integer -- Defined in ‘GHC.Num’
instance Num Double -- Defined in ‘GHC.Float’
instance Num Float -- Defined in ‘GHC.Float’
...plus two others
...plus one instance involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the expression: 10
In an equation for ‘y’: y = 10
In the expression:
do let op = "+"
let x = 8
let y = 10
print (opMe (x, y, op))
|
6 | let y = 10
| ^^
q58566673.hs:7:3: error:
• No instance for (Show
((a0, b0, [Char]) -> [Char] -> (a0, b0, [Char])))
arising from a use of ‘print’
(maybe you haven't applied a function to enough arguments?)
• In a stmt of a 'do' block: print (opMe (x, y, op))
In the expression:
do let op = "+"
let x = 8
let y = 10
print (opMe (x, y, op))
In an equation for ‘main’:
main
= do let op = ...
let x = ...
let y = ...
....
|
7 | print(opMe (x, y, op))
| ^^^^^^^^^^^^^^^^^^^^^^
q58566673.hs:7:9: error:
• No instance for (Num (a0, b0, [Char]))
arising from a use of ‘opMe’
• In the first argument of ‘print’, namely ‘(opMe (x, y, op))’
In a stmt of a 'do' block: print (opMe (x, y, op))
In the expression:
do let op = "+"
let x = 8
let y = 10
print (opMe (x, y, op))
|
7 | print(opMe (x, y, op))
| ^^^^^^^^^^^^^^^
That's a spectacularly unhelpful set of error messages. The reason these errors are so unhelpful is that they're a type mismatch error, but you didn't specify a type for opMe
, so GHC inferred one that was more polymorphic (and thus gives more complicated error messages) than necessary. Let's add a type signature to get a better error message.
opMe :: Integer -> Integer -> String -> Integer
opMe x y op = if op =="+" then x+y else undefined
main=do
let op = "+"
let x = 8
let y = 10
print(opMe (x, y, op))
q58566673.hs:8:14: error:
• Couldn't match expected type ‘Integer’
with actual type ‘(Integer, Integer, [Char])’
• In the first argument of ‘opMe’, namely ‘(x, y, op)’
In the first argument of ‘print’, namely ‘(opMe (x, y, op))’
In a stmt of a 'do' block: print (opMe (x, y, op))
|
8 | print(opMe (x, y, op))
| ^^^^^^^^^^
Much more clear. The problem here is that you defined your function curried (i.e., opMe x y op
), but then called it as if it were uncurried (i.e., opMe (x, y, op)
). To fix it, pick one or the other and stick to it. Since currying is idiomatic in Haskell, let's go with it:
opMe :: Integer -> Integer -> String -> Integer
opMe x y op = if op =="+" then x+y else undefined
main=do
let op = "+"
let x = 8
let y = 10
print(opMe x y op)
18
And we're done! It works now.
Upvotes: 2