我正在尝试在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`
前两种情况正常,但最后一种情况导致我出现问题,我不知道为什么,我得到的错误是:
答案 0 :(得分:2)
:
的第二个参数应该是一个列表,但last(xs) - take_amnt
显然只产生一个元素。尝试
row == 3 = x : head(xs) : [last(xs) - take_amnt]
答案 1 :(得分: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)
答案 2 :(得分:2)
“:”中的第二个参数应该是一个列表,last(xs) - take_amnt
只给出一个元素。
将其包装在“[]”中,这将是[last(xs) - take_amnt]