On 7/4/09, Marcin Kosiba <marcin.kos...@gmail.com> wrote: > On Saturday 04 July 2009, Uwe Hollerbach wrote: >> Good evening, all, following up on my question regarding space leaks, >> I seem to have stumbled across something very promising. I said I was >> using this tiny function "lastOrNil" to get the last value in a list, >> or the empty (scheme) list if the haskell list was empty. The uses of >> it were all of the form >> >> lastOrNil (mapM <something> <some list>) >> >> so I wrote a different function mapML to do this directly: >> > mapML fn lst = mapMLA (List []) fn lst >> > where mapMLA r _ [] = return r >> > mapMLA ro fn (x:xs) = >> > do rn <- fn x >> > mapMLA rn fn xs >> >> This isn't an accumulator, it's a replacer (or, if you like, the >> "accumulation" is "drop the old one on the floor"), it starts out with >> the scheme empty list that I want as the default, and it never even >> builds the list which it'll just dump an instant later. Shazam! Memory >> usage dropped by roughly an order of magnitude in my little Collatz >> benchmark, and incidentally runtime improved by 25% or so as well. The >> horror! :-) > > Hi, > IMHO expressing mapML using StateT would be a bit cleaner ;) > > mapML :: (Monad m) => (a -> m List) -> [a] -> m List > mapML fn lst = execStateT mapMLAs (List []) > where > mapMLAs = sequence_ $ map mapMLA lst > mapMLA x = (lift $ fn x) >>= put > > -- > Marcin Kosiba
Yeah, I'm sure there are more-elegant ways to write this, I'm still very much a beginner in haskell. I'm just very thrilled by the reduction in memory usage! Uwe _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe