pipes-text- Text pipes.

Safe HaskellNone




Text IO

Where pipes IO replaces lazy IO, Producer Text IO r replaces lazy Text. This module exports some convenient functions for producing and consuming pipes Text in IO, namely, readFile, writeFile, fromHandle, toHandle, stdin and stdout. Some caveats described below.

The main points are as in Pipes.ByteString:

A Handle can be associated with a Producer or Consumer according as it is read or written to.

import Pipes
import qualified Pipes.Text as Text
import qualified Pipes.Text.IO as Text
import System.IO

main =
    withFile "inFile.txt"  ReadMode  $ \hIn  ->
    withFile "outFile.txt" WriteMode $ \hOut ->
    runEffect $ Text.fromHandle hIn >-> Text.toHandle hOut

To stream from files, the following is perhaps more Prelude-like (note that it uses Pipes.Safe):

import Pipes
import qualified Pipes.Text as Text
import qualified Pipes.Text.IO as Text
import Pipes.Safe

main = runSafeT $ runEffect $ Text.readFile "inFile.txt" >-> Text.writeFile "outFile.txt"

Finally, you can stream to and from stdin and stdout using the predefined stdin and stdout pipes, as with the following "echo" program:

main = runEffect $ Text.stdin >-> Text.stdout


The operations exported here are a convenience, like the similar operations in Data.Text.IO (or rather, Data.Text.Lazy.IO, since, again, Producer Text m r is 'effectful text' and something like the pipes equivalent of lazy Text.)

  • Like the functions in Data.Text.IO, they attempt to work with the system encoding.
  • Like the functions in Data.Text.IO, they significantly slower than ByteString operations. Where you know what encoding you are working with, use Pipes.ByteString and Pipes.Text.Encoding instead, e.g. view utf8 Bytes.stdin instead of Text.stdin
  • Like the functions in Data.Text.IO , they use Text exceptions, not the standard Pipes protocols.

Something like

 view utf8 . Bytes.fromHandle :: Handle -> Producer Text IO (Producer ByteString m ()) 

yields a stream of Text, and follows standard pipes protocols by reverting to (i.e. returning) the underlying byte stream upon reaching any decoding error. (See especially the pipes-binary package.)

By contrast, something like

Text.fromHandle :: Handle -> Producer Text IO () 

supplies a stream of text returning '()', which is convenient for many tasks, but violates the pipes pipes-binary approach to decoding errors and throws an exception of the kind characteristic of the text library instead.


fromHandle :: MonadIO m => Handle -> Producer Text m ()

Convert a Handle into a text stream using a text size determined by the good sense of the text library. Note with the remarks at the head of this module that this is slower than view utf8 (Pipes.ByteString.fromHandle h) but uses the system encoding and has other nice Data.Text.IO features

stdin :: MonadIO m => Producer Text m ()

Stream text from stdin

readFile :: MonadSafe m => FilePath -> Producer Text m ()

Stream text from a file in the simple fashion of Data.Text.IO

>>> runSafeT $ runEffect $ Text.readFile "hello.hs" >-> Text.map toUpper >-> hoist lift Text.stdout


toHandle :: MonadIO m => Handle -> Consumer' Text m r

Convert a text stream into a Handle

Note: again, for best performance, where possible use (for source (liftIO . hPutStr handle)) instead of (source >-> toHandle handle).

stdout :: MonadIO m => Consumer' Text m ()

Stream text to stdout

Unlike toHandle, stdout gracefully terminates on a broken output pipe.

Note: For best performance, it might be best just to use (for source (liftIO . putStr)) instead of (source >-> stdout) .

writeFile :: MonadSafe m => FilePath -> Consumer' Text m ()

Stream text into a file. Uses pipes-safe.