Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] extensible records again
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Oleg Trott <oleg_trott@c...>
Subject: Re: [Caml-list] extensible records again
Michael Vanier wrote:

>[...] I want users to be able to add
>their own types to the language without hacking the core type definition.
>  
>

Note that in a language like Scheme, users can not add new types other 
than by combining the primitives. So, I suppose you aren't really 
talking about language users, but those who extend the language.

The obvious thing to do is to use polymorphic variants. E.g.

(* "core language" *)

let plus a b =
   match (a, b) with
   |  (`Int x), (`Int y) -> `Int (x + y)
    (*  ... *)
   |  _ -> failwith "runtime type error: argument is not a number"

>I can do this as follows:
> 
>    (* types.mli *)
>    type data =
>        Int of int
>      | Float of float
>      | ...
>      | Extension of exn
> 
>    (* files.ml *)
>    exception File of out_channel
>                                                                                        
>    let close (d : data) =
>      match data with
>        Extension ext ->
>          (match ext with
>              File f -> (* close the file *)
>            | _ -> raise (Failure "invalid type")))
>        | _ -> raise (Failure "invalid type")
>                                                                                        
>This is OK, but it abuses the exception system.  I asked for ways to get the
>same result with polymorphic variants.  A suggested approach (thanks to
>Aleksey Nogin) was this:
>                                                                                        
># type 'a data = Int of int | Ext of 'a;;
>type 'a data = Int of int | Ext of 'a
># let open_file f =
>      match f with
>         Ext `File f -> print_string ("Opening file" ^ f)
>       | _ -> raise (Invalid_argument "open_file")
>   ;;
>val open_file : [> `File of string] data -> unit = <fun>
># let run ( f :  [> ] data -> unit) = f (Ext (`Foo 1));;
>val run : ([> `Foo of int] data -> unit) -> unit = <fun>
># run open_file;;
>Exception: Invalid_argument "open_file" 
>  
>


(* language exension example, adding "files" *)

let open = function `File f -> open_file f | _ -> failwith "runtime type 
error: argument is not a file"


HTH
Oleg

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners