2016-09-18 42 views
-2

我想在Haskell中編寫一個程序,該程序需要一個數字列表並返回最大連續子序列的值。Guard中的else語句不會編譯:解析輸入'|'時的錯誤

我收到第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的定義可用於有警衛的三條線。

回答

4

粗略地說,守衛在=左側使用,如

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