出于缓存目的,我想创建一个数组,它将函数的输入值映射到输出值。我知道,我的功能只会在这个特定的范围内使用,我想这样的事情:
MyType = ... deriving (Ix)
myFunction :: MyType -> foo
myCache = createArrayFromFunction (start,end) myFunction
这是可能的还是我只是认为“不起作用”,还有另一种解决方案。我需要数组,因为我需要O(1)访问成员并从头开始知道长度。
答案 0 :(得分:6)
如果您只是想创建缓存,那么只要您拥有所有索引的列表,就可以使用listArray
和map
:
myCache :: Array MyType Foo
myCache = listArray (start,end) . map myFunction $ range (start,end)
我假设正如Reid Barton指出的那样,这就是MyType
此处有Enum
个实例;如果没有,你需要一些其他方法来生成一个有效输入列表,这取决于你的类型。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