From: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
To: Kiselyov Oleg <oleg@okmij.org>
Cc: seliopou@gmail.com, OCaML List Mailing <caml-list@inria.fr>
Subject: Re: [Caml-list] "map"-ing parameterized class types
Date: Fri, 23 Oct 2015 15:48:12 +0900 [thread overview]
Message-ID: <F35F77A2-CB10-474E-9F78-B47B2D77F5C1@math.nagoya-u.ac.jp> (raw)
In-Reply-To: <20151022150430.GA2917@Magus.sf-private>
Hi Oleg,
The externalizing solution has been known since the beginning of
OCaml, but it is nice to know that it has such a cute name…
Jacques
On 2015/10/23 00:04, Oleg wrote:
>
> The question was about creating a class of the following type
>
>> class type ['a] container : 'a ->
>> object
>> method map : 'b. ('a -> 'b) -> 'b container
>> end
>
> with a mapping method that makes a container of a different
> type. Jeremy Yallop has explained very well the class of exactly such
> type is not possible. The following is perhaps the simplest workaround
> requiring neither modules nor other higher-class artillery. It should
> have been possible even in OCaml 3.10 or earlier.
>
> The idea was inspired by some high-falutin' Math, namely, left Kan
> extension from Category Theory. I actually don't know CT but I think I
> got the gist of the left Kan extension: rather than execute an an
> operation, just collect all the needed arguments and declare the
> operation performed. The recent paper on Freer monads (Haskell
> Symposium 2015) used two instances of this new kind of laziness.
>
> Here is the whole solution
>
> type 'a cont_proxy = P of 'a
>
> class ['a] container (x : 'a) = object
> method get_x = x
> method map' : 'b. ('a -> 'b) -> 'b cont_proxy = fun f ->
> P (f x)
> end
>
> The class container has one argument, which is the value needed to
> construct the container. The data type cont_proxy contains all the
> information needed to construct the container, but not the container
> itself (for one, the container type is not yet defined when we
> declared P). The method map' doesn't actually construct anything; it
> merely returns the data needed for the construction.
>
> The map itself is then easy to define:
>
> let map : ('a -> 'b) -> ('a container -> 'b container) = fun f c ->
> match c#map' f with
> P x -> new container x
>
> let c = new container 3
> val c : int container = <obj>
> let _ = c#get_x
> - : int = 3
> let c' = map string_of_int c
> val c' : string container = <obj>
> let _ = c'#get_x
> - : string = "3"
prev parent reply other threads:[~2015-10-23 6:48 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-19 16:58 Spiros Eliopoulos
2015-10-19 18:14 ` Jeremy Yallop
2015-10-19 20:15 ` Spiros Eliopoulos
2015-10-20 11:57 ` Mikhail Mandrykin
2015-11-26 23:25 ` Glen Mével
2015-10-22 15:04 ` Oleg
2015-10-23 6:48 ` Jacques Garrigue [this message]
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=F35F77A2-CB10-474E-9F78-B47B2D77F5C1@math.nagoya-u.ac.jp \
--to=garrigue@math.nagoya-u.ac.jp \
--cc=caml-list@inria.fr \
--cc=oleg@okmij.org \
--cc=seliopou@gmail.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