Q:

Haskell bzlib-conduit/zlib-conduit example

Let's assume we create the file a.txt.gz as follows:
$ echo "foobar" > a.txt
$ gzip a.txt

I intend to use zlib-conduit in order to emulate zcat in Haskell.
I'm looking for a simple example that can also be applied to bzlib-conduit.
Note: This question was answered immediately in a Q&A-Style. Therefore it intentionally does not show any research effort.

A:

If you intend to work with conduits, I highly recommend to read the excellent Conduit overview by Michael Snoyman and the FP Complete tutorial on this topic first.
I've turned on my -vv flag to make this suitable for Haskell beginners (like myself).
You need three things:

A file source
A zlib decompression filter
A stdout sink

Let's start off with this simple file copy example:
import Data.Conduit (runResourceT, ($$))
import qualified Data.Conduit.Binary as CB
import Data.Conduit.Zlib

main = do
    runResourceT $ CB.sourceFile "input.txt" $$ CB.sinkFile "output.txt"

What do we need to modify here?

The input filename is not a.txt.gz
zlib decompressor is missing
We want to output to stdout, not to output.txt

Indeed the decompress documentation contains an example of how to decompress.
Note that you can't use decompress for gzip-generated files. decompress decompresses .Z files generated by the old compress UNIX program.
After modifying the above example we get:
import Data.Conduit (runResourceT, ($$), ($=))
import qualified Data.Conduit.Binary as CB
import Data.Conduit.Zlib
import System.IO

main = do
    runResourceT $ CB.sourceFile "a.txt.gz" $= ungzip $$ CB.sinkHandle stdout

The difference when using bzlib-conduit is minimal:
import Data.Conduit (runResourceT, ($$), ($=))
import qualified Data.Conduit.Binary as CB
import Data.Conduit.BZlib
import System.IO

main = do
    runResourceT $ CB.sourceFile "a.txt.bz2" $= bunzip2 $$ CB.sinkHandle stdout

