It seems to be possible with phantom types & GADTs which are a very dark corner of OCaml and one which we shouldn't use, but here's how:
---------------------------------------------------------------------- type nullable type not_nullable type _ arg = | Char : not_nullable arg | Int : not_nullable arg | String : nullable arg | List : nullable arg (* # Char ;; - : not_nullable arg = Char # String ;; - : nullable arg = String *) let only_for_nullables = function | String -> "do something" | List -> "do something else" | not_nullable -> . (* val only_for_nullables : nullable arg -> string = <fun> *) ---------------------------------------------------------------------- Notes: (1) The “| not_nullable -> .” line can be omitted. It's just there to document the unreachable case, but (in this case) the compiler can infer this. (2) If you omit either of the “| String“ or “| List“ cases then the compile will warn about incomplete matching, which is good. Extending the example further, you can see how GADTs make the common case (second one below) possible, but harder to write: ---------------------------------------------------------------------- # let only_not_nullables = function | Char -> "char" | Int -> "int" ;; val only_not_nullables : not_nullable arg -> string = <fun> # let all : type a. a arg -> string = function | Char -> "char" | Int -> "int" | String -> "string" | List -> "list";; val all : 'a arg -> string = <fun> ---------------------------------------------------------------------- Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com nbdkit - Flexible, fast NBD server with plugins https://gitlab.com/nbdkit/nbdkit _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://listman.redhat.com/mailman/listinfo/libguestfs