From: skaller <skaller@users.sourceforge.net>
To: David Allsopp <dra-news@metastack.com>
Cc: OCaml List <caml-list@yquem.inria.fr>
Subject: Re: [Caml-list] Polymorphic variants question
Date: Sat, 02 Sep 2006 05:29:53 +1000 [thread overview]
Message-ID: <1157138993.22787.34.camel@rosella.wigram> (raw)
In-Reply-To: <012901c6cdec$64edf490$6a7ba8c0@treble>
On Fri, 2006-09-01 at 18:31 +0100, David Allsopp wrote:
> let f x = if x = `A then (true, `B) else (false, x)
> let (f : [`A | `C] -> bool * [`A | `B | `C]) = fun x -> ...
BTW: when using polymorphic variants I find it is a good idea to:
(a) provide names (aliases, abbreviations) for your types.
(b) annotate function arguments and returns -- if not
all of them, focus on the top level ones: it's necessary
for the mli file anyhow.
(c) Prefer
let f x = match x with | ...
over
let f = fun x -> ...
and
let f = function | ..
and in particular for big top level functions like
let f (x:t1):t2 =
print_endline ("In Debug " ^ string_of_t1 x);
let r : t2 = match x with
..
in
print_endline ("Out Debug " ^ string_of_t2 r);
r
This shape instruments the input type, output type,
input value and output value.
The thing about polymorphic variants is that because
(a) the typing is structural not nominal (like ordinary variants)
(b) type inference tries to figure out the types from
usage scattered through the program
it is not only easy to extend them .. it is easy to
extend them incorrectly .. and the diagnostics from
big variants are horrible :)
Using annotations tends to localise the errors
and give you more information, including Ocaml's
smart trick of using your own alias. (This is very
clever :) It also often reports that you're missing
a particular constructor.
I've been using PM variants for a while now.
I just converted a couple of non-PM ones over.
I kind of like this function, it prints many of
the types I use in my compiler in one function,
almost like overloading :)
let string_of_term dfns term = match term with
| #qualified_name_t as x -> string_of_qualified_name x
| #regexp_t as x -> string_of_re x
| #typecode_t as x -> string_of_typecode x
| #tpattern_t as x -> string_of_tpattern x
| #literal_t as x -> string_of_literal x
| #expr_t as x -> string_of_expr x
| #pattern_t as x -> string_of_pattern x
| #statement_t as x -> string_of_statement 0 x
| #exe_t as x -> string_of_exe 0 x
| #btypecode_t as x -> string_of_btypecode dfns x
(* hack .. the type because tbexpr_t is a pair not a variant *)
| #bexpr_t as x -> string_of_bound_expression dfns (x,`BTYP_void)
| #bexe_t as x -> string_of_bexe dfns 0 x
| #ast_term_t as x -> string_of_ast_term 0 x
(* hack cause we don't know the name *)
| #symbol_definition_t as x -> string_of_symdef x "unk" []
| #bbdcl_t as x -> string_of_bbdcl dfns x 0
| #param_kind_t as x -> string_of_param_kind x
| #property_t as x -> string_of_property x
| #c_t as x -> string_of_code_spec x
| #dcl_t as x -> string_of_dcl 0 "unk" (Some 0) [] x
| #asm_t as x -> string_of_asm 0 x
| #iface_t as x -> string_of_iface 0 x
| #access_t as x -> string_of_access x
| #biface_t as x -> string_of_biface dfns 0 x
| #btype_qual_t as x -> string_of_bqual dfns x
| #type_qual_t as x -> string_of_qual x
| #requirement_t as x -> string_of_raw_req x
| #ikind_t as x -> string_of_ikind x
| #named_req_expr_t as x -> string_of_named_req_expr x
| #raw_req_expr_t as x -> string_of_raw_req_expr x
| #glr_term_t as x -> string_of_glr_term x
let st dfns term = string_of_term dfns term
This function doesn't DO anything I couldn't already do.
It just saves me worrying what the type of the term is,
and then trying to remember the name of the function that
prints it.
The PM variants let me unify any variants types I'm using,
which is why I converted most of the remaining non-PM
variants over.
Stick with them .. they're worth it!
--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net
next prev parent reply other threads:[~2006-09-01 19:30 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-01 17:31 David Allsopp
2006-09-01 18:33 ` Chris King
2006-09-01 19:00 ` [Caml-list] " skaller
2006-09-01 19:57 ` David Allsopp
2006-09-01 20:40 ` Jacques Carette
2006-09-01 18:40 ` [Caml-list] " Olivier Andrieu
2006-09-01 19:26 ` Jon Harrop
2006-09-01 19:29 ` skaller [this message]
2006-09-01 20:49 ` Andres Varon
2006-09-02 11:16 ` Jacques Garrigue
2006-09-03 1:22 ` Andres Varon
2006-09-03 9:08 ` Jacques Garrigue
2006-09-03 15:00 ` Andres Varon
2006-09-03 23:18 ` Jacques Garrigue
2006-09-03 0:48 ` [Caml-list] Polymorphic variants problem skaller
2006-09-03 1:12 ` Andres Varon
-- strict thread matches above, loose matches on Subject: below --
2001-07-20 1:05 [Caml-list] polymorphic variants question John Max Skaller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1157138993.22787.34.camel@rosella.wigram \
--to=skaller@users.sourceforge.net \
--cc=caml-list@yquem.inria.fr \
--cc=dra-news@metastack.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox