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