Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 从指定坐标和方向的二维数组中获取n个元素_Haskell - Fatal编程技术网

Haskell 从指定坐标和方向的二维数组中获取n个元素

Haskell 从指定坐标和方向的二维数组中获取n个元素,haskell,Haskell,我有x,y坐标和char元素的数组。我需要一个函数来获取指定坐标方向上n个字符的列表。我用循环的方式写的: import Data.Array exampleArray = array ((1,1),(2,2)) [((1,1),'a'), ((1,2),'b'), ((2,1),'c'), ((2,2),'d')] -- 1 2 -- +---+---+ -- 1 | a | b | -- +---+---+ -- 2 | c | d | --

我有x,y坐标和char元素的数组。我需要一个函数来获取指定坐标方向上n个字符的列表。我用循环的方式写的:

import Data.Array

exampleArray = array ((1,1),(2,2)) [((1,1),'a'), ((1,2),'b'), ((2,1),'c'), ((2,2),'d')]
--       1   2  
--     +---+---+
--   1 | a | b |
--     +---+---+
--   2 | c | d |
--     +---+---+

f :: Array (Int, Int) Char -> Int -> (Int, Int) -> (Int, Int) -> [Char]
f _ 0 _ _ = []
f arr n (x,y) (dirX, dirY) = (arr ! (y,x)) : f arr (n-1) (x+dirX,y+dirY) (dirX, dirY)

-- ac
list = f exampleArray 2 (1,1) (0,1) -- get 2 chars from array at 1,1 toward E

-- cb
list2 = f exampleArray 2 (1,2) (1,(-1)) -- get 2 chars from array at 1,2 toward NE

它可以工作,但太慢了,我想知道如何优化它

阵列
速度很慢,因此您的第一步应该是移植到。使用unbox变量,因为默认的“boxed”表示为每个值分配堆存储并存储指向它的指针。没有二维向量这样的东西,所以您必须编写代码将坐标对转换为一维向量中的位置。如果仍然不够快,则使用
unsafeIndex
函数及其相关函数进行访问,这些函数不进行边界检查(但不调用您所调用的函数)


另请参见。

您可以使用如下原语重新设计:
f arr n s(dx,dy)=take n。地图(啊!)。迭代(\(!y,!x)->(y+dy,x+dx))。交换$s
。你能在代码运行太慢的情况下编写一个真正简单的例子吗?我得到了非法的bang模式(使用bang模式):!我不能提供简单的例子,但是考虑GOOKU-AI中成千上万个数组中的搜索模式。如果您修复了函数,我将提供两个函数之间的时间差。使用扩展名
BangPatterns
以避免编译错误。获得最佳移动需要17秒,使用您的函数需要18秒。我正在寻找优化函数的方法,但如果将数组更改为unbox vector help,我将接受您的答案。给我一些时间,我看不出你的函数本质上有什么慢的地方,除了它使用数组,因此有很多未绑定的值。另一点是,通过使用一维实现,所有移动(N、NE、E等)都可以用一个偏移量表示,因此每一步只需进行一次加法。目前在数组中,我使用自己的类型,如
data Square=Cross | Nought | Empty
,因此我不能只使用vector,因为它需要
Unbox
实例。你认为创建/派生它会更好,还是我应该更改所有函数来处理chars?我使用
vector-th-Unbox
和port-program-to-vector.Unbox成功地派生了Unbox实例,但它运行速度慢了两倍:不看代码很难说更多。您是否在进行优化编译?