caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Warren Harris <warrensomebody@gmail.com>
To: OCaml <caml-list@inria.fr>
Subject: polymorphic variants and recursive functions
Date: Wed, 25 Mar 2009 14:39:28 -0700	[thread overview]
Message-ID: <CA29810E-1260-4571-87FA-96C71F62C065@gmail.com> (raw)

I stumbled upon a little puzzle that I can't quite work out. I'm  
trying to use polymorphic variants as phantom types and in one  
particular situation involving a polymorphic type with an invariant  
type parameter (Lwt.t) the compiler is unhappy with a set of mutually  
recursive functions. I can appreciate at some level that an invariant  
type parameter will cause the phantom types to become unsatisfied, but  
in this particular case my sense is that they should be satisfiable,  
and feel that I might be overlooking an appropriate coercion. Perhaps  
someone here can lend a hand...


Here's the best I can do at creating a simple example: First, here's  
the case the works... I would like a family of constructors, including  
two higher-order ones, 'arr' and 'obj', such that 'arr' can only be  
constructed from 'obj' instances:

let obj (v:[> `V]) : [`O|`V] = `V
let arr (v:[> `O]) : [`V]    = `V
let v0 : [`V]                = `V

This works as expected:

let ok1 = obj v0
let ok2 = arr (obj v0)
let ok3 = obj (arr (obj v0))

and fails as expected:

let fail1 = arr v0
                   ^^
This expression has type [ `V ] but is here used with type [> `O ]
The first variant type does not allow tag(s) `O

I can now use these constructors in conjunction with some mutually- 
recursive functions (coercions are needed):

let rec eval = function
   | `Arr v -> (eval_arr v : [`V]    :> [> `V])
   | `Obj v -> (eval_obj v : [`V|`O] :> [> `V])
and eval_arr v = arr (eval_obj v)
and eval_obj v = obj (eval v)

although oddly, the coercions don't seem to affect the final type of  
eval:

val eval : ([< `Arr of 'a | `Obj of 'a ] as 'a) -> [ `O | `V ] = <fun>
val eval_arr : ([< `Arr of 'a | `Obj of 'a ] as 'a) -> [ `V ] = <fun>
val eval_obj : ([< `Arr of 'a | `Obj of 'a ] as 'a) -> [ `O | `V ] =  
<fun>



Now the case that doesn't work: Introducing 'a Lwt.t into the above:

open Lwt
let obj (v:[> `V]) : [`O|`V] Lwt.t = return `V
let arr (v:[> `O]) : [`V] Lwt.t    = return `V
let v0 : [`V] Lwt.t                = return `V

let ok1 = v0 >>= obj
let ok2 = v0 >>= obj >>= arr
let ok3 = v0 >>= obj >>= arr >>= obj
(*let fail1 = v0 >>= arr*)

let rec eval = function
   | `Arr v -> (eval_arr v : [`V] Lwt.t    :> [> `V] Lwt.t)
   | `Obj v -> (eval_obj v : [`V|`O] Lwt.t :> [> `V] Lwt.t)
and eval_arr v = eval_obj v >>= arr
and eval_obj v = eval v >>= obj

     | `Obj v -> (eval_obj v : [`V|`O] Lwt.t :> [> `V] Lwt.t)
                  ^^^^^^^^^^
This expression has type [ `O | `V ] Lwt.t but is here used with type
   [ `V ] Lwt.t
The second variant type does not allow tag(s) `O



Any suggestions would be much appreciated,

Warren


             reply	other threads:[~2009-03-25 21:39 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-25 21:39 Warren Harris [this message]
2009-03-25 23:24 ` [Caml-list] " Mauricio Fernandez
2009-03-26  0:06   ` [Caml-list] polymorphic variants and recursive functions (caml: to exclusive) Warren Harris

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=CA29810E-1260-4571-87FA-96C71F62C065@gmail.com \
    --to=warrensomebody@gmail.com \
    --cc=caml-list@inria.fr \
    /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;
as well as URLs for NNTP newsgroup(s).