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