Lazier I/O?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Lazier I/O?

Dimitry Golubovsky-2
This may be a stupud question, but how to make I/O in Haskell really lazy?

Here is a simple program:

====

module Main where

import System.IO
import Foreign
import Data.Word
import Data.Char

s2c :: String -> [Word8]

s2c s = map (fromIntegral . ord) s

sendstr :: Handle -> String -> IO Int

sendstr h s = do
   let c = s2c s
       ln = length c
   allocaBytes ln $ \buf -> do
     pokeArray buf c
     hPutBuf h buf ln
     return ln


main = do
   hSetBuffering stdout NoBuffering
   l1 <- sendstr stdout "abcde\n"
   l2 <- sendstr stdout "defghij\n"
   putStrLn $ "sent " ++ (show l2) ++ " bytes"
   putStrLn $ "sent " ++ (show l1) ++ " bytes"

====

It prints:

abcde
defghij
sent 8 bytes
sent 6 bytes

i. e. the first string is output first although the result from that
output (how many bytes sent) is needed second.

What is desired is to have the IO actions perform as their results are
needed. I am assuming some knowledge that those actions have only
limited scope of side effects (e. g. order of outputs within a window is
significant, but order of appearance of those windows on the screen may
not be). I see some way to do this by writing regular non-monadic
Haskell stuff, representing each side effects scope (i. e. where
ordering of actions is necessary) with its own instance of an I/O like
monad (but runnable from an outside non-monadic code), and then using
unsafePerformIO as needed. But there may be some framework already
developed (albeit with unsafePerformIO, but hiding it from application
developers).

Any ideas, pointers?

Thanks

Dimitry


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lazier I/O?

Duncan Coutts
On Mon, 2005-11-28 at 07:27 -0500, Dimitry Golubovsky wrote:

> This may be a stupud question, but how to make I/O in Haskell really lazy?
>
> What is desired is to have the IO actions perform as their results are
> needed. I am assuming some knowledge that those actions have only
> limited scope of side effects (e. g. order of outputs within a window is
> significant, but order of appearance of those windows on the screen may
> not be). I see some way to do this by writing regular non-monadic
> Haskell stuff, representing each side effects scope (i. e. where
> ordering of actions is necessary) with its own instance of an I/O like
> monad (but runnable from an outside non-monadic code), and then using
> unsafePerformIO as needed. But there may be some framework already
> developed (albeit with unsafePerformIO, but hiding it from application
> developers).
>
> Any ideas, pointers?

unsafeInterleaveIO

http://haskell.org/ghc/docs/latest/html/libraries/base/System-IO-Unsafe.html#v%3AunsafeInterleaveIO

Duncan

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lazier I/O?

David Roundy
In reply to this post by Dimitry Golubovsky-2
On Mon, Nov 28, 2005 at 07:27:44AM -0500, Dimitry Golubovsky wrote:
> Any ideas, pointers?

unsafeInterleaveIO does what you want.
--
David Roundy
http://www.darcs.net
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lazier I/O?

Wolfgang Jeltsch
In reply to this post by Dimitry Golubovsky-2
Am Montag, 28. November 2005 13:27 schrieb Dimitry Golubovsky:
> [...]

> What is desired is to have the IO actions perform as their results are
> needed. I am assuming some knowledge that those actions have only
> limited scope of side effects (e. g. order of outputs within a window is
> significant, but order of appearance of those windows on the screen may
> not be). I see some way to do this by writing regular non-monadic
> Haskell stuff, representing each side effects scope (i. e. where
> ordering of actions is necessary) with its own instance of an I/O like
> monad (but runnable from an outside non-monadic code), and then using
> unsafePerformIO as needed. But there may be some framework already
> developed (albeit with unsafePerformIO, but hiding it from application
> developers).

Be very careful with unsafePerformIO.  When using it, compiler optimizations
are likely to change the semantics of your program.  In my diploma thesis, I
developed a framework for "lazy execution", based on two special monads.  
First, I implemented these monads on top of unsafePerformIO.  Then I had to
discover that it was practically impossible to make this safe but that it was
possible to implement these monads on top of unsafeInterleaveIO which I did
then.

> Any ideas, pointers?

You might want to have a look at my thesis.  Alas, it's written in German but
maybe the Haskell code it contains is useful for you.  It can be downloaded
via http://www.informatik.tu-cottbus.de/~jeltsch/diplomarbeit/.  Chapter 4 is
the "lazy execution" part.

> Thanks
>
> Dimitry

Best wishes,
Wolfgang
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe