我在做一个Haskell库。我需要一个大的(约10万个项目)带整数值的未装箱数组,以便不时地从库的各个部分访问它们。数组应该包含需要初始化一次的预先计算的数据。它们的初始化的实现没有问题。问题是如何更好地构造它们的初始化,并为其余部分提供对它们的访问。图书馆。我考虑以下可能性:
1.用数组定义一个记录类型,并使用Readermonad提供一个预计算数据的环境。
1.使用ST monad构建数组,并使用每个数组的常规函数访问它们。
第一个选项似乎可以工作,但它需要在Reader中执行所有操作第二个选项似乎可以,但我不确定计算结果是否会一直存储在运行时中,即数组不会被GC扫描并重新初始化。(数组很大,它们的初始化很繁重)。我的推理正确吗?如果正确,哪个选项更好?我承认我可能会错过其他可能性,是否有其他方法或模式来处理预先计算的数据?
1条答案
按热度按时间q3qa4bjr1#
如果在顶层定义未装箱的
Array
或Vector
:字符串
那么只要
myData
被强制为WHNF,所有的值将被完全计算,并且对myData
的元素的所有访问将使用预先计算的值。如果你不手动强制,那么当
myData
的元素在程序中的任何地方被第一次访问时,所有的值都将被预先计算。这可能就足够了。否则,你可以在IO monad中用evaluate
强制它。下面的测试程序说明了这种方法。你应该观察到Loading myData...
和DONE
之间的延迟,但是在访问预先计算的元素时没有进一步的延迟。型
如果你需要在初始化中使用
ST
monad,也可以。只需在myData
中完成所有ST
的工作,并返回最终的不可变向量。例如,将上面程序中的myData
替换为以下内容即可:型