我如何使用守卫:输入'|'时出现解析错误

How do I use guards: parse error on input '|'

编辑:这是一个老问题,Whosebug 不允许我删除。当时我不明白守卫什么时候合适,选择的答案很好地描述了这一点。

我正在尝试在 Haskell 中编写一个程序,该程序采用数字列表和 returns 最大连续子序列的值。

第 7 行出现编译错误,第一个守卫所在的那一行。

maxsubseq list = maxsubseqRecurse 0 list

maxsubseqRecurse sofar restOfList =
   if null restOfList
      then sofar
      else
         | if newSofar < 0
         |     then maxsubseqRecurse 0     newRestOfList
         |     else maxsubseqRecurse sofar newRestOfList
         where
            newSofar = sofar + head restOfList
            newRestOfList = tail restOfList

为什么守卫不是有效的语法?我的意图是使newSofar和newRestOfList的定义可用于有守卫的三行。

粗略地说,守卫用在=的左边,如

f x y
   | cond1 x y = ...
   | cond2 x y = ...
   | otherwise = ...

在您的代码中,只需删除 |——您不需要守卫。 if 足够了。

此外,使用 if null, head, tail 是不合常理的,因为存在更好的选择。请记住,head,tail 会在您忘记 null 检查的那一天使您的程序崩溃。由于模式匹配没有这个问题,因此在可能的情况下是首选。

maxsubseqRecurse sofar [] = sofar
maxsubseqRecurse sofar (h:newRestOfList) =
    if newSofar < 0
    then maxsubseqRecurse 0     newRestOfList
    else maxsubseqRecurse sofar newRestOfList
       where
       newSofar = sofar + h

重新引入守卫,我们得到:

maxsubseqRecurse sofar [] = sofar
maxsubseqRecurse sofar (h:newRestOfList)
   | newSofar < 0 = maxsubseqRecurse 0     newRestOfList
   | otherwise    = maxsubseqRecurse sofar newRestOfList
   where
   newSofar = sofar + h