[MLton-user] bug report: vector equality

Sam Lindley Sam.Lindley@ed.ac.uk
Fri, 27 Feb 2004 17:34:05 +0000


Stephen Weeks wrote:
> Hi Sam.  Thanks for the bug report.
> 
> 
>>The latest experimental release of mlton (20040221), and the previous one
>>from the beginning of January both fall over on the following code:
>>
>>  val _ =
>>    if (Int32Vector.fromList [1])=(Int32Vector.fromList [2]) then
>>      TextIO.print "oops"
>>    else
>>      TextIO.print "not equal"
>>
>>$ mlton test.sml
>>Error: test.sml 2.32: function applied to incorrect argument
>>   expects: [<equality>] * [<equality>]
>>   but got: [<non-equality>] * [<non-equality>]
>>   in: = (Int32Vector.fromList [1], Int32Vector.fromList [2])
>>compilation aborted: elaborate reported errors
>>
>>It compiles correctly under the release version.
> 
> Under my reading of the basis library specification, the behavior of
> MLton 20040221 is correct.  There is a difference between the types
> "Int32.int vector" and "Int32Vector.vector".  The former is an
> equality type, because the vector type admits equality, as can be seen
> in the VECTOR signature, which says "eqtype 'a vector".  The latter is
> not an equality type, as can be seen in the MONO_VECTOR signature,
> which says "type vector", not "eqtype vector".

I hadn't realised that the spec calls for an opaque signature constraint:

   structure Int<N>Vector :> MONO_VECTOR

In other implementations such as NJ and the release version of mlton 
this constraint is transparent, which means the eqtype is visible.

Actually, having another look at the latest code on the web, I can't see 
any opaque constraints on Int32Vector...

[..]

> You can compare mono vectors directly as follows.
> 
> ----------------------------------------------------------------------
> functor Equals (structure V: MONO_VECTOR
> 		val elemEquals: V.elem * V.elem -> bool):
>    sig
>       include MONO_VECTOR
> 	 
>       val equals: vector * vector -> bool
>    end =
>    struct
>       open V
> 	 
>       fun equals (v: vector, v': vector): bool =
> 	 length v = length v'
> 	 andalso not (isSome
> 		      (findi (fn (i, x) => not (elemEquals (x, sub (v', i)))) v))
>    end
> ----------------------------------------------------------------------

Seems reasonable.

Sam