The Pervasive.in_channel in the ocaml std library is not extensible. If you want to mix different in_channel, for example, one from Pervasive and on from the Gzip library, then you are in trouble. The good fellows of extlib solved this problem providing an extensible stream data type in the IO library [1] . This is a small example using that module.

let gzip_open_in file =
    let ch = Gzip.open_in file in
    IO.create_in
    ~read:(fun () -> Gzip.input_char ch)
    ~input:(Gzip.input ch)
    ~close:(fun () -> Gzip.close_in ch)

let std_open_in file =
    let ch = open_in file in
    IO.create_in
    ~read:(fun () -> input_char ch)
    ~input:(input ch)
    ~close:(fun () -> close_in ch)

let main () =
    let file = Sys.argv.(1) in
    let ch =
        if Filename.check_suffix file ".gz" then gzip_open_in file 
        else std_open_in file
    in
    try
        while true do
            print_endline (IO.read_line ch)
        done
    with End_of_file ->
        IO.close_in ch
;;

main ();;

untested compile commands (I use ocamlbuild + custom myocamlbuild.ml):

ocamlfind ocamldep -package extlib -package zip -modules test.ml > test.ml.depends
ocamlfind ocamlc -c -package extlib -package zip -o test.cmo test.ml
ocamlfind ocamlc -linkpkg -package extlib -package zip test.cmo -o test.byte

[1] http://ocaml-lib.sourceforge.net/doc/IO.html