I forgot to note, that the interesting thing was how the type inferred for Modifier.attach when it had
one argument applied did not show the < _.. > monomorphic object constraint. Modifier.attach
is actually a: fun id -> (key -> fn -> deleter), rather than a straightforward three-argument function. Once
the (key -> fn -> deleter) function would come into play, the "object" was revealed.


On Sat, Apr 13, 2013 at 10:07 AM, Anthony Tavener <anthony.tavener@gmail.com> wrote:
Ohhh... that is interesting. (TL;DR: problem solved, and it was from inappropriate Oo.id use.)

Modifier.attach is actually implemented as a function of one argument which does some stuff,
returning a function of two arguments, to avoid redundant lookups in the case of multiple "attach"
to the same "id".

When I remove the let m = ... and just inline "Modifer.attach id ..." the type of Modifier.attach changes to:

  Db.key -> int * (((< _.. > as 'a) list -> exn) * (exn -> 'a list) -> 'a -> Modifier.deleter

So, 'a becomes: (< _.. > as 'a) -- I get some monomorphic... object?

As I wrote this I had an idea and found the problem:

  ...
  (* return (tbl -> unit) function which deletes this specific function *)
  let del_id = Oo.id fn in
  (fun tbl ->
    let lst = List.filter (fun e -> Oo.id e <> del_id) (fn_list tbl) in
    Hashtbl.replace tbl tag (inj lst))


Here, "fn" is the provided function, and I want an easy way to remove such functions uniquely from the
mess of Hashtbl, universal embedding, and list. I tried a trick I once read Alain suggest for getting a
unique id using the object module... and I guess that brought in this <..> thing I was unfamiliar with. :)
Instead of Oo.id I'm using Hashtbl.hash now, which is normally what I'd do... not sure why I
half-remembered some trick with Oo.id.

Thank-you for looking at this, both of you. It helped me dig in the right direction!


On Sat, Apr 13, 2013 at 1:33 AM, Gabriel Scherer <gabriel.scherer@gmail.com> wrote:
This looks like a value restriction issue with

  let m = Modifier.attach id

  "A function obtained through partial application is not polymorphic enough"
  http://caml.inria.fr/resources/doc/faq/core.en.html#eta-expansion

If this is indeed the source of your error, you can regain
type-checking by using instead

  let m total = Modifier.attach id total

Note that this may change the semantics of your code if
(Modifier.attach id) does a side-effect before getting its next
parameter: if would have been effected only once with your previous
definition, and will be effected at each call of 'm' with the new
definition.

On Sat, Apr 13, 2013 at 8:56 AM, Kakadu <kakadu.hafanana@gmail.com> wrote:
> Maybe function type (int * int -> int * int) is incompatible with object
> type <..>?
>
> Kakadu
>
>
> On Sat, Apr 13, 2013 at 10:50 AM, Anthony Tavener
> <anthony.tavener@gmail.com> wrote:
>>
>> File "virtue.ml", line 462, characters 12-24:
>> Error: This expression has type
>>          int * ((int * int -> int * int) list -> exn) *
>>          (exn -> (int * int -> int * int) list)
>>        but an expression was expected of type
>>          int * ((< .. > as 'a) list -> exn) * (exn -> 'a list)
>>
>> The code in question:
>>
>>   (fun id ->
>>     let m = Modifier.attach id in
>>       [ m Cast.total'k (fun (v,b) -> (v, max 1 (b-3)))     (* <-- line 462
>> *)
>>       ; m Lab.total'k (fun (v,b) -> (v, max 1 (b-3))) ])
>>
>> For reference, the signature of Modifier.attach:
>>   Db.key -> int * ('a list -> exn) * (exn -> 'a list) -> 'a ->
>> Modifier.deleter
>>
>> OCaml version is 4.00.0 -- I know I should upgrade. Keep meaning to, I
>> guess I will if I wake up and there's no helpful soul explaining what
>> could
>> be wrong here. :)
>>
>> Thank-you for any help. My eyes are starting to bug-out looking at this.
>>
>>  -Tony
>>
>>
>