Source

xp.memo / code / Memo / SNMap / SNMap.hs

Full commit
module Memo.SNMap.SNMap where

import System.Mem.Weak
import System.Mem.StableName

applyWeak :: (a -> b) -> SNMap a (Weak b) -> a -> b
applyWeak f table arg =
  unsafePerformIO (do
    { sn  <- mkStableName arg
    ; lkp <- lookupSNMap tbl sn
    ; case lkp of
        Nothing    -> not_found tbl sn
        Just weak  -> do { val <- deRefWeak weak
                         ; case val of 
                             Just result  -> return result
                             Nothing      -> return not_found tbl sn
                         }
    })
  where
    not_found tbl sn = do { let res = f arg
                          ; weak <- mkSimpleWeak arg res
                          ; insertSNMap tbl sn weak
                          ; return res
                          }