Version française
Home     About     Download     Resources     Contact us    
Browse thread
Wrapping OCaml function returning a variant
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Serge Aleynikov <serge@h...>
Subject: Re: [Caml-list] Wrapping OCaml function returning a variant
Joel Reymont wrote:
> 
> On Mar 28, 2007, at 1:55 PM, Serge Aleynikov wrote:
> 
>> You can read the section 18.3.4 of 
>> http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html
> 
> It does not clearly explain how to handle variant types in C code. Maybe 
> I'm dumb but I did not understand it.
> 
>> Then if still unclear, examine: http://oracaml.sourceforge.net/
>> or any other C-interface library available on Caml Hump: 
>> http://caml.inria.fr/cgi-bin/hump.en.cgi?sort=0&browse=65
> 
> It looks like you are using polymorphic variants in new syntax. Maybe 
> I'm wrong but it doesn't work for me
> 
> # type foo = [Null | Int of int];;
> Syntax error

That's because this code is written using revised 
(http://caml.inria.fr/pub/docs/tutorial-camlp4/tutorial005.html) syntax. 
  These are not polymorphic variants but rather a basic union type with 
non-constant constructors.

Hint: you can start the ocaml toplevel like this to get it understand 
revised syntax: "ocaml camlp4r.cma".

 > I still don't understand how I can handle regular variants of the
 > following type returned by OCaml to the C side

In terms of your example above, on the C side you would do:

void bar(value foo) {
   if (Is_long(foo)) {
      switch (Long_val(foo)) {
        case 0: /* Null */
          ...
          break;
        /* if there are other constant constructors besides Null
           add additional cases here */
        default:
          fail_exception(Long_val(foo), "Unknown constant constructor!");
      }
   } else {
      switch (Tag_val(foo)) {
        case 0:  /* Int of int */
          /* Access the non-constant value by Long_val(Field(foo,0))) */
          break;
        ...
      }
   }
}

Regards,

Serge