[MLton-commit] r5752

Vesa Karvonen vesak at mlton.org
Mon Jul 9 23:10:38 PDT 2007


Sane semantics for ORD/compare and a few minor implementation tweaks in Eq
and Ord.

----------------------------------------------------------------------

U   mltonlib/trunk/com/ssh/generic/unstable/detail/value/eq.sml
U   mltonlib/trunk/com/ssh/generic/unstable/detail/value/ord.sml
U   mltonlib/trunk/com/ssh/generic/unstable/public/value/eq.sig
U   mltonlib/trunk/com/ssh/generic/unstable/public/value/ord.sig

----------------------------------------------------------------------

Modified: mltonlib/trunk/com/ssh/generic/unstable/detail/value/eq.sml
===================================================================
--- mltonlib/trunk/com/ssh/generic/unstable/detail/value/eq.sml	2007-07-10 03:03:56 UTC (rev 5751)
+++ mltonlib/trunk/com/ssh/generic/unstable/detail/value/eq.sml	2007-07-10 06:10:36 UTC (rev 5752)
@@ -48,9 +48,8 @@
                          fn (l, r) =>
                             case e2to l & e2to r of
                                NONE   & NONE   => exn (l, r)
-                             | NONE   & SOME _ => false
-                             | SOME _ & NONE   => false
-                             | SOME l & SOME r => t (l, r)) exn
+                             | SOME l & SOME r => t (l, r)
+                             | _               => false) exn
       val exn = fn ? => !exn ?
 
       val list = ListPair.allEq
@@ -58,11 +57,14 @@
       fun seq length sub eq (l, r) = let
          val lL = length l
          val lR = length r
-         fun lp i = i = lL
-                    orelse eq (sub (l, i), sub (r, i))
-                           andalso lp (i+1)
+         fun lp i = let
+            val i = i-1
+         in
+            i < 0 orelse eq (sub (l, i), sub (r, i))
+                         andalso lp i
+         end
       in
-         lL = lR andalso lp 0
+         lL = lR andalso lp lL
       end
 
       fun vector ? = seq Vector.length Vector.sub ?

Modified: mltonlib/trunk/com/ssh/generic/unstable/detail/value/ord.sml
===================================================================
--- mltonlib/trunk/com/ssh/generic/unstable/detail/value/ord.sml	2007-07-10 03:03:56 UTC (rev 5751)
+++ mltonlib/trunk/com/ssh/generic/unstable/detail/value/ord.sml	2007-07-10 06:10:36 UTC (rev 5752)
@@ -7,23 +7,19 @@
 functor WithOrd (Arg : OPEN_GENERIC) : ORD_GENERIC = struct
    (* <-- SML/NJ workaround *)
    open TopLevel
-   infix  7 *`
-   infix  6 +`
-   infix  0 &
+   infix 0 &
    (* SML/NJ workaround --> *)
 
    structure Ord =
       LayerGenericRep (structure Outer = Arg.Rep
                        structure Closed = MkClosedGenericRep (Cmp))
 
-   open Ord.This
+   val compare = Ord.This.getT
 
-   val compare = getT
-
    structure Layered = LayerGeneric
      (structure Outer = Arg and Result = Ord and Rep = Ord.Closed
 
-      fun iso b (a2b, _) = b o Pair.map (Sq.mk a2b)
+      fun iso b (a2b, _) = Cmp.map a2b b
       val isoProduct = iso
       val isoSum     = iso
 
@@ -66,19 +62,21 @@
       val array  = Array.collate
       val vector = Vector.collate
 
-      fun refc t = iso t (!, ref)
+      fun refc t = Cmp.map ! t
 
       val bool   = Bool.compare
       val char   = Char.compare
       val int    = Int.compare
-      val real   = Real.compare
       val string = String.compare
       val word   = Word.compare
 
       val largeInt  = LargeInt.compare
-      val largeReal = LargeReal.compare
       val largeWord = LargeWord.compare
 
+      fun mk cast = Cmp.map cast
+      val largeReal = mk CastLargeReal.castToWord CastLargeReal.Word.compare
+      val real      = mk      CastReal.castToWord      CastReal.Word.compare
+
       val word8  = Word8.compare
       val word32 = Word32.compare
       val word64 = Word64.compare)

Modified: mltonlib/trunk/com/ssh/generic/unstable/public/value/eq.sig
===================================================================
--- mltonlib/trunk/com/ssh/generic/unstable/public/value/eq.sig	2007-07-10 03:03:56 UTC (rev 5751)
+++ mltonlib/trunk/com/ssh/generic/unstable/public/value/eq.sig	2007-07-10 06:10:36 UTC (rev 5752)
@@ -9,28 +9,35 @@
  *
  * For equality types the semantics is the same as SML's equality.  For
  * mutable types (refs and arrays) this means that two objects are
- * considered equal iff they have the same identity.  User defined
- * datatypes and exceptions are given a structural semantics of equality.
- * Specifically, two datatypes or exceptions are considered equal iff they
- * have the same constructor and the arguments of the constructors are
- * considered equal.  (Of course, all of this is modulo user specified
- * morphisms.)
+ * considered equal iff they have the same identity.  This means that the
+ * result of comparing two particular mutable objects is invariant.  If
+ * you truly need a structural equality relation for mutable types that
+ * ignores identity, see {ORD}.
  *
- * The equality of reals is bitwise equality.  While this matches the
- * notion of equality provided for other types, this differs from the
- * notions of equality provided for reals by the Basis Library.  In
- * particular, {~0.0} and {0.0} are considered unequal and {nan} is
- * considered equal to {nan}.  This treatment of equality is important for
- * a number of non-numerical applications such as serialization.
+ * The comparison of reals is done bitwise.  While this matches the notion
+ * of equality provided for other types, this differs from the notions of
+ * equality provided for reals by the Basis Library.  In particular,
+ * {~0.0} and {0.0} are considered unequal and {nan} is considered equal
+ * to {nan}.  This treatment is important for a number of non-numerical
+ * applications such as serialization.
+ *
+ * User defined datatypes and exceptions are given a structural semantics
+ * of equality.  Specifically, two datatype or exception values are
+ * considered equal iff they have the same constructor and the arguments
+ * of the constructors are considered equal.  Of course, all of this is
+ * modulo user specified morphisms!
+ *
+ * Comparison of exceptions only works when at least one of the exception
+ * constructors involved in a comparison has been registered with
+ * {regExn}.
+ *
+ * Comparison of functions is impossible and fails at run-time.
  *)
 signature EQ = sig
    structure Eq : OPEN_GENERIC_REP
 
    val eq : ('a, 'x) Eq.t -> 'a BinPr.t
-   (**
-    * Extracts the equality relation.  Note that the type variable {'a}
-    * isn't an equality type variable.
-    *)
+   (** Extracts the equality relation. *)
 
    val notEq : ('a, 'x) Eq.t -> 'a BinPr.t
    (** {notEq t = not o eq t} *)

Modified: mltonlib/trunk/com/ssh/generic/unstable/public/value/ord.sig
===================================================================
--- mltonlib/trunk/com/ssh/generic/unstable/public/value/ord.sig	2007-07-10 03:03:56 UTC (rev 5751)
+++ mltonlib/trunk/com/ssh/generic/unstable/public/value/ord.sig	2007-07-10 06:10:36 UTC (rev 5752)
@@ -5,23 +5,37 @@
  *)
 
 (**
- * Signature for a generic compare function.  The idea is that the compare
- * functions just implement some arbitrary logical ordering that you need
- * for things such as search trees.
+ * Signature for a generic linear ordering.
  *
- * Note that comparison of functions is impossible and fails at run-time.
- * Comparison of exceptions only works when both exception constructors
- * involved in a comparison have been registered with {regExn}.  Also,
- * comparison of arrays and references does not coincide with SML's notion
- * of equality.  More precisely, for an implementation of the {ORD}
- * signature, two arrays (or refs) {a} and {b} may compare {EQUAL}, but it
- * is not necessarily the case that {a=b} evaluates to {true}.
+ * The semantics is an unspecified, structural, linear ordering, suitable
+ * for use in applications such as search trees.  The ordering does not
+ * necessarily correspond to a "natural" ordering for any type.
+ *
+ * Mutable types (refs and arrays) are ordered structurally and the
+ * ordering does not coincide with SML's notion of equality.  More
+ * precisely, two mutable object {a} and {b} may compare {EQUAL}, but it
+ * is not necessarily the case that {a} and {b} have the same identity.
+ * This means that the ordering of mutable objects is not invariant with
+ * respect to mutation.
+ *
+ * The comparison of reals is done bitwise.  While this matches the notion
+ * of ordering for other types, this differs from the notions of ordering
+ * provided for reals by the Basis library.  In particular, {~0.0} and
+ * {0.0} are considered unequal and {nan} is considered equal to {nan}.
+ * This treatment is important for a number of non-numerical applications
+ * such as serialization.
+ *
+ * Comparison of exceptions only works when at least one of the exception
+ * constructors involved in a comparison has been registered with
+ * {regExn}.
+ *
+ * Comparison of functions is impossible and fails at run-time.
  *)
 signature ORD = sig
    structure Ord : OPEN_GENERIC_REP
 
    val compare : ('a, 'x) Ord.t -> 'a Cmp.t
-   (** Extracts the compare function. *)
+   (** Extracts the linear ordering. *)
 end
 
 signature ORD_GENERIC = sig




More information about the MLton-commit mailing list