On Fri, Mar 02, 2007 at 02:58:21PM +0000, Paul Moore wrote: > On 02/03/07, Bayley, Alistair <[EMAIL PROTECTED]> > wrote: > >There's a big difference between getContents and Takusen: getContents > >has a non-trivial implementation (using unsafeInterleaveIO) that allows > >it to return data lazily. Takusen has no such implementation. > > ... ie, there's deep dark magic involved in the seemingly simple > getContents, which isn't easily available to mere mortals (or even > semi-immortal library designers). That figures. It's a shame, but not > totally unsurprising.
I think I understand it ... here a some illustrative (I hope!) examples: [EMAIL PROTECTED]:~$ ghci ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.7.20070223, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help. Loading package base ... linking ... done. Prelude> :m + System.IO. System.IO.Error System.IO.Unsafe Prelude> :m + System.IO.Unsafe Prelude System.IO.Unsafe> foo <- unsafeInterleaveIO (putStr "foo") -- note that IO does NOT happen immediately Prelude System.IO.Unsafe> show foo -- but forcing it causes the IO to happen (unsafely interleaved with printing (pun intentional)) "foo()" Prelude System.IO.Unsafe> show foo -- but now that it is in WHNF, forcing it again has no effect (laziness) "()" Prelude System.IO.Unsafe> -- a more interesting case is using unsafeInterleaveIO in list recursion Prelude System.IO.Unsafe> let myGetContents = unsafeInterleaveIO $ do { ch <- getChar; chs <- myGetContents ; return (ch:chs) } Prelude System.IO.Unsafe> -- simplified by omitting support for EOF handling and block reads Prelude System.IO.Unsafe> print . map reverse . lines =<< myGetContents f["oo? ?oof"Interrupted. Prelude System.IO.Unsafe> mapM_ putStrLn . map reverse . lines =<< myGetContents foo? ?oof bar! !rab muahahaha. .ahahahaum ^D^? Interrupted. Prelude System.IO.Unsafe> > > >> That's what my earlier code looked like, and I found it harder to > >> understand than the getContents/process/put approach. I'm trying to > >> explore ways of factoring data manipulation code out of database > >> access functions, but maybe that's not the right way of doing it. > > > >I don't think it's possible to pursue this style of programming with > >Takusen. If you do, you'll have to process the entire result-set into a > >data structure and then process it, which has obvious memory > >implications. > > Oh, well. It's mostly irrelevant for me anyway, as the data sets I'm > actually playing with are small enough that slurping them into memory > isn't an issue - so I just choose between a simple and decoupled > implementation or a more complex and scalable one, which is a fairly > standard optimisation choice. > > Thanks for clarifying. > Paul. > _______________________________________________ > Haskell-Cafe mailing list > [email protected] > http://www.haskell.org/mailman/listinfo/haskell-cafe HTH Stefan _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
