On Thu, Sep 29, 2022 at 10:58:36AM +0100, Richard W.M. Jones wrote:
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
Probably would have been better if I'd called those phantom types "primitive" and "boxed" :-) Rich.
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
-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-builder quickly builds VMs from scratch http://libguestfs.org/virt-builder.1.html