在Haskell

时间:2015-08-01 19:01:39

标签: haskell

我正在制作一个扫雷(游戏),而不是使用列表作为表示,我使用不同的集合来保持按类型收集的单元格。

我试图生成一个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

1 个答案:

答案 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),你将它作为第二个参数传递给createBoardboard),所以ghc认为board应该是一个函数并拒绝你试图给它Map

如果在函数上添加显式类型注释,您将获得更好的错误消息。