Sml 按字典顺序排列元组列表

Sml 按字典顺序排列元组列表,sml,ml,Sml,Ml,我试图在标准ML中创建一个函数,它获取一个string*int列表,并返回一个字典排序列表 例如,foo[(“y”,5),(“x”,10)]将返回[(“x,10),(“y”,5)](只有每个元组的第一个元素是重要的) 我写了以下几行: fun foo ([]:(string * int)) = [] | foo [x] = [x] | foo ((x,y)::xs) = let val (s,t) = hd(xs) (* gets next element stri

我试图在标准ML中创建一个函数,它获取一个
string*int
列表,并返回一个字典排序列表

例如,foo
[(“y”,5),(“x”,10)]
将返回
[(“x,10),(“y”,5)]
(只有每个元组的第一个元素是重要的)

我写了以下几行:

fun foo ([]:(string * int)) = []
  | foo [x] = [x]
  | foo ((x,y)::xs) = 
    let
      val (s,t) = hd(xs) (* gets next element string *)
      fun sort ... = ...
    in

    end
我不知道如何实现
排序
功能,但我希望它具有我编写的以下代码:

    case String.compare(x,s) of
      LESS => ...
    | EQUAL => ...
    | GREATER => ...
case String.compare (x,s) of ...
另外,我需要在
排序
函数中使用
val(s,t)=hd(xs)
,这样它将是递归的,但我不确定。此外,我不允许使用任何其他库-仅使用隐藏的let/local。

SML/NJ中的(如果允许使用库函数,)看起来像:

sort f l
返回
l
中元素的列表,按照``大于``谓词
f
指定的非降序排序。具体来说,如果
f(x,y)
的计算结果为true,则
x
将出现在结果列表中的
y
之后

使用此库函数编写
foo

fun foo pairs = ListMergeSort.sort (fn ((s : string,_), (t,_)) => s > t)
如果使用SML/NJ以外的其他编译器,这可能会有点不同


为了解决您的子问题

我不知道如何实现排序功能

(因为不允许使用任何库函数,)您可以构建一个以
字符串为参数的排序函数。比较
作为参数。根据排序算法,排序函数的草图可能如下所示:

fun sort cmp [] = []
  | sort cmp [x] = [x]
  | sort cmp xs = ... partially sort xs using `cmp`, combine results ...
它的签名是
('a*'a->order)->'a list->'a list

你不是在问如何做一个排序函数(只是说你不知道怎么做),如果是的话,我倾向于说这个问题太宽泛了,因为你没有说明你想实现什么样的算法,或者你在这个过程中遇到了什么问题。例如,见Q&a

我希望它具有我编写的以下代码:

    case String.compare(x,s) of
      LESS => ...
    | EQUAL => ...
    | GREATER => ...
case String.compare (x,s) of ...
[…]我不允许有任何额外的库[…]

但是
String.compare
也是一个库函数!您可以编写自己的
String.compare
。或者(a)将字符串分解为字符列表并使用列表递归来确定它们的字典顺序,或者(b)计算字符串的长度并使用
String.sub(s,i)
获取每个字符串的
i
th字符
s
,直到确定了字典顺序。虽然(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

您不必使用
hd(xs)
。您可以使用模式匹配。