caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] recursive module, object types, tying knot
@ 2011-09-07 21:29 Dmitry Grebeniuk
  2011-09-07 21:44 ` Jacques Garrigue
  0 siblings, 1 reply; 6+ messages in thread
From: Dmitry Grebeniuk @ 2011-09-07 21:29 UTC (permalink / raw)
  To: caml-list

Hello.

  I have an usual question.  I want to make some object
types (container-like) that can map the stored contents
with its method.  For example, let the container will be
the simple list:
class ['a] (lst : list 'a) = object ...
  method map : ('a -> 'b) -> 'b lst

  The compiler yields an error:
# class ['a] lst x = object
   method map : 'b . ('a -> 'b) -> 'b lst
   = fun f -> List.map f x end;;
Error: This type scheme cannot quantify 'b :
it escapes this scope.

  I know the solution with separate function for map,
but I don't like it: the whole mess with objects is
to use less information to make api call: compare
"MapIntToString.get my_map 123" with
"my_map#get 123".  Having to remember where
(in which module) the correct map function resides
will ruin the purpose of the code I'm writing now.

  (maybe "implicit values" could help here, but they are
not the part of official compiler for now.)

  I need to write the code that performs that map, maybe
with help of some additional types and values.  And I
began experimenting.


  Now I have two pieces of code (for even simpler
container, that contains just one value), the second one
is derived from the first one by replacing the type "ta"
from the record to the object type.  The first piece
of code works, but the second does not.  Why there is
such a difference, and, more importantly, how should
I tweak the second piece of code to make it work?
(if you remember, referencing the record's fields will
require the path to the module where the record
is declared (see the "q#tbm.L.tam" subexpression),
so the first "solution" is not a solution for my current
problem.)

$ ocaml
        Objective Caml version 3.12.1+rc1

# module rec L
 :
  sig
    type 'a ta = { tam : 'b. ('a -> 'b) -> 'b L.tb }
    class ['a] tb : 'a -> object method tbm : 'a L.ta end
    val make_ta : 'a -> 'a L.ta
  end
 =
  struct
    type 'a ta = { tam : 'b. ('a -> 'b) -> 'b L.tb }
    let make_ta : 'a -> 'a L.ta = fun a -> { tam = fun f -> new L.tb (f a)}
    class ['a] tb x = object method tbm : 'a L.ta = L.make_ta x end
  end;;
module rec L :
  sig
    type 'a ta = { tam : 'b. ('a -> 'b) -> 'b L.tb; }
    class ['a] tb : 'a -> object method tbm : 'a L.ta end
    val make_ta : 'a -> 'a L.ta
  end

# let q = new L.tb 123;;
val q : int L.tb = <obj>

# let w = q#tbm.L.tam string_of_int;;
val w : string L.tb = <obj>

#

  (it really works -- the map is applied, the
object is created.  I've checked it with more
extended types that allowed me to examine
the contents of such a great container.)

$ ocaml
        Objective Caml version 3.12.1+rc1

# module rec L
   :
    sig
      type 'a ta = < tam : 'b. ('a -> 'b) -> 'b L.tb >
      class ['a] tb : 'a -> object method tbm : 'a L.ta end
      val make_ta : 'a -> 'a L.ta
    end
   =
    struct
      type 'a ta = < tam : 'b. ('a -> 'b) -> 'b L.tb >
      let make_ta : 'a -> 'a L.ta = fun a ->
        object method tam : 'b. ('a -> 'b) -> 'b L.tb =
          fun f -> new L.tb (f a)
        end
      class ['a] tb x = object method tbm : 'a L.ta = L.make_ta x end
    end;;
Error: In the definition of L.tb, type 'a L.ta should be 'b L.ta
#

  Maybe there is a problem with type "ta" in the second piece,
because record is "concrete" type, but the object type is just
a list of their methods.  But I can't check it successfully: trying
to wrap occurences of "tb" with "type 'a id = Id of 'a" (and removing
"ta" at all) does not help, just yields different types in error
"In the definition of .., type .. should be ..".

  Please help me.  Any ideas are highly appreciated.

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

end of thread, other threads:[~2011-09-13  7:23 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-07 21:29 [Caml-list] recursive module, object types, tying knot Dmitry Grebeniuk
2011-09-07 21:44 ` Jacques Garrigue
2011-09-09 11:14   ` Dmitry Grebeniuk
2011-09-09 13:50     ` Jacques Garrigue
2011-09-13  4:56       ` Dmitry Grebeniuk
2011-09-13  7:22         ` 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).