3

我是 SML 的新手,我正在尝试获取列表中某个项目的索引。我知道使用 List.nth 会给我一个项目在索引位置的值,但我想要索引值。甚至可能有一个我不知道的内置函数。在我的情况下,列表将不包含重复项,因此如果该项目在列表中,我将获得索引,否则返回 ~1。这是我到目前为止的代码。它有效,但我认为它不是很干净:

val L=[1,2,3,4,5];
val m=length L-1;
fun Index(item, m, L)=if m<0 then ~1 else
    if List.nth(L, m)=item then m else Index(item,m-1,L);
4

3 回答 3

5

为了详细说明我之前的评论,我建议对更适合 ML 习语的实现进行一些更改:

fun index(item, xs) =
  let
    fun index'(m, nil) = NONE
      | index'(m, x::xr) = if x = item then SOME m else index'(m + 1, xr)
  in
    index'(0, xs)
  end

个别变化如下:

  • index返回类型的值int optionNONE表示该项目不在列表中,SOME i表示它在列表中,并且其第一次出现的索引是i。这样,不需要~1使用特殊值 (),并且可以从函数的类型推断出函数的预期用途。
  • m通过将函数重命名为并将其包装到使用适当参数调用它index'的外部函数来隐藏参数。index主要字符(`) 通常表示辅助值。
  • 使用列表上的模式匹配来获取各个元素,无需List.nth.

另请注意,最常见的函数和变量名称以小写字母开头(index而不是Index),而大写字母用于构造函数常量(SOME)等。

于 2013-07-25T07:32:11.743 回答
0

我想提出这个index函数的一个更简单、效率更低的版本。我同意使用异常而不是使用异常是不可取的int option,并且它不是尾递归的。但它肯定更容易阅读,因此可以作为学习材料:

fun index (x, []) = raise Subscript
  | index (x, y::ys) =
    if x = y then 0 else 1 + index (x, ys)
于 2013-08-04T00:17:10.847 回答
-1
fun index(list,n)=
= if n=0 then hd(list) else index(tl(list),n-1);
val index = fn : 'a list * int -> 'a

index([1,2,3,4,5],2);
val it = 3 : int

index([1,2,3,4,5],0);
val it = 1 : int
于 2019-11-04T04:43:20.833 回答