以下代码无法解析:
main :: IO ()
main = do
print $ result
where result = foldl' (+) 0 [1..1000000]
print $ result
where result = last [1..1000000]
编译器抱怨第二个输出:src / Main.hs:10:5:输入'print'上的解析错误
为什么是这样?
问题在于where
子句只能附加到绑定,不能附加到表达式。事实上:
main :: IO ()
main = do
print $ result
where result = foldl' (+) 0 [1..1000000]
完全等同于:
main :: IO ()
main = do
print $ result
where result = foldl' (+) 0 [1..1000000]
即在where
定义了本地定义main
不是为print $ result
行。由于where
必须是绑定的最后一部分,因此以下print
表达式显然会导致语法错误。
要where
在do
-block内部使用,您必须在定义let
此类绑定时使用它(非常愚蠢的示例):
main = do
let result = f
where f = foldl' (+) 0 [1..1000000]
print result
您可以在语法中检查此内容:
decl → gendecl
| (funlhs | pat) rhs
rhs → = exp [where decls]
| gdrhs [where decls]
请注意,where decls
是rhs
定义声明右侧的规则的一部分。如果您查看规则,exp
将不会发现以下内容where
:
exp → infixexp :: [context =>] type (expression type signature)
| infixexp
infixexp → lexp qop infixexp (infix operator application)
| - infixexp (prefix negation)
| lexp
lexp → \ apat1 … apatn -> exp (lambda abstraction, n ≥ 1)
| let decls in exp (let expression)
| if exp [;] then exp [;] else exp (conditional)
| case exp of { alts } (case expression)
| do { stmts } (do expression)
| fexp
fexp → [fexp] aexp (function application)
aexp → qvar (variable)
| gcon (general constructor)
| literal
| ( exp ) (parenthesized expression)
| ( exp1 , … , expk ) (tuple, k ≥ 2)
| [ exp1 , … , expk ] (list, k ≥ 1)
| [ exp1 [, exp2] .. [exp3] ] (arithmetic sequence)
| [ exp | qual1 , … , qualn ] (list comprehension, n ≥ 1)
| ( infixexp qop ) (left section)
| ( qop⟨-⟩ infixexp ) (right section)
| qcon { fbind1 , … , fbindn } (labeled construction, n ≥ 0)
| aexp⟨qcon⟩ { fbind1 , … , fbindn } (labeled update, n ≥ 1)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句