
Hello Alistair, Friday, March 2, 2007, 5:48:17 PM, you wrote:
sure if it would be possible. I don't really understand how getContents works; is there any advice or guidelines as to how to use (or abuse) unsafeInterleaveIO? Some googling has found:
i think i can explain this dark side of IO :) one can use unsafePerformIO (not unsafeInterleaveIO) to perform i/o operations noy in predefined order but by demand. for example, the following code: do let c = unsafePerformIO getChar do_proc c will perform getChar i/o call only when value of c is really required by code, i.e. it this call will be performed lazily as any usual Haskell computation now imagine the following code: do let s = [unsafePerformIO getChar, unsafePerformIO getChar, unsafePerformIO getChar] do_proc s three chars inside this list will be computed on demand too, and this means that their values will depend on the order they are consumed. it is not that we usually need :) unsafeInterleaveIO solves this problem - it performs i/o only on demand but allows to define exact *internal* execution order for parts of your datastructure. it is why i wrote that unsafeInterleaveIO makes illegal copy of button :) first, unsafeInterleaveIO has (IO a) action as a parameter and returns value of type 'a': do str <- unsafeInterleaveIO myGetContents second, unsafeInterleaveIO don't perform any action immediately, it only creates a box of type 'a' which on requesting this value will perform action specified as a parameter third, this action by itself may compute the whole value immediately or... use unsafeInterleaveIO again to defer calculation of some sub-components: myGetContents = do c <- getChar s <- unsafeInterleaveIO myGetContents return (c:s) this code will be executed only at the moment when value of str is really demanded. in this moment, getChar will be performed (with result assigned to c) and one more lazy IO box will be created - for s. this box again contains link to the myGetContents call then, list cell returned that contains one char read and link to myGetContents call as a way to compute rest of the list. only at the moment when next value in list required, this operation will be performed again as a final result, we get inability to read second char in list before first one, but lazy character of reading in whole. bingo! ps: of course, actual code should include EOF checking. also note that you can read many chars/records at each call: myGetContents = do c <- replicateM 512 getChar s <- unsafeInterleaveIO myGetContents return (c++s) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com