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.