
Am Dienstag, 7. Oktober 2008 20:27 schrieb Andrew Coppin:
The good news: I managed to turn ResultSet into a monad transformer. Yay, me!
The bad news: It generates the entire result set before returning anything to the caller.
In other words, it works perfectly for finite result sets, and locks up forever on infinite result sets. Since the entire *point* of the monad is to handle infinite result sets correctly, that's kind-of a problem. And one that I see absolutely no way of fixing. :-(
Basically, the core code is something like
raw_bind :: (Monad m) => [[x]] -> (x -> m (ResultSet y)) -> m (ResultSet y) raw_bind [] f = return empty raw_bind (xs:xss) f = do rsYs <- mapM f xs rsZ <- raw_bind xss f return (foldr union (cost rsZ) rsYs)
As you can see, this generates all of rsZ before attempting to return anything to the caller. And I'm really struggling to see any way to avoid that.
Maybe it is as simple as raw_bind (xs:xss) f = do rsYs <- mapM f xs ~rsZ <- raw_bind xss f return (foldr union (cost rsZ) rsYs) then rsZ should only be evaluated when it's needed