If you just want to create a cache, then you can just use listArray
and map
, as long as you have a list of all your indices:
myCache :: Array MyType Foo
myCache = listArray (start,end) . map myFunction $ range (start,end)
I assumed that MyType
has an Enum
instance here; if it doesn't, you'll need some other way to generate a list of valid inputs, which depends on your type. As Reid Barton pointed out, this is what range
is for.
Another option, if you want to present a function to the user, would be
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 !)
Then you wouldn't export myInternalFunc
from your module; you probably wouldn't export myFuncCache
either, but I could imagine needing it. If you aren't in a module, you could put myInternalFunc
in a let
- or where
-block within myFuncCache
. Once you do this, myFunction mt
just does a cache lookup, and so is O(1).