John Launchbury wrote:
> test :: [Int]
> test = do (x,z) <- [(y,1),(2*y,2), (3*y,3)]
>           Just y <- map isEven [z .. 2*z]
>           return (x+y)
> 
> isEven x = if even x then Just x else Nothing

I would expect this to be equivalent to

        test = do (~(x,z), ~(Just y)) <-
                        [(y,1),(2*y,2), (3*y,3)]
                        `prod`
                        map isEven [z .. 2*z]
                  return (x+y)

for a function

        prod :: Monad m => m a -> m b -> m (a,b)
        prod a b = do { x <- a; y <- b; return (x,y) }

But what does a single recursive binding mean?  We want the monad
to be in the class

        class Monad m => MonadLoop m where
                fix :: (a -> m a) -> m a

and then we can rewrite a recursive binding x <- e to

        x <- fix (\x -> e)

and there are reasonable definitions of fix for some monads (e.g. ST).
If we were to just use

        fix f = c where c = do { x <- c; f x }

then the one for lists is pretty useless: in the above example, we don't
know if the list of ((x,z),y)'s is nonempty until we have z, which is
coming from the list.  I think the value is bottom.


Reply via email to