haskell - 错误处理:不正确的缩进 Haskell
问题描述
我在使用这个简单的代码时遇到了问题,因为它给了我一个错误,指出缩进不正确。
opMe x y op = if op =="+" let x+y
main=do
op = "+"
x = 8
y = 10
print(opMe (x, y, op))
我正在寻找的回报是 18。我收到的回报是 Incorrect Indention。
解决方案
这里有很多问题。让我们一一修复它们:
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
| ^
这里的问题实际上不是缩进。这是您的if
语句没有then
or else
,因此解析器期望它继续,而不是您开始新的声明。看起来你let
在你打算使用的地方使用了then
,所以让我们改变它。此外,else
在 Haskell 中是强制性的。由于您还没有定义任何其他操作,所以我undefined
现在将使用它,它可以让您的程序编译,但如果您最终在那里崩溃。
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
| ^^^^
还是不行。具有讽刺意味的是,现在的问题是缩进,但新的错误消息不再提到这种可能性。具体来说,问题是前导空格opMe
。让我们删除它。
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 = "+"
| ^
在这里,GHC 的建议是正确的。您需要使用let
在do
块中声明变量。
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))
| ^^^^^^^^^^^^^^^
这是一组非常无用的错误消息。这些错误如此无用的原因是它们是类型不匹配错误,但您没有为 指定类型opMe
,因此 GHC 推断出一个比必要的多态性(因此给出更复杂的错误消息)的错误。让我们添加一个类型签名以获得更好的错误消息。
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))
| ^^^^^^^^^^
清楚得多。这里的问题是你定义了你的函数curried(即,opMe x y op
),但随后调用它就好像它是非curried(即,opMe (x, y, op)
)。要修复它,请选择其中一个并坚持下去。由于柯里化在 Haskell 中是惯用的,让我们继续吧:
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
我们完成了!现在可以了。
推荐阅读
- c# - 错误 NU1202:包 Microsoft.AspNetCore.Blazor.Cli 0.7.0 与 netcoreapp2.0 (.NETCoreApp,Version=v2.0) 不兼容
- java - 如何将 log4j 转换模式应用于特定包?
- javascript - 在鼠标悬停之前保存原始图像
- vba - 创建过滤循环函数
- ios - 如何将位于 UITableViewCell 中的 UIButton 与位于 View Controller 中的数据模型绑定?
- javascript - 如何根据使用 javascript 的另一个输入字段禁用某些选择按钮的选项?
- python - 如何从python中的数组中找到最小值和最大值?
- flutter - 如何在飞镖逻辑中获取每周日期列表
- python - 如何从 Python 数据框中提取和分离随机元组值?
- python - 如何在 wordnet 中使用超/下义词找到单词的抽象性?