(如果您被允许使用库函数,) SML/NJ 中的ListMergeSort.sort 看起来像:
val sort : ('a * 'a -> bool) -> 'a list -> 'a list
sort f l 返回 l 中的元素列表,按“大于”谓词指定的非降序排序 f。具体来说,如果 f(x,y) 的计算结果为真,那么 x 将出现在结果列表中的 y 之后。
使用这个库函数来写你的foo:
fun foo pairs = ListMergeSort.sort (fn ((s : string,_), (t,_)) => s > t)
如果您使用 SML/NJ 以外的其他编译器,这可能看起来有点不同。
为了解决您的子问题,
我不知道如何实现sort函数
(因为您不允许使用任何库函数,)您可以构建一个以String.compare 作为参数的排序函数。根据排序算法,排序函数的粗略草图可能如下所示:
fun sort cmp [] = []
| sort cmp [x] = [x]
| sort cmp xs = ... partially sort xs using `cmp`, combine results ...
它的签名是('a * 'a -> order) -> 'a list -> 'a list。
您不是在问如何制作排序功能(只是说您不知道如何),如果您是,我倾向于说这个问题太宽泛了,而您不知道指定您希望实现的算法类型,或者您在此过程中遇到的问题。例如见Rosetta Code's MergeSort,或问答Standard sorting functions in SML?
我希望它具有我编写的以下代码:
case String.compare (x,s) of ...
[...] 我不允许任何其他库 [...]
但是String.compare 也是一个库函数!您可以编写自己的String.compare。 (a) explode 将字符串分解为字符列表并使用列表递归来确定它们的字典顺序,或者 (b) count 字符串的长度并使用String.sub (s, i) 获取每个字符串的s 的ith 字符,直到确定字典顺序。虽然 (b) 更有效(因为它使用少量且恒定的内存),但 (a) 是列表递归的一个很好的练习。
对于(a),您可以从以下开始:
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
然后你可以用同样的方式组合它们:
fun foo pairs = sort (fn ((s,_), (t,_)) => stringCompare (s, t)) pairs