@@ -55,12 +55,14 @@ module Data.MemoTrie
55 , memo, memo2, memo3, mup
55 , memo, memo2, memo3, mup
56 , inTrie, inTrie2, inTrie3
56 , inTrie, inTrie2, inTrie3
57 -- , untrieBits
57 -- , untrieBits
58− , trieGeneric, untrieGeneric, enumerateGeneric, Reg
58+ , trieGeneric, untrieGeneric, enumerateGeneric, Reg
61-- Export the parts of HasTrie separately in order to get the associated data
62-- Export the parts of HasTrie separately in order to get the associated data
62-- type constructors, so I can define instances of other classes on them.
63-- type constructors, so I can define instances of other classes on them.
65+import Data.Function (fix)
64import Data.Bits
66import Data.Bits
65import Data.Word
67import Data.Word
66import Data.Int
68import Data.Int
@@ -168,6 +170,42 @@ mup mem f = memo (mem . f)
168memo2 = mup memo
170memo2 = mup memo
169memo3 = mup memo2
171memo3 = mup memo2
173+-- | Memoizing recursion. Use like `fix`.
174+memoFix :: HasTrie a => ((a -> b) -> (a -> b)) -> (a -> b)
175+memoFix h = fix (memo . h)
180+memoFix h = fix (\ f' -> memo (h f'))
183+ where f' = memo (h f')
194+fibF :: (Integer -> Integer) -> (Integer -> Integer)
197+fibF f n = f (n-1) + f (n-2)
199+fib :: Integer -> Integer
202+fib' :: Integer -> Integer
205+-- Try fib 30 vs fib' 30
171-- | Apply a unary function inside of a trie
209-- | Apply a unary function inside of a trie
172inTrie :: (HasTrie a, HasTrie c) =>
210inTrie :: (HasTrie a, HasTrie c) =>
173 ((a -> b) -> (c -> d))
211 ((a -> b) -> (c -> d))
@@ -685,4 +723,3 @@ dropSum s = case s of
685liftSum :: Either (f a) (g a) -> (f :+: g) a
723liftSum :: Either (f a) (g a) -> (f :+: g) a
686liftSum = either L1 R1
724liftSum = either L1 R1
687{-# INLINEABLE liftSum #-}
725{-# INLINEABLE liftSum #-}