Reputation: 113
I have a problem with the following code:
fun unsorted cmp ((x, y)::[]) = false
| unsorted cmp ((x, y)::xx::xs) =
if cmp(y, xx) = GREATER then true else unsorted cmp (xx::xs)
I just want that this function returns true
if the list is unsorted and false
otherwise. This should work for a list of pairs compared by the second component.
Here is my correct code for a plain list:
fun unsorted' cmp [] = false
| unsorted' cmp (x::[]) = false
| unsorted' cmp (x::xx::xs) =
if cmp(x, xx) = GREATER then true else unsorted' cmp (xx::xs)
but where is my mistake with the list of pairs?
Upvotes: 0
Views: 244
Reputation: 8485
The problem is in your call to cmp
. Here's the inferred type for your working version of unsorted
: ('a * 'a -> order) -> 'a list -> bool
It takes a comparison function (with type 'a * 'a -> order
) and a list containing elements whose type is 'a
. You then pattern match the list using the following pattern: (x::xx::xs)
so both x
and xx
are bound to values of type 'a
, and xs
is bound to a list of 'a
. Then you call cmp
with a 2-tuple, which has the type 'a * 'a
: cmp(x,xx)
.
In your other version, you want to work on a list of pairs (ie a value of type 'a * 'a list
) and so you're using a different pattern: ((x,y)::xx::xs)
. In this case, x
and y
are both bound to values of type 'a
but xx
is bound to a pair, with type 'a * 'a
. So in your call to cmp
, this is the type of the parameter: 'a * ('a * 'a)
. Remember that in ML all functions take a single argument, and multiple arguments are achieved by passing tuples or currying, both of which you are using in this example. (cmp
takes a tuple, and unsorted
is curried)
Try using the following patterns in your new version:
fun unsorted cmp ((x,y)::[]) = ...
| unsorted cmp ((x,y)::(xx,yy)::xs) = ...
... and see how far you get as you try to complete the function.
Upvotes: 1