为什么以下代码不解析?

时间:2014-07-21 07:00:01

标签: haskell

以下代码无法解析:

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'

时解析错误

为什么会这样?

1 个答案:

答案 0 :(得分:9)

问题是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,您必须在定义let绑定时使用它(例如非常愚蠢的例子):

main = do
    let result = f
        where f = foldl' (+) 0 [1..1000000]
    print result

您可以在grammar

中查看此内容
decl    →   gendecl
        |   (funlhs | pat) rhs

rhs     →   = exp [where decls]
        |   gdrhs [where decls] 

请注意,where declsrhs规则的一部分,该规则定义了声明的右侧。如果您检查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) 
相关问题