2

我正在尝试在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`

前两种情况工作正常,但是最后一种情况给我带来了问题,我不知道为什么,我得到的错误是:

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

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

4

3 回答 3

2

to 的第二个参数:应该是一个列表,但last(xs) - take_amnt显然只产生一个元素。尝试

row == 3 = x : head(xs) : [last(xs) - take_amnt]
于 2012-12-17T20:34:04.467 回答
2
last(xs) - take_amnt

Int,但 的第二个参数(:)必须是列表,因为(:) :: a -> [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)
于 2012-12-17T20:34:13.780 回答
2

":" 中的第二个参数应该是一个列表,last(xs) - take_amnt只给出一个元素。

将它包装在“[]”中,这将是[last(xs) - take_amnt]

于 2012-12-17T20:36:47.900 回答