{-# LANGUAGE
MultiParamTypeClasses,
Rank2Types
#-}
module Control.Monad.Sharing (
module Control.Monad,
module Control.Monad.Sharing
) where
import Control.Monad
class MonadPlus m => Nondet m a
where
mapNondet :: (forall b . Nondet m b => m b -> m (m b)) -> a -> m a
eval :: Nondet m a => a -> m a
eval = mapNondet (\a -> a >>= eval >>= return . return)
class MonadPlus m => Sharing m
where
share :: Nondet m a => m a -> m (m a)
shareRec :: (Sharing m, Nondet m a) => (m a -> m a) -> m (m a)
shareRec f = let x = share (f (x >>= id)) in x