caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] accessing the type of a polymorphic parameter
@ 2012-10-26 18:01 "Mark"
  2012-10-26 19:23 ` Gabriel Scherer
  2012-10-26 21:31 ` Anil Madhavapeddy
  0 siblings, 2 replies; 6+ messages in thread
From: "Mark" @ 2012-10-26 18:01 UTC (permalink / raw)
  To: caml-list

Hello.

Is it possible in OCaml for a polymorphic function to somehow have
access to the concrete type of an actual parameter used in a call of
the function?

For example, is there some way of writing a polymorphic function 'foo'
list this:

     let foo x =
        match (type_of x) with
          Int    -> ....
        | String -> ....

where 'type_of' is some function that returns a representation of the
concrete type of its argument.

I want this because I want to implement an ad-hoc polymorphic
function.  I know this is outside the bounds of "normal" OCaml, but is
there some nasty part of the language like Obj.magic that I could use
to achieve this?

Mark.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] accessing the type of a polymorphic parameter
  2012-10-26 18:01 [Caml-list] accessing the type of a polymorphic parameter "Mark"
@ 2012-10-26 19:23 ` Gabriel Scherer
  2012-10-26 21:31 ` Anil Madhavapeddy
  1 sibling, 0 replies; 6+ messages in thread
From: Gabriel Scherer @ 2012-10-26 19:23 UTC (permalink / raw)
  To: "Mark"; +Cc: caml-list

Short answer: no, it is not possible to do this.

Long answer: I presume that your implementation works for any type
providing some fixed set of operations, but that you wish those
operations to be implemented differently for each type. You can define
a type ('a ops) describing these operations on the type 'a (as a
record of functions for example), and use the polymorphic type ('a ->
'a ops -> foo) instead of ('a -> foo) to write your function.
Depending on your specific needs there may be slightly different
approaches (using a algebraic representation of runtime types rather
than a typeclass-like dictionary), a very general way being described
in this blog post by Alain Frisch :
  http://www.lexifi.com/blog/dynamic-types
It could help to have more details on your needs to suggest a better solution.

Wrong answer: yes, using Obj.magic you can access the runtime
representation of values. You can't distinguish between boolean and
integers and the empty list, but worrying about that is for the
coward, let's shoot yourself in the foot -- starting by reading the
documentation on the representation of OCaml values, chapter
"interacting with C" in the manual.

On Fri, Oct 26, 2012 at 8:01 PM, "Mark" <mark@proof-technologies.com> wrote:
> Hello.
>
> Is it possible in OCaml for a polymorphic function to somehow have
> access to the concrete type of an actual parameter used in a call of
> the function?
>
> For example, is there some way of writing a polymorphic function 'foo'
> list this:
>
>      let foo x =
>         match (type_of x) with
>           Int    -> ....
>         | String -> ....
>
> where 'type_of' is some function that returns a representation of the
> concrete type of its argument.
>
> I want this because I want to implement an ad-hoc polymorphic
> function.  I know this is outside the bounds of "normal" OCaml, but is
> there some nasty part of the language like Obj.magic that I could use
> to achieve this?
>
> Mark.
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] accessing the type of a polymorphic parameter
  2012-10-26 18:01 [Caml-list] accessing the type of a polymorphic parameter "Mark"
  2012-10-26 19:23 ` Gabriel Scherer
@ 2012-10-26 21:31 ` Anil Madhavapeddy
  1 sibling, 0 replies; 6+ messages in thread
From: Anil Madhavapeddy @ 2012-10-26 21:31 UTC (permalink / raw)
  To: Mark; +Cc: caml-list

You could use the Dyntype extension for this, if you don't mind a spot
of Camlp4 being involved: https://github.com/mirage/dyntype

Toplevel:

$ #require "dyntype.syntax" ;;
$ type t = { foo: int; bar: string }  with type_of;;
type t = { foo : int; bar : string; }
val type_of_t : Dyntype.Type.t = Dyntype.Type.Ext ("t", 
   Dyntype.Type.Dict (`R, [("foo", `RO, Dyntype.Type.Int (Some 63)); 
   ("bar", `RO, Dyntype.Type.String)]))

...and you can collect and inspect the dynamic types in other code.

This won't work with polymorphic types, but you can probably rephrase
your problem to it work with this approach.

Note that this suffers from the usual drawbacks of camlp4-based
interpretation of type declarations, but it works fairly well "in the
wild" and with an existing, unmodified OCaml toolchain.

-anil

On 26 Oct 2012, at 11:01, "Mark" <mark@proof-technologies.com> wrote:

> Hello.
> 
> Is it possible in OCaml for a polymorphic function to somehow have
> access to the concrete type of an actual parameter used in a call of
> the function?
> 
> For example, is there some way of writing a polymorphic function 'foo'
> list this:
> 
>     let foo x =
>        match (type_of x) with
>          Int    -> ....
>        | String -> ....
> 
> where 'type_of' is some function that returns a representation of the
> concrete type of its argument.
> 
> I want this because I want to implement an ad-hoc polymorphic
> function.  I know this is outside the bounds of "normal" OCaml, but is
> there some nasty part of the language like Obj.magic that I could use
> to achieve this?
> 
> Mark.
> 
> -- 
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] accessing the type of a polymorphic parameter
  2012-10-26 19:58 ` Gabriel Scherer
@ 2012-10-26 20:01   ` Gabriel Scherer
  0 siblings, 0 replies; 6+ messages in thread
From: Gabriel Scherer @ 2012-10-26 20:01 UTC (permalink / raw)
  To: "Mark"; +Cc: caml-list

Also relevant is this old blog bost by Matías Giovannini about manual
encoding of Haskell type classes (essentially the ('a ops) idea):
  http://alaska-kamtchatka.blogspot.fr/2009/08/fun-with-type-class.html

On Fri, Oct 26, 2012 at 9:58 PM, Gabriel Scherer
<gabriel.scherer@gmail.com> wrote:
> If you can formulate your problems with ('a ops), the module defining
> an abstract type t can provide a (t ops) from inside the abstraction
> boundary. Handling composite data types is also rather easy, just
> provide for example an ('a ops -> 'a list ops) function.
>
> The runtime type representation idea of Alain can also be extended to
> deal with private types, but you need either to pre-plan the required
> operation in advance and provide them from inside the abstraction
> boundary, or expose the runtime type representation of the abstract
> type which lessen encapsulation (but you can hardly do worse than
> using Obj.magic in this case). This is present in "ocaml-ty", a
> prototype work on runtime type representation by Pierre Chambart and
> Grégoire Henry which has been presented during the last OCaml Users
> and Developers Meeting back in September. It's experimental work and a
> moving target, and comes with a "modification of the language" part
> that isn't really the concern here, but you could think of looking at
> their work (and providing them feedback!) if you really insist on
> making heavy use of ad-hoc polymorphism.
>   https://gitorious.org/ocaml-ty
>
>
>
> On Fri, Oct 26, 2012 at 9:39 PM, "Mark" <mark@proof-technologies.com> wrote:
>> Superb, thanks David, Lilian, Gabriel.  This may be just about sufficient
>> for my purposes.  I'll have a play.
>>
>> As well as predefined OCaml primitive datatypes, what would perfect for me
>> would be the ability to also do newly created abstract datatypes, and
>> composite datatypes like lists of strings.  Are either of these possible
>> with your solutions?
>>
>> Mark.
>>
>> on 26/10/12 7:29 PM, David Allsopp <dra-news@metastack.com> wrote:
>>
>>> ...
>>> For this explicit example, you could write:
>>>
>>> let foo x =
>>> match Obj.tag (Obj.repr x) with
>>> x when x = Obj.int_tag -> ...
>>> | x when x = Obj.string_tag -> ...
>>>
>>> but this probably isn't what you're after. The type of foo will also be 'a
>>> -> '_b so you won't get any help from the type system in the calling of
>> foo.
>>> ...
>>
>>
>> on 26/10/12 7:50 PM, Lilian Jean BESSON <lilian.besson@ens-cachan.fr> wrote:
>>
>>> ...
>>> In my code "surcharge.ml", the main functions are "typage" : 'a ->
>>> string, and "dump" : a' -> string.
>>> Examples:
>>> #9> Surcharge.typage;;
>>> - : 'a -> string = <fun>
>>> #10> Surcharge.typage 4  (* ok *);;
>>> - : string = "int"
>>> #11> Surcharge.typage 8.7  (* ok *);;
>>> - : string = "float"
>>> #12> Surcharge.typage "ok";; (* ok *)
>>> - : string = "string"
>>> #13> Surcharge.typage 'k'  (* not ok *);;
>>> - : string = "int"
>>> #14> Surcharge.typage [4]  (* not ok *);;
>>> - : string = "array"
>>> #15> Surcharge.typage [|4|];;
>>> - : string = "array"
>>> #16> Surcharge.typage cos  (* not ok *);;
>>> - : string = "unknown"
>>> But this function "typage" is very limited : no difference between arrays
>>> and strings etc...
>>> ...
>>
>>
>> on 26/10/12 8:24 PM, Gabriel Scherer <gabriel.scherer@gmail.com> wrote:
>>
>>> ...
>>> Long answer: I presume that your implementation works for any type
>>> providing some fixed set of operations, but that you wish those
>>> operations to be implemented differently for each type. You can define
>>> a type ('a ops) describing these operations on the type 'a (as a
>>> record of functions for example), and use the polymorphic type ('a ->
>>> 'a ops -> foo) instead of ('a -> foo) to write your function.
>>> Depending on your specific needs there may be slightly different
>>> approaches (using a algebraic representation of runtime types rather
>>> than a typeclass-like dictionary), a very general way being described
>>> in this blog post by Alain Frisch :
>>> http://www.lexifi.com/blog/dynamic-types
>>> It could help to have more details on your needs to suggest a better
>>> solution.
>>>
>>> Wrong answer: yes, using Obj.magic you can access the runtime
>>> representation of values. You can't distinguish between boolean and
>>> integers and the empty list, but worrying about that is for the
>>> coward, let's shoot yourself in the foot -- starting by reading the
>>> documentation on the representation of OCaml values, chapter
>>> "interacting with C" in the manual.
>>> ...

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] accessing the type of a polymorphic parameter
  2012-10-26 19:39 "Mark"
@ 2012-10-26 19:58 ` Gabriel Scherer
  2012-10-26 20:01   ` Gabriel Scherer
  0 siblings, 1 reply; 6+ messages in thread
From: Gabriel Scherer @ 2012-10-26 19:58 UTC (permalink / raw)
  To: "Mark"; +Cc: caml-list

If you can formulate your problems with ('a ops), the module defining
an abstract type t can provide a (t ops) from inside the abstraction
boundary. Handling composite data types is also rather easy, just
provide for example an ('a ops -> 'a list ops) function.

The runtime type representation idea of Alain can also be extended to
deal with private types, but you need either to pre-plan the required
operation in advance and provide them from inside the abstraction
boundary, or expose the runtime type representation of the abstract
type which lessen encapsulation (but you can hardly do worse than
using Obj.magic in this case). This is present in "ocaml-ty", a
prototype work on runtime type representation by Pierre Chambart and
Grégoire Henry which has been presented during the last OCaml Users
and Developers Meeting back in September. It's experimental work and a
moving target, and comes with a "modification of the language" part
that isn't really the concern here, but you could think of looking at
their work (and providing them feedback!) if you really insist on
making heavy use of ad-hoc polymorphism.
  https://gitorious.org/ocaml-ty



On Fri, Oct 26, 2012 at 9:39 PM, "Mark" <mark@proof-technologies.com> wrote:
> Superb, thanks David, Lilian, Gabriel.  This may be just about sufficient
> for my purposes.  I'll have a play.
>
> As well as predefined OCaml primitive datatypes, what would perfect for me
> would be the ability to also do newly created abstract datatypes, and
> composite datatypes like lists of strings.  Are either of these possible
> with your solutions?
>
> Mark.
>
> on 26/10/12 7:29 PM, David Allsopp <dra-news@metastack.com> wrote:
>
>> ...
>> For this explicit example, you could write:
>>
>> let foo x =
>> match Obj.tag (Obj.repr x) with
>> x when x = Obj.int_tag -> ...
>> | x when x = Obj.string_tag -> ...
>>
>> but this probably isn't what you're after. The type of foo will also be 'a
>> -> '_b so you won't get any help from the type system in the calling of
> foo.
>> ...
>
>
> on 26/10/12 7:50 PM, Lilian Jean BESSON <lilian.besson@ens-cachan.fr> wrote:
>
>> ...
>> In my code "surcharge.ml", the main functions are "typage" : 'a ->
>> string, and "dump" : a' -> string.
>> Examples:
>> #9> Surcharge.typage;;
>> - : 'a -> string = <fun>
>> #10> Surcharge.typage 4  (* ok *);;
>> - : string = "int"
>> #11> Surcharge.typage 8.7  (* ok *);;
>> - : string = "float"
>> #12> Surcharge.typage "ok";; (* ok *)
>> - : string = "string"
>> #13> Surcharge.typage 'k'  (* not ok *);;
>> - : string = "int"
>> #14> Surcharge.typage [4]  (* not ok *);;
>> - : string = "array"
>> #15> Surcharge.typage [|4|];;
>> - : string = "array"
>> #16> Surcharge.typage cos  (* not ok *);;
>> - : string = "unknown"
>> But this function "typage" is very limited : no difference between arrays
>> and strings etc...
>> ...
>
>
> on 26/10/12 8:24 PM, Gabriel Scherer <gabriel.scherer@gmail.com> wrote:
>
>> ...
>> Long answer: I presume that your implementation works for any type
>> providing some fixed set of operations, but that you wish those
>> operations to be implemented differently for each type. You can define
>> a type ('a ops) describing these operations on the type 'a (as a
>> record of functions for example), and use the polymorphic type ('a ->
>> 'a ops -> foo) instead of ('a -> foo) to write your function.
>> Depending on your specific needs there may be slightly different
>> approaches (using a algebraic representation of runtime types rather
>> than a typeclass-like dictionary), a very general way being described
>> in this blog post by Alain Frisch :
>> http://www.lexifi.com/blog/dynamic-types
>> It could help to have more details on your needs to suggest a better
>> solution.
>>
>> Wrong answer: yes, using Obj.magic you can access the runtime
>> representation of values. You can't distinguish between boolean and
>> integers and the empty list, but worrying about that is for the
>> coward, let's shoot yourself in the foot -- starting by reading the
>> documentation on the representation of OCaml values, chapter
>> "interacting with C" in the manual.
>> ...

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] accessing the type of a polymorphic parameter
@ 2012-10-26 19:39 "Mark"
  2012-10-26 19:58 ` Gabriel Scherer
  0 siblings, 1 reply; 6+ messages in thread
From: "Mark" @ 2012-10-26 19:39 UTC (permalink / raw)
  To: gabriel.scherer; +Cc: caml-list

Superb, thanks David, Lilian, Gabriel.  This may be just about sufficient
for my purposes.  I'll have a play.

As well as predefined OCaml primitive datatypes, what would perfect for me
would be the ability to also do newly created abstract datatypes, and
composite datatypes like lists of strings.  Are either of these possible
with your solutions?

Mark.

on 26/10/12 7:29 PM, David Allsopp <dra-news@metastack.com> wrote:

> ...
> For this explicit example, you could write:
>
> let foo x =
> match Obj.tag (Obj.repr x) with
> x when x = Obj.int_tag -> ...
> | x when x = Obj.string_tag -> ...
>
> but this probably isn't what you're after. The type of foo will also be 'a
> -> '_b so you won't get any help from the type system in the calling of
foo.
> ...


on 26/10/12 7:50 PM, Lilian Jean BESSON <lilian.besson@ens-cachan.fr> wrote:

> ...
> In my code "surcharge.ml", the main functions are "typage" : 'a ->
> string, and "dump" : a' -> string.
> Examples:
> #9> Surcharge.typage;;
> - : 'a -> string = <fun>
> #10> Surcharge.typage 4  (* ok *);;
> - : string = "int"
> #11> Surcharge.typage 8.7  (* ok *);;
> - : string = "float"
> #12> Surcharge.typage "ok";; (* ok *)
> - : string = "string"
> #13> Surcharge.typage 'k'  (* not ok *);;
> - : string = "int"
> #14> Surcharge.typage [4]  (* not ok *);;
> - : string = "array"
> #15> Surcharge.typage [|4|];;
> - : string = "array"
> #16> Surcharge.typage cos  (* not ok *);;
> - : string = "unknown"
> But this function "typage" is very limited : no difference between arrays
> and strings etc...
> ...


on 26/10/12 8:24 PM, Gabriel Scherer <gabriel.scherer@gmail.com> wrote:

> ...
> Long answer: I presume that your implementation works for any type
> providing some fixed set of operations, but that you wish those
> operations to be implemented differently for each type. You can define
> a type ('a ops) describing these operations on the type 'a (as a
> record of functions for example), and use the polymorphic type ('a ->
> 'a ops -> foo) instead of ('a -> foo) to write your function.
> Depending on your specific needs there may be slightly different
> approaches (using a algebraic representation of runtime types rather
> than a typeclass-like dictionary), a very general way being described
> in this blog post by Alain Frisch :
> http://www.lexifi.com/blog/dynamic-types
> It could help to have more details on your needs to suggest a better
> solution.
>
> Wrong answer: yes, using Obj.magic you can access the runtime
> representation of values. You can't distinguish between boolean and
> integers and the empty list, but worrying about that is for the
> coward, let's shoot yourself in the foot -- starting by reading the
> documentation on the representation of OCaml values, chapter
> "interacting with C" in the manual.
> ...

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-10-26 21:31 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-26 18:01 [Caml-list] accessing the type of a polymorphic parameter "Mark"
2012-10-26 19:23 ` Gabriel Scherer
2012-10-26 21:31 ` Anil Madhavapeddy
2012-10-26 19:39 "Mark"
2012-10-26 19:58 ` Gabriel Scherer
2012-10-26 20:01   ` Gabriel Scherer

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).