2011-06-05 103 views
9

學習Haskell和希望的功能,產生類似於2D網格瞭如何在C:生成2D網格在Haskell

int data[3][3] 

什麼是可以接受的,優雅的方法嗎?壓縮?與foldl?

我可以宣佈一個樣:

x = [[0,0,0], 
    [0,0,0], 
    [0,0,0]] 

但我想與x和y參數的函數。努力理解的最簡單的方式,而不用於/ while循環:(

+1

你是什麼意思的「生成」? – vicvicvic 2011-06-05 03:07:09

+1

@Cyclone:Haskell中的for循環看起來像什麼? – Gabe 2011-06-05 03:33:04

+0

@Gabe:我想像像http://www.xoltar.org/old_site/2003//sep/09/haskellLoops.html – Cyclone 2011-06-05 03:35:21

回答

18

你似乎在問:「我應該用什麼來代替Haskell中的數組」,對吧?您詢問了有關使用列表的問題,這些列表當然不是數組,應避免任何需要非順序訪問的嚴重工作(例如,列表提供O(n)元素訪問而不是O(1))。 (舊的,標準的Haskell數組),向量(新的,使用流融合,快速,實際上合理的API,盒裝或拆箱,但只有一個維度,除非你嵌套它們),以及(僅適用於較新的GHC版本,但允許多維數組和並行操作,即使在未裝箱的表示上也是如此)。

最簡單的方法來初始化這些(我假設你的意思是「初始化」,當你說「生成」)是他們各自的「fromList」函數。例如:

import Data.Vector as V 
... 
    V.fromList $ map V.fromList [[01,02,03],[11,12,13],[22,22,23]] 
+1

公平點,TomMD!我對「嚴肅的工作」這個術語有所反對 - 性能至關重要是更好的描述。 – vicvicvic 2011-06-05 03:50:03

+1

vicvicvic:對,我只是編輯該部分以更好地表明我的意思是性能關鍵的非順序訪問。 – 2011-06-05 03:50:57

3

我會使用(:: [[a]])列表的列表,可能會進行一些新的類型,以確保所有的名單長度相等。

要創建一個包含n值的列表,你可以使用replicate :: Int -> a -> [a],所以生成一個列表的列表,你只是再次複製列表...

grid :: Int -> Int -> a -> [[a]] 
grid x y = replicate y . replicate x 

這裏,a參數可以讓你產生任何名單任何類型的「零」值,可以這樣使用:

> grid 3 3 0 
[[0,0,0],[0,0,0],[0,0,0]] 
> grid 2 3 False 
[[False,False],[False,False],[False,False]] 

編輯:這個座標系統使用(y, x)我知道(我是在(row, column)思考)。你可以交換grid中的x和y來獲得「通常」系統。

+0

列表是一個非常糟糕的替代陣列。除非你確定你沒有任何性能問題,Dominic,我會考慮與O(1)訪問不同的數據結構。 – 2011-06-05 03:43:05

+0

哇,這是非常優雅。謝謝。現在瞭解複製! – 2011-06-05 03:43:57

+0

@TomdMD。嗯,雖然表現並不重要,但如果有更好的產品存在,我寧願不使用天真的解決方案。將研究Data.Vector – 2011-06-05 03:47:49

3

如果你想擁有的東西快速讀取和合理快「更新」不是太複雜,你應該考慮使用Mapimport Data.Map)與(x,y)雙作爲鍵。添加幫助函數進行範圍檢查並返回缺失條目的默認值,並且您有一個很好的替換(只要矩陣不是很大)