2012-08-05 69 views
0

我不能爲我的生活弄清楚爲什麼這個if語句有問題(haskell noobie。)任何人都可以幫我解決嗎?Haskell,在輸入'解析錯誤'

fst3 (a,b,c) = a 
snd3 (a,b,c) = b 
trd3 (a,b,c) = c 
fst4 (a,b,c,d) = a 
snd4 (a,b,c,d) = b 
trd4 (a,b,c,d) = c 
qud4 (a,b,c,d) = d 

fractionalKnapsack (x:xs) = 
    fractionalKnapsack (x:xs) [] 

fractionalKnapsack (x:xs) fracList = 
    ((fst3 x),(snd3 x),(trd3 x),(snd3 x)/(trd3 x)):fracList 
    if length (x:xs) <= 1 
    then computeKnapsack sort(fracList) 
    else fractionalKnapsack xs fracList 

computeKnapsack (x:xs) = (x:xs) 
+7

作爲一個側面說明,使用三元組和四元組通常意味着您應該創建一個新的數據類型,以更充分地描述您的數據。 – 2012-08-05 14:05:26

+4

即使有三元組,也沒有必要使用這些笨拙的幫助函數:你可以直接在元組上匹配,即'fractionalKnapsack ls @((f,s,t):xs)fracList = (f, s,t,s/t):fracList' – leftaroundabout 2012-08-05 15:36:23

回答

8

這段代碼有幾個錯誤。對於fractionalKnapsack你有兩個不同的定義,每個定義都有不同數量的參數,明顯會導致編譯器有些麻煩。另外,if語句的解析錯誤是因爲實際上不應該有一個if語句,當你試圖放一個if語句時,你在到達if語句之前已經完成了函數的定義。

如果您更好地解釋了您正在嘗試執行的操作,或者您希望使用您編寫的代碼進行操作,可能會有所幫助。

3

computeKnapsack sort(fracList)

這可能是一個錯誤了。它應該是computeKnapsack (sort fracList)(或等同於computeKnapsack $ sort fracList)。

當你做computeKnapsack sort(fracList)這等於做computeKnapsack sort (fracList),這相當於做computeKnapsack sort fracList,意思是:「給computeKnapsack兩個參數:sortfracList」。

8

:是「cons」操作符。它利弊通過提供左邊的「頭」元素-tructs列表,你可以模式匹配名單上超過0元素使用:右側

ghci> 1 : [2,3,4] 
[1,2,3,4] 

「尾巴」名單。

ghci> let (x:xs) = [1,2,3,4] 
ghci> x 
1 
ghci> xs 
[2,3,4] 

,你在你的代碼中使用(x:xs)的方式暗示你還沒有列出的模式匹配的,也沒有定義的牢牢把握。而不是使用

if length (x:xs) <= 1 

它只是模式匹配更常見。一個簡單的例子:

howMany :: [a] -> String 
howMany [] = "Zero" 
howMany [x] = "One" 
howMany (x:xs) = "Many" 

Haskell函數可以用「方程式」的這樣一個順序來定義,你對你有興趣在這給我們帶來了其他問題與您的代碼可能的情況下,模式匹配,它們是:

  • fractionalKnapsack的公式不匹配。一個有1個參數,另一個有2個。你可能打算命名第二個fractionalKnapsack'
  • fractionalKnapsack定義都不處理空列表大小寫。我對此不確定;這可能是可以接受的,如果你知道它永遠不會被給出一個空列表。
  • 您的任何函數都沒有類型簽名。類型推斷可以推斷出它們,但是首先編寫類型簽名通常是一個好主意,以表達你對函數的意圖並指導你實現它。
  • fractionalKnapsack的第二個定義沒有意義。=符號後面只能有一個表達式,但是您提供了兩個表達式,用換行符分隔。這是無效的Haskell,並解釋了爲什麼在「if」上有一個解析錯誤:因爲無論您使用的編譯器/解釋器都不期望另一個表達式的開始!