如何从函数创建Haskell数组

时间:2010-10-17 13:36:10

标签: arrays haskell

出于缓存目的,我想创建一个数组,它将函数的输入值映射到输出值。我知道,我的功能只会在这个特定的范围内使用,我想这样的事情:

MyType = ... deriving (Ix)

myFunction :: MyType -> foo

myCache = createArrayFromFunction (start,end) myFunction

这是可能的还是我只是认为“不起作用”,还有另一种解决方案。我需要数组,因为我需要O(1)访问成员并从头开始知道长度。

2 个答案:

答案 0 :(得分:6)

如果您只是想创建缓存,那么只要您拥有所有索引的列表,就可以使用listArraymap

myCache :: Array MyType Foo
myCache = listArray (start,end) . map myFunction $ range (start,end)

我假设MyType此处有Enum个实例;如果没有,你需要一些其他方法来生成一个有效输入列表,这取决于你的类型。正如Reid Barton指出的那样,这就是range的用途。

如果要向用户提供功能,另一个选项是

myInternalFunc :: MyType -> Foo
myInternalFunc mt = (complex calculation) (using mt)

myFuncCache :: Array MyType Foo
myFuncCache = listArray (start,end) . map myFunction $ range (start,end)

myFunction :: MyType -> Foo
myFunction = (myFuncCache !)

然后你不会从模块中导出myInternalFunc;你可能也不会导出myFuncCache,但我可以想象需要它。如果您不在某个模块中,则可以将myInternalFunc放在let - 或where - myFuncCache内。执行此操作后,myFunction mt只执行缓存查找, O (1)也是如此。

答案 1 :(得分:3)

如果您正在查看数组,那么还要考虑Vector。除了融合和强大的拼接功能之外,值得注意的一个重要区别是Vector都是Int索引的。使用此库,您的生成功能是:

generate :: Int -> (Int -> a) -> Vector a