我是否必须在所有2D操作中使用Array2D然后将它们转换为List2D?任何方便的函数调用或库来定义和操作2D列表?
答案 0 :(得分:6)
简答:不,没有2d列表。
更长的回答:
我认为这样的类型在创建时会有问题,因为它的直接实现要么在其等效的cons操作上没有O(1)复杂性,要么破坏结构相等。
F#列表和数组并不是完全相同的。让我们回想起一些关于F#列表的事实,人们会认为它们具有2d版本。它们:
两个维度中的F#列表的等价物可以被认为是格子状结构中的矩形,例如:
N: Node N-N-0
0: None | |
N-N-N-0
| | |
N-N-N-N-N-0
| | | | |
0 0 0 0 0
其中-
表示左边的节点包含对右边的引用,|
表示上面的节点保存对下面节点的引用。就像在一维列表中一样,每个节点将包含一个完整的2d列表,即矩形中从其自身到右下角的最后一个节点的所有元素。
由于列表应该是不可变的但允许从子列表进行迭代构造,因此通过添加节点创建新列表仅在以下三种情况下有效:
这就是麻烦的来源。你怎么知道两个邻居在结构比较的世界中建立在相同的子列表上?您可以通过右下和右下路径从新节点沿对角线向下一步,看看您是否最终处于同一元素。如果结果不同(由于参数无效而失败)或引用相同(新的2d列表有效),这是好的和花花公子,但是如果它们的内容相同但是它们的身份不是什么呢?换句话说:它们是不同的对象但可能是等价的?现在,我们被迫完成整个事情并比较一切,否则我们最终可能会构建一些根本不是二维的疯狂图形。
这需要比较整个子列表,这些子列表是从新插入节点到最右下节点一步对角线的节点。那不太实际;构建像这样的n个元素的2d列表将具有O(n ^ 2) - 除非存在某种形式的优化,例如跟踪所有节点并给予等效节点唯一标识。
此时,我想我可以看到为什么这样的东西没有进入F#核心库。