缓存一系列计算的中间状态

时间:2014-08-01 08:50:38

标签: haskell functional-programming composition

所以,这是一个具体的想法:我正在编写一个Scrabble游戏AI,并且在计算棋盘上所有可能移动的过程中,我必须计算每个棋盘方块的一堆中间值。我想以一种可组合的方式缓存这些中间值。

所以,更抽象地说:

没有缓存,我有f :: w a -> w bg :: w b -> w c,其中w可以是任何仿函数,但在我的情况下是Scrabble board数据类型。添加缓存后,我有f' :: m (w a) -> m (w b)g' :: m' (w b) -> m' (w c),其中mm'是包含缓存状态的 monads 数据类型*。但现在我无法撰写f'g'

我不太熟悉monad变换器,但听起来好像我在这里使用它,我需要反复lift我的monadic函数取决于我在缓存函数组合链中的深度。例如。如果我有f' . g' . h',则h'的实施需要lift . lift . lift get之类的内容。我在这里偏离基地吗?原则上,f'g'h'是无关的,并且不需要了解彼此的缓存状态。是否有更好的方法来做反映这种独立性的事情?

*我不认为他们必须是monad,因为我不打算让其他功能修改mm'。它们仅对f'g'“隐私”。

1 个答案:

答案 0 :(得分:1)

一般情况下,m (w a) -> m (w b)m' (w b) -> m' (w c)不会撰写。

如果mFunctor(或其他协变仿函数)并且m'是“尖头”(即它具有返回/纯函数),那么您可以撰写获取{ {1}}。

此外,如果m (w a) -> m (m' (w c))m并且两者都被提升为一个共同的monad(即某些monad存在函数m'm a -> t a),那么你可以使用那些提升和连接以生成m' a -> t a类型的组合。

独立性和构图是竞争目标 - 两者都很好 - 但是,要构成两件事,他们必须具有“匹配的形状”,这些形状不会让它们独立变化。