(If you were allowed to use library functions,) ListMergeSort.sort
in SML/NJ looks like:
val sort : ('a * 'a -> bool) -> 'a list -> 'a list
sort f l
returns a list of the elements in l
, sorted in non-decreasing order as specified by the ``greater than'' predicate f
. Specifically, if f(x,y)
evaluates to true, then x
will appear after y
in the resulting list.
Using this library function to write your foo
:
fun foo pairs = ListMergeSort.sort (fn ((s : string,_), (t,_)) => s > t)
This might look a little different if you use another compiler than SML/NJ.
To address your sub-problems,
I don't know how to implement the sort
function
(Since you're not allowed any library functions,) you could build a sorting function that takes String.compare
as argument. Depending on the sorting algorithm, a rough sketch of the sorting function could look like:
fun sort cmp [] = []
| sort cmp [x] = [x]
| sort cmp xs = ... partially sort xs using `cmp`, combine results ...
and its signature would be ('a * 'a -> order) -> 'a list -> 'a list
.
You're not asking how to make a sorting function (but merely saying that you don't know how to), and if you were, I would be inclined to say that this question is too broad when you don't specify what kind of algorithm you wish to implement, or where you got stuck in the process. See for example Rosetta Code's MergeSort, or the Q&A Standard sorting functions in SML?
I would like it to have the following code I wrote:
case String.compare (x,s) of ...
[...] I'm not allowed any additional libraries [...]
But String.compare
is a library function, too! You could write your own String.compare
. Either (a) explode the strings into char lists and use list recursion to determine their lexicographical order, or (b) count the length of the strings and use String.sub (s, i)
to get the i
th char of s
for each string until the lexicographical order is determined. While (b) is more efficient (since it uses a small, constant amount of memory), (a) is a fine exercise in list recursion.
For (a) you could start with:
fun stringCompare (s, t) =
let fun cmp (x::xs, y::ys) = if x < y then ... else ...
| cmp (_::_, []) = ...
| cmp ([], _::_) = ...
| cmp ([], []) = EQUAL
in cmp (explode s, explode t) end
You can then compose them in the same way:
fun foo pairs = sort (fn ((s,_), (t,_)) => stringCompare (s, t)) pairs