From: Warren Harris <warren@metaweb.com>
To: caml-list caml-list <caml-list@yquem.inria.fr>
Subject: killing a cat
Date: Mon, 8 Sep 2008 11:37:35 -0700 [thread overview]
Message-ID: <0233247D-28D8-4C83-9EFB-6FD4B50B3D8B@metaweb.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 3094 bytes --]
I've encountered a complicated issue that I'm wondering if anyone can
shed some light on here. It relates to polymorphic types what I like
to call Schrödinger types (sorry, I don't know the real name for
these, but they're the dreaded polymorphic variables with underscores
that, like Schrödinger's cat, are undefined until you use them for the
first time). I'll try to distill it down to its simplest form here,
but the issue arises from desiring to implement something based on
"type-indexed values" such as described here: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.53.1977
In its simplest form, I have a writer type and a dispatching handler
like this:
type ('a, 'b) writer = ((unit -> 'a) -> 'b)
type ('a, 'b) handler = { handle : 'a -> (string -> 'a -> 'b, 'b)
writer }
Then I wish to define a family of handlers that ultimately call the
writer's continuation. In the very simplest form, a handler might be
expressed as:
let f = { handle = fun a k -> write_int_field "f" a k }
which would have type "(int, 'a) handler" as desired. (In the real
implementation, there will be more than one handler, hence the need
for the record.) However, I wish to define a family of handlers that
all share common implementation, so I define a helper function (again,
vastly simplified):
let helper name wf = { handle = fun a k -> wf name a k }
let f = helper "f" write_int_field
However, here the type of "f" is now "('int, '_a) handler" and fails
to unify with the desired type expressed in the interface.
Now, I could get around this by making "f" be a function that when
evaluated returns the result of the helper. However, I'm trying to
avoid that because in the real implementation, the work of the helper
is somewhat expensive and should only be performed once. An alternate
solution can be achieved by pushing the universal qualifier for the
result type down into the handler:
type 'a handler = { handle : 'b . 'a -> (string -> 'a -> 'b, 'b)
writer }
However, this doesn't allow me to define the helper function as before:
let helper name wf = { handle = fun a k -> wf name a k };;
^^^^^^^^^^^^^^^^^^^^^^
This field value has type 'a -> (string -> 'a -> 'b, 'b) writer
which is less general than 'c. 'd -> (string -> 'd -> 'c, 'c) writer
I am forced into reworking the helper parameter function, wf, to also
become a record in order for it to be universally qualified:
type 'a field_handler = { write_field : 'b . string -> 'a -> (unit ->
string -> 'a -> 'b) -> 'b }
This works:
let helper name wf = { handle = fun a k -> wf.write_field name a k }
let f = helper "f" write_int_field
Here "f" has type "int handler" as desired, although this solution
seems somewhat round-about, and was difficult to arrive at. Can anyone
suggest another approach that prevents the dreaded underscores? (Note
that using objects instead of records exhibits the exact same behavior.)
Warren Harris
Metaweb Technologies
[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 3739 bytes --]
next reply other threads:[~2008-09-08 18:37 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-08 18:37 Warren Harris [this message]
2008-09-09 14:11 ` Zheng Li
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=0233247D-28D8-4C83-9EFB-6FD4B50B3D8B@metaweb.com \
--to=warren@metaweb.com \
--cc=caml-list@yquem.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