最近我一直在使用MemoCombinators和MemoTrie軟件包,並試圖記錄一個正在採用樹的函數(這是一個真正的DAG,因爲幾個節點被共享) 。在形式:基於密鑰的記憶
data Tree k a = Branch (Tree k a) (k, a) (Tree k a) | Leaf (k, a)
所以我想memoise類型的函數(基於它的鍵):
Tree k a -> b
現在我有一個模糊的認識,這些memoisation組合子是用來把你的函數f :: a -> a
轉化爲a
的惰性(未評估)值的結構,以便在您將其拉出時已經對其進行了評估。所以這對我的樹不會有什麼問題 - 不知何故,我需要把它變成一個由k
索引的值的結構。
我想不出如何用combinator庫做到這一點。一個簡單的方法是製作一個函數k -> a
,它索引一張地圖,該地圖很適合,但看起來有點笨拙。
我誤入了這個目標,還是錯過了一些明顯的東西?
我可以很容易地看到如何寫這個功能了與這種風格,通過所有的計算線程明確我的「表」:
f :: Tree Int Int -> Map Int Int -> (Int, Map Int Int)
f (Branch l (k, x) r) m | (Just r) <- lookup k m = r
| otherwise = (max rl rr, m'')
where
(rl, m') = (f l m)
(rr, m'') = (f r m')
但事實並非如此漂亮。
請參閱 - 這是麻煩。除非我創建外部映射(從鍵 - >樹),否則沒有簡單的方法來編寫keyToTree。 – Oliver 2012-02-02 05:35:21
看看你如何寫memoFor - 問題是樹的領域不容易找到,他們不能用空氣製造。當構建表結構時,無論它是一個列表還是一個數組,它都需要是可以構建的東西的函數(或者作爲memoFor的列表提供)。嗯。 – Oliver 2012-02-02 07:36:52
@Oliver:那麼,您如何更新代碼來使用monad?然後,你可以使用狀態和緩存,因爲你得到的東西。我會用一個例子來更新。 – rampion 2012-02-02 08:02:58