2012-04-18 77 views
1

我正在重新编写游戏,我在Haskell问了一个问题“How can I iterate over a quadruple linked 2-dimensional grid of data as if it were a 2-dimensional array?”。如何将索引转换为可变数组并将其转换为Haskell中的状态引用?

为了首先创建数据网格,我使用了一个非常必要的样式算法,如下所示。它依赖的关键特性是我可以将索引放入数组中并从中创建一个参考。例如,“& array [x] [y]”。

我需要能够索引到一个可变数组中,并在Haskell中创建一个状态引用。因此,该类型签名可能是

convertToSTRef :: i -> STArray s i a -> ST s (STRef s a) 

我已经看过的文件过来,都尝试hoogle和hayoo,并没有找到一种方法来做到这一点。

P.S.或者,如果有人使用了我可以使用的不同算法,那就太好了。

P.S.S.简单的命令式算法。

const size_t rows = 20; 
const size_t columns = 59; 

block tiles[columns][rows]; 
block * const start = &tiles[columns/2][rows/2]; 

for (size_t x = 0; x < columns; ++x) 
for (size_t y = 0; y < rows; ++y) 
{ 
    tiles[x][y].floor = '^'; 
    tiles[x][y].inhabitant = WALL; 
    tiles[x][y].side_block[EAST] = (x + 1 < columns) ? &tiles[x + 1][y] : NULL; 
    tiles[x][y].side_block[SOUTH] = (y + 1 < rows) ? &tiles[x][y + 1] : NULL; 
    tiles[x][y].side_block[WEST] = (x > 0) ? &tiles[x - 1][y] : NULL; 
    tiles[x][y].side_block[NORTH] = (y > 0) ? &tiles[x][y - 1] : NULL; 
} 
+0

您是否需要在稍后的时间更改这些参考文献指向的位置?如果没有,则根本不需要存储它们,而只需使用函数'sideBlock :: Direction - >(Int,Int) - > Maybe(Int,Int)'来代替。 – hammar 2012-04-18 21:13:50

回答

5

可以代表一个“指针”通过光标,即,包含一个数组引用和偏移量的数据结构。

data Cursor t i a = Cursor (t i a) i 

makeCursor :: STArray s i a -> i -> Cursor (STArray s) i a 
makeCursor = Cursor 

readCursor :: Ix i => Cursor (STArray s) i a -> ST s a 
readCursor (Cursor arr i) = readArray arr i 

writeCursor :: Ix i => a -> Cursor (STArray s) i a -> ST s() 
writeCursor x (Cursor arr i) = writeArray arr i x 

指向GHC中垃圾收集对象的内部是不可能的。垃圾回收器不能理解这样的指针。如果数组由垃圾收集器移动,则垃圾收集器无法正确更新这些指针。如果给垃圾收集器一个指向数组中间的指针,它将无法扫描整个数组,因为它找不到数组的开头。

+0

我想过只是将索引存储到数组中,但它更合乎逻辑(您的想法),将指针一起存储到数组和索引。 – 2012-04-18 21:16:19

相关问题