Refnum

Henry Cejtin henry@sourcelight.com
Thu, 20 Sep 2001 13:43:04 -0500


Sure,  once  you  are  willing to re-define ref's it is all easy.  I actually
don't see why your ref was so complicated.  Why not just do

    structure Refnum:
       sig
          structure Ref:
             sig
                type 'a t

                val reff: 'a -> 'a t
                val ! : 'a t -> 'a
                val := : 'a t * 'a -> unit
             end

          val refnum: 'a Ref.t -> int
       end =
       struct
          structure Ref =
             struct
                type 'a t = (int option * 'a) ref

                fun reff z = ref (NONE, z)

                fun ! (ref (_, ans)) = ans

                local
                   fun store (lhs as ref (name, _), rhs) = lhs := (name, rhs)
                in val op := = store
                end
             end

          val count = ref 0

          fun refnum lhs =
                 case lhs of
                   ref (SOME ans, _) => ans
                 | ref (_, z) =>
                      let val c = 1 + ! count
                      in count := c;
                         lhs := (SOME c, z);
                         c
                      end
       end

(Although I would make the signature constraint on Ref opaque.)

The  point  is  that  if you are willing to make a new type (instead of refs)
then you can clearly have a polymorphic function that only uses the int  part
of  what  is  stored  there.   You  could  probably  make the above more time
efficient (although less space efficient) by changing
    (int option * 'a) ref
to
    int option ref * 'a ref