module Control.Monad.Trans.UnionFind
( UnionFindT, runUnionFind
, Point, fresh, repr, descriptor, union, equivalent
) where
import Control.Applicative (Applicative)
import Control.Monad.Trans.Class (MonadTrans(..))
import Control.Monad.Trans.State (StateT(..), evalStateT)
import Data.UnionFind.IntMap (Point)
import qualified Control.Monad.Trans.State as State
import qualified Data.UnionFind.IntMap as UF
newtype UnionFindT p m a = UnionFindT {
unUnionFindT :: StateT (UF.PointSupply p) m a
} deriving (Functor, Applicative, Monad, MonadTrans)
runUnionFind :: Monad m => UnionFindT p m a -> m a
runUnionFind = (`evalStateT` UF.newPointSupply) . unUnionFindT
swap :: (a, b) -> (b, a)
swap (x, y) = (y, x)
fresh :: Monad m => p -> UnionFindT p m (Point p)
fresh x = UnionFindT . StateT $ return . swap . flip UF.fresh x
repr :: Monad m => Point p -> UnionFindT p m (Point p)
repr = UnionFindT . State.gets . flip UF.repr
descriptor :: Monad m => Point p -> UnionFindT p m p
descriptor = UnionFindT . State.gets . flip UF.descriptor
union :: Monad m => Point p -> Point p -> UnionFindT p m ()
union p1 p2 = UnionFindT . State.modify $ \x -> UF.union x p1 p2
equivalent :: Monad m => Point p -> Point p -> UnionFindT p m Bool
equivalent p1 p2 = UnionFindT . State.gets $ \x -> UF.equivalent x p1 p2