2011-06-05 84 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)双作为键。添加帮助函数进行范围检查并返回缺失条目的默认值,并且您有一个很好的替换(只要矩阵不是很大)