我正在制作一个扫雷(游戏),而不是使用列表作为表示,我使用不同的集合来保持按类型收集的单元格。
我试图生成一个Map,它使用元组作为关键字(x坐标,y坐标)作为一对,例如像这样(0,0)。地图的价值将是包含炸弹的邻居数量。例如(0,0)1意味着单元格(0,0)与炸弹有1个邻居。
虽然我在Map.empty上收到错误,但我能够想出一个肮脏的方法来制作它。
错误
setTest.hs:57:70:
Couldn't match expected type `Map.Map (t0, t0) Int
-> Map.Map (t0, t0) Int'
with actual type `Map.Map k0 a1'
In the second argument of `createBoard', namely `Map.empty'
In the expression: createBoard listOfBombs Map.empty fieldList
In the expression:
let
fieldList = [... | x <- ..., y <- ...]
nrBombs = round $ fromIntegral (xCoord * yCoord) * 0.20
listOfBombs
= Set.fromAscList
(take nrBombs
$ nub $ randomRs ((0, 0), (xCoord, yCoord)) (mkStdGen seed))
in createBoard listOfBombs Map.empty fieldList
Failed, modules loaded: none.
我确实理解错误的出现是因为Map.empty的格式与我在函数中使用的Map不同。但是我找不到解决这个问题的方法?另外,我有一种方法可以使用Map / fold或zip链接这些功能更顺畅吗?
--Generate Set with all the neighbors of a cell
neighbours (xCoord,yCoord) = Set.fromAscList $ filter (/=(xCoord,yCoord)) [(x,y) | x <- [(pred xCoord) .. (succ xCoord)], y <- [(pred yCoord) .. (succ yCoord)]]
--Gives back the number of neighbors with a bomb for a cell
giveBackBombsNumber (xCoord,yCoord) listOfBombs = Set.size $ Set.intersection (neighbours (xCoord,yCoord)) listOfBombs
-- Will insert a cell with the number of bombs around it to the board map.
insertFunction field listOfBombs board = Map.insert field (giveBackBombsNumber field listOfBombs) board
-- Will create a new Map containing
createBoard listOfBombs board [] = board
createBoard listOfBombs board (x: xs) = createBoard listOfBombs (insertFunction x listOfBombs) xs
testFunction (xCoord,yCoord) seed = let fieldList = [(x,y) | x <- [0 .. xCoord] , y <- [0 .. yCoord]]
nrBombs = round $ fromIntegral (xCoord * yCoord) * 0.20
listOfBombs = Set.fromAscList (take nrBombs $ nub $ randomRs ((0,0), (xCoord,yCoord)) (mkStdGen seed))
in createBoard listOfBombs Map.empty fieldList
答案 0 :(得分:5)
忽略详细信息,您的错误消息显示为:
Couldn't match expected type `X -> Y'
with actual type `Map.Map k0 a1'
即。你正在使用Map
代码期待函数的地方。
可能是罪魁祸首:
createBoard listOfBombs board (x: xs) = createBoard listOfBombs (insertFunction x listOfBombs) xs
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
您使用2个参数调用insertFunction
,但需要3个。
由于currying,insertFunction x listOfBombs
本身就是一个函数(\board -> Map.insert field (giveBackBombsNumber field listOfBombs) board
),你将它作为第二个参数传递给createBoard
(board
),所以ghc认为board
应该是一个函数并拒绝你试图给它Map
。
如果在函数上添加显式类型注释,您将获得更好的错误消息。