{-# LANGUAGE CPP #-}
module IntMemo(memoInt) where
import Prelude hiding (lookup)
import CmdLineEnv(argFlag)
data IntMemo a
= Tip
| Node a (IntMemo a) (IntMemo a)
lookup :: Int -> IntMemo a -> Maybe a
lookup n m =
case m of
Tip -> Nothing
Node x l r ->
case n of
0 -> Just x
_ -> lookup (n `div` 2) ((if n `mod` 2==0 then l else r){-#STRICT#-})
memoInt :: (Int->a)->(Int->a)
memoInt f = if memoOn then g else f
where
g n = if n<0
then case lookup (-n) negtable of Just x -> x
else case lookup n table of Just x -> x
table = tabulate 0 1
negtable = tabulate 0 (-1)
tabulate n b = Node (f n) (tabulate n ((2*b){-#STRICT#-}))
(tabulate ((n+b){-#STRICT#-}) ((2*b){-#STRICT#-}))
memoOn = argFlag "memoint" True