List Haskell列表中存在错误

List Haskell列表中存在错误,list,haskell,guard,list-comprehension,take,List,Haskell,Guard,List Comprehension,Take,我试图在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)

我试图在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`
前两个案例运行良好,但最后一个案例给我带来了问题,我不确定原因,我得到的错误是:


的第二个参数:应该是一个列表,但是
last(xs)-take\amnt
显然只生成一个元素。试一试

row == 3 = x : head(xs) : [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)
“:”中的第二个参数应该是一个列表,
last(xs)-take\amnt
只提供一个元素


将其用“[]”括起来,这将是
[最后一个(xs)-获取\u amnt]

您的备选
更新\u游戏
定义将产生错误,而原始函数将产生
[1]
更新\u游戏[1]10
,它基于一个明确提到的假设,即列表总是正好有三个元素。@FrerichRaabe如果我没有弄错的话,在原始代码中,这将导致调用
head[]
,这将导致一个错误。@Willenss:in
update\u game[1]1 0
row==1
保持,因此,使用了
x-take\amnt:xs
;无
head
call here。在Windows控制台中,您可以通过单击窗口图标,选择“标记”,进行选择,然后按Enter键将文本复制到剪贴板来复制文本。
update_game xs index take_amnt = zipWith (-) xs (replicate (index-1) 0 ++ take_amnt : repeat 0)