By the way, you can use this stuff to solve the restricted monad
problem (e.g. make Set an instance of Monad). This is not that useful
until we find out what the mother of all MonadPlus is, though, because
we really need a MonadPlus Set instance.

Code below.

Cheers,
Max

\begin{code}
{-# LANGUAGE RankNTypes #-}
import Control.Applicative

import Data.Set (Set)
import qualified Data.Set as S


newtype CodensityOrd m a = CodensityOrd { runCodensityOrd :: forall b.
Ord b => (a -> m b) -> m b }

-- liftCodensityOrd :: Monad m => m a -> CodensityOrd m a
-- liftCodensityOrd m = CodensityOrd ((>>=) m)

-- lowerCodensityOrd :: (Ord a, Monad m) => CodensityOrd m a -> m a
-- lowerCodensityOrd m = runCodensityOrd m return

instance Functor (CodensityOrd f) where
    fmap f m = CodensityOrd (\k -> runCodensityOrd m (k . f))

instance Applicative (CodensityOrd f) where
    pure x = CodensityOrd (\k -> k x)
    mf <*> mx = CodensityOrd (\k -> runCodensityOrd mf (\f ->
runCodensityOrd mx (\x -> k (f x))))

instance Monad (CodensityOrd f) where
    return = pure
    m >>= k = CodensityOrd (\c -> runCodensityOrd m (\a ->
runCodensityOrd (k a) c))



liftSet :: Ord a => Set a -> CodensityOrd Set a
liftSet m = CodensityOrd (bind m)
    where bind :: (Ord a, Ord b) => Set a -> (a -> Set b) -> Set b
          mx `bind` fxmy = S.fold (\x my -> fxmy x `S.union` my) S.empty mx

lowerSet :: Ord a => CodensityOrd Set a -> Set a
lowerSet m = runCodensityOrd m S.singleton


main = print $ lowerSet $ monadicPlus (liftSet $ S.fromList [1, 2, 3])
(liftSet $ S.fromList [1, 2, 3])

monadicPlus :: Monad m => m Int -> m Int -> m Int
monadicPlus mx my = do
    x <- mx
    y <- my
    return (x + y)

\end{code}
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to