packages feed

lazyio 0.0.3.3 → 0.1

raw patch · 5 files changed

+46/−31 lines, 5 files

Files

+ CHANGES view
@@ -0,0 +1,7 @@+0.1++* System.IO.Lazy.T: remove MonadIO instance,+liftIO did not satisfy MonadIO laws.+You must use the new function LazyIO.interleave instead.+A positive side-effect is that you do not need+to depend explicitly on 'transformers' anymore.
lazyio.cabal view
@@ -1,5 +1,5 @@ Name:             lazyio-Version:          0.0.3.3+Version:          0.1 License:          BSD3 License-File:     LICENSE Author:           Henning Thielemann <haskell@henning-thielemann.de>@@ -17,6 +17,9 @@ Tested-With:       GHC==7.4.1, GHC==7.6.3 Cabal-Version:     >=1.6 Build-Type:        Simple+Extra-Source-Files:+  CHANGES+ Source-Repository head   type:     darcs   location: http://code.haskell.org/~thielema/lazyio/@@ -24,7 +27,7 @@ Source-Repository this   type:     darcs   location: http://code.haskell.org/~thielema/lazyio/-  tag:      0.0.3.3+  tag:      0.1  Flag splitBase   description: Choose the new smaller, split-up base package.
src/System/IO/Lazy.hs view
@@ -1,9 +1,9 @@ {- | Caution: -- Although this module calls 'Unsafe.interleaveIO' for you,+- Although this module calls 'unsafeInterleaveIO' for you,   it cannot take the responsibility from you.-  Using this module is still as unsafe as calling 'Unsafe.interleaveIO' manually.+  Using this module is still as unsafe as calling 'unsafeInterleaveIO' manually.   Thus we recommend to wrap the lazy I/O monad   into a custom @newtype@ with a restricted set of operations   which is considered safe for interleaving I/O actions.@@ -14,25 +14,31 @@   It will also often be the case, that not the complete output is read,   and thus the closing action is never reached.   It is certainly best to call a closing action after you wrote-  the complete result of the lazy I/O monad somewhere+  the complete result of the lazy I/O monad somewhere. -- @return a :: LazyIO a@ is very different from @liftIO (return a) :: LazyIO a@.+- @return a :: LazyIO a@ is very different+  from @interleave (return a) :: LazyIO a@.   The first one does not trigger previous IO actions,   whereas the second one does.+  This is the reason why we do not instantiate @MonadIO@+  with @liftIO = LazyIO.interleave@,+  despite the matching type signatures.+  One of the @MonadIO@ laws explicitly requires @return a = liftIO (return a)@.  - We advise to lift strict IO functions into the lazy IO monad.   Lifting a function like @readFile@ may lead to unintended interleaving.+  In the future we may enforce that using the @deepseq@ package.  Use it like  > import qualified System.IO.Lazy as LazyIO >-> LazyIO.run $->    do liftIO $ putStr "enter first line:"->       x <- liftIO getLine->       liftIO $ putStr "enter second line:"->       y <- liftIO getLine->       return x+> LazyIO.run $ do+>    LazyIO.interleave $ putStr "enter first line:"+>    x <- LazyIO.interleave getLine+>    LazyIO.interleave $ putStr "enter second line:"+>    y <- LazyIO.interleave getLine+>    return x  Because only the first entered line is needed, only the first prompt and the first 'getLine' is executed.@@ -40,9 +46,9 @@ module System.IO.Lazy (    T,    run,+   interleave,    ) where -import Control.Monad.IO.Class (MonadIO(liftIO), ) import Control.Monad.Trans.State (StateT(StateT), mapStateT, evalStateT, {- runStateT, -} ) import Control.Monad (ap, {- liftM2, -} ) import Control.Applicative (Applicative(pure, (<*>)), )@@ -67,8 +73,8 @@    pure = return    (<*>) = ap -instance MonadIO T where-   liftIO m = Cons $ StateT $ \RunAll -> fmap (\x->(x,RunAll)) m+interleave :: IO a -> T a+interleave m = Cons $ StateT $ \RunAll -> fmap (\x->(x,RunAll)) m  run :: T a -> IO a run =@@ -76,17 +82,17 @@  {- correct:-run $ do x <- liftIO getLine; y <- liftIO getLine; a <- return (x,y); return (fst a)+run $ do x <- interleave getLine; y <- interleave getLine; a <- return (x,y); return (fst a) -*LazyIO> run (Control.Monad.replicateM 5 (liftIO getChar)) >>= putStrLn+*LazyIO> run (Control.Monad.replicateM 5 (interleave getChar)) >>= putStrLn 0011223344 -*LazyIO> run (liftIO (putStrLn "bla") >> liftIO getLine) >>= print+*LazyIO> run (interleave (putStrLn "bla") >> interleave getLine) >>= print "bla 1 1" -*LazyIO> run $ Monad.liftM (\ ((a,b),(c,d))->b) $ liftM2 (,) (liftM2 (,) (liftIO getLine) (liftIO getLine)) (liftM2 (,) (liftIO getLine) (liftIO getLine))+*LazyIO> run $ Monad.liftM (\ ((a,b),(c,d))->b) $ liftM2 (,) (liftM2 (,) (interleave getLine) (interleave getLine)) (liftM2 (,) (interleave getLine) (interleave getLine)) "1 2 2"@@ -94,12 +100,12 @@  {- testLazy, testStrict :: IO String-testLazy   = run $ liftM2 (const)      (liftIO getLine) (liftIO getLine)-testStrict = run $ liftM2 (flip const) (liftIO getLine) (liftIO getLine)+testLazy   = run $ liftM2 (const)      (interleave getLine) (interleave getLine)+testStrict = run $ liftM2 (flip const) (interleave getLine) (interleave getLine)  test :: IO (String, RunAll) test = flip runStateT RunAll $ decons $-   liftIO getLine >>= \x ->-   liftIO getLine >>+   interleave getLine >>= \x ->+   interleave getLine >>    return x -}
src/System/IO/Lazy/Applicative.hs view
@@ -19,12 +19,12 @@    Cons f <*> Cons x = Cons $ liftM2 (<*>) f x  -- instance MonadIO T where-liftIO :: IO a -> T a-liftIO = Cons . Unsafe.interleaveIO . fmap (Chain.Cons Chain.RunAll)+interleave :: IO a -> T a+interleave = Cons . Unsafe.interleaveIO . fmap (Chain.Cons Chain.RunAll)  run :: T a -> IO a run = fmap Chain.result . decons  {--run $ liftA (\ ~( ~(a,b), ~(c,d)) -> a) $ liftA2 (,) (liftA2 (,) (liftIO getLine) (liftIO getLine)) (liftA2 (,) (liftIO getLine) (liftIO getLine))+run $ liftA (\ ~( ~(a,b), ~(c,d)) -> a) $ liftA2 (,) (liftA2 (,) (interleave getLine) (interleave getLine)) (liftA2 (,) (interleave getLine) (interleave getLine)) -}
src/Test/Main.hs view
@@ -2,11 +2,10 @@  import qualified System.IO.Lazy as LazyIO import qualified System.IO as IO-import Control.Monad.IO.Class (MonadIO(liftIO), )-import Control.Monad.Trans.Reader (ReaderT, runReaderT, asks, )+import System.Exit (exitFailure, ) +import Control.Monad.Trans.Reader (ReaderT(ReaderT), runReaderT, ) import Control.Monad (liftM2, )-import System.Exit (exitFailure, )  import Prelude hiding (getLine, ) @@ -47,7 +46,7 @@  getLine :: HasReadHandle h => ReaderT h LazyIO.T String getLine =-   asks getReadHandle >>= \h -> liftIO $ IO.hGetLine h+   ReaderT $ LazyIO.interleave . IO.hGetLine . getReadHandle  getLinePair :: HasReadHandle h => ReaderT h LazyIO.T (String, String) getLinePair =@@ -76,7 +75,7 @@  putLine :: HasWriteHandle h => String -> ReaderT h LazyIO.T () putLine str =-   asks getWriteHandle >>= \h -> liftIO $ IO.hPutStrLn h str+   ReaderT $ \h -> LazyIO.interleave $ IO.hPutStrLn (getWriteHandle h) str  runReadWriteTest ::    String -> String -> ReaderT ReadWriteHandle LazyIO.T a -> (a -> IO ()) -> IO ()