我正在学习Haskell,并希望编写一个类似于C语言中生成二维网格的函数:
int data[3][3]
什么是一个可接受且优雅的方法?Zip?Foldl?
我可以像这样声明一个:
x = [[0,0,0],
[0,0,0],
[0,0,0]]
但我想要一个带有x和y参数的函数。很难理解不使用for/while循环的最简单方法 :(
我正在学习Haskell,并希望编写一个类似于C语言中生成二维网格的函数:
int data[3][3]
什么是一个可接受且优雅的方法?Zip?Foldl?
我可以像这样声明一个:
x = [[0,0,0],
[0,0,0],
[0,0,0]]
但我想要一个带有x和y参数的函数。很难理解不使用for/while循环的最简单方法 :(
您似乎在问“在Haskell中,我应该使用什么代替数组”,对吗?您询问了使用列表的情况,但这显然不是数组,并且对于需要非顺序访问的任何严肃工作都应该避免使用它们(例如,列表提供O(n)元素访问而不是O(1))。
您应该考虑的软件包:array(旧的、标准的Haskell数组)、vector(新的、使用流融合技术、快速、合理的API、封装或非封装、但只有一个维度,除非您将它们嵌套),以及repa(仅适用于较新的GHC版本,但允许多维数组和并行操作,即使使用非封装表示)。
初始化它们中的任何一个最简单的方法是它们各自的“fromList”函数。例如:
import Data.Vector as V
...
V.fromList $ map V.fromList [[01,02,03],[11,12,13],[22,22,23]]
(x,y)
对作为键的 Map
(import Data.Map
)。添加辅助函数进行范围检查和返回缺失条目的默认值,这样就可以很好地替代矩阵了(只要矩阵不是特别大)。我会使用一个列表的列表(:: [[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)
,我意识到我在考虑(行,列)
。您可以只需交换grid
中的x和y以获取“通常”的系统。