Hi, I'm trying to do IO and it isn't lazy enough. My problem seems similar to this one: Write a function that lazily reads characters from stdin, just like getContents does. These two don't work: lazyRead :: IO String lazyRead = do first_char <- getChar rest <- lazyRead return $ first_char:rest lazyRead2 :: IO String lazyRead2 = (liftM2 (:)) getChar lazyRead2 because neither has the intended behavior, because if I type: lazyRead >>= putChar . head Then it seems that all of stdin is read, not just the first character, which is different from: getContents >>= putChar . head which only reads one character. So how do you write getContents in haskell? Thanks for any insight. -- Ben Escoto
Alle 01:50, domenica 19 ottobre 2003, Ben Escoto ha scritto:
which only reads one character. So how do you write getContents in haskell? Thanks for any insight.
You have to use unsafeInterleaveIO, wich lazily defers the IO action passed as an argument. Look for this function in your documentation, both hugs and ghc have it. V.
On Sun, 19 Oct 2003 02:03:58 +0200 Nick Name <nick.name@inwind.it> wrote:
You have to use unsafeInterleaveIO, wich lazily defers the IO action passed as an argument. Look for this function in your documentation, both hugs and ghc have it.
Got it, thanks. Do you know in what sense it is "unsafe" though? Are there some pitfalls I should be aware of? -- Ben Escoto
It is unsafe because, in general, lazy IO is a bad idea. In particular: foo f x = do h <- openFile x ReadMode t <- hGetContents h v <- f t hClose h return t will do substantially different things depending on the strictness of 'f'. For instance, if 'f' is 'return . head', you might get a 'head:: empty list' error, while if 'f' is 'evaluate . head', you won't. -- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume On Sat, 18 Oct 2003, Ben Escoto wrote:
On Sun, 19 Oct 2003 02:03:58 +0200 Nick Name <nick.name@inwind.it> wrote:
You have to use unsafeInterleaveIO, wich lazily defers the IO action passed as an argument. Look for this function in your documentation, both hugs and ghc have it.
Got it, thanks. Do you know in what sense it is "unsafe" though? Are there some pitfalls I should be aware of?
-- Ben Escoto
On Sat, 18 Oct 2003 19:17:06 -0700 (PDT) Hal Daume III <hdaume@ISI.EDU> wrote:
It is unsafe because, in general, lazy IO is a bad idea. In particular:
foo f x = do h <- openFile x ReadMode t <- hGetContents h v <- f t hClose h return t
will do substantially different things depending on the strictness of 'f'. For instance, if 'f' is 'return . head', you might get a 'head:: empty list' error, while if 'f' is 'evaluate . head', you won't.
I don't understand the details of your example (for instance, what does "evaluate" do? I found a reference to it in the GHC manual under Debug.QuickCheck, but couldn't figure out what it.), but get the general point. In my case, I wanted to represent a directory tree that was too big to fit in memory. I was planning on declaring it as data DirTree = DirTree File [DirTree] but then I apparently need lazy IO. If lazy IO is bad, is data DirTree = DirTree File [IO DirTree] a better way of doing it? P.S. Thanks for your haskell book. I read it and learned a lot. -- Ben Escoto
I don't understand the details of your example (for instance, what does "evaluate" do? I found a reference to it in the GHC manual under Debug.QuickCheck, but couldn't figure out what it.), but get the general point.
evaluate is from Control.Exception; basically it's: evaluate :: a -> IO a evaluate x = x `seq` return x if I recall correctly -- it just forces something to be evaluated.
In my case, I wanted to represent a directory tree that was too big to fit in memory. I was planning on declaring it as
data DirTree = DirTree File [DirTree]
but then I apparently need lazy IO. If lazy IO is bad, is
data DirTree = DirTree File [IO DirTree]
a better way of doing it?
Hard to say. In this case, lazy io doesn't seem to bad, to me at least. but keep in mind that the DirTree can still grow very large if a lot of it is evaluated. - Hal
participants (3)
-
Ben Escoto -
Hal Daume III -
Nick Name