2012-12-17 24 views
2

我試圖寫在Haskell一個很簡單的功能取決於輸入列表中的更改值如下Haskell的列表和逆天錯誤

update_game :: [Int] -> Int -> Int -> [Int] 
update_game (x:xs) row take_amnt | row == 1 = x - take_amnt:xs 
           | row == 2 = x : head(xs) - take_amnt : tail(xs) 
           | row == 3 = x : head(xs) : last(xs) - take_amnt` 

在前兩種情況下工作得很好,但是最後情況導致我的問題和IM不知道爲什麼,我得到的錯誤是:

http://i.stack.imgur.com/jpT8b.png

http://i.stack.imgur.com/tlz5t.png

+4

在Windows控制檯,您可以通過點擊窗口圖標複製文本,選擇「標記」,讓您的選擇,然後按Enter鍵將其複製到剪貼板。 –

回答

2

的第二個參數:應該是一個列表,但last(xs) - take_amnt顯然只產生一個單一的元素。嘗試

row == 3 = x : head(xs) : [last(xs) - take_amnt] 
2
last(xs) - take_amnt 

Int,但(:)第二個參數必須是一個列表,因爲(:) :: a -> [a] -> [a]

如果你的列表總是三個要素長(但你應該使用一個元組,而不是一個列表),因爲它似乎,包裹在一個[ ]將與語義正確解決它,

update_game :: [Int] -> Int -> Int -> [Int] 
update_game (x:xs) row take_amnt | row == 1 = x - take_amnt:xs 
           | row == 2 = x : head(xs) - take_amnt : tail(xs) 
           | row == 3 = x : head(xs) : [last(xs) - take_amnt] 

然而,這將是更好的模式匹配相應

update_game [x,y,z] 1 take_amnt = [x - take_amnt, y, z] 
update_game [x,y,z] 2 take_amnt = [x, y - take_amnt, z] 
update_game [x,y,z] 3 take_amnt = [x, y, z - take_amnt] 
update_game _  _ _   = error "Invalid input" 

或使它通用沒有模式匹配

update_game xs index take_amnt = zipWith (-) xs (replicate (index-1) 0 ++ take_amnt : repeat 0) 
+0

你的替代'update_game'定義會產生一個錯誤,而原始函數會產生'[1]''update_game [1] 1 0'。 –

+0

嗯,它基於明確提到的假設,即列表總是隻有三個元素。 –

+0

@FrerichRaabe如果我沒有弄錯,在原始代碼中會導致調用head []',這會導致錯誤。 –

2

「:」中的第二個參數應該是一個列表,last(xs) - take_amnt只給出一個元素。

包裝在「[]」這將是[last(xs) - take_amnt]