{-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses #-} module Control.Monad.Sharing.Lazy.Simple where import Control.Monad.State import Control.Monad.Writer import Control.Monad.Sharing import Control.Monad.Sharing.Memoization newtype Lazy m a = Lazy { fromLazy :: WriterT Shared (StateT ThunkStore m) a } deriving (Monad, MonadPlus, MonadState ThunkStore, MonadWriter Shared) runLazy :: Monad m => Lazy m a -> m a runLazy m = do ((x,_),_) <- runStateT (runWriterT (fromLazy m)) emptyThunkStore return x instance MonadPlus m => Sharing (Lazy m) where share a = memo $ do (x,s) <- listen a if isShared s then shared (return x) else mapNondet share x