List SML:获取列表中项目的索引

List SML:获取列表中项目的索引,list,indexing,sml,List,Indexing,Sml,我是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 Lis

我是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);
val L=[1,2,3,4,5];
val m=长度L-1;

fun Index(item,m,L)=如果m要详细说明我之前的评论,我建议对一个更适合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
个别改变包括:

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

还请注意,最常见的是,函数和变量名以小写字母开头(索引而非索引),而大写字母用于构造函数常量(某些)等。

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

fun index (x, []) = raise Subscript
  | index (x, y::ys) =
    if x = y then 0 else 1 + index (x, ys)

你的问题到底是什么?我相信没有一个标准函数可以明确地做到这一点,至少在列表结构中没有。至于清理代码,我建议1)使用选项或异常而不是返回
~1
,2)通过将函数包装到外部函数中来隐藏参数
m
,3)使用
m
上的模式匹配来消除一个条件(
如果m<0…
),谢谢提示。问题是,“做这件事最好的方法是什么?”。最好不要将m传递到函数中,因为它取决于L的长度,但正如我所说的,我对SML是新手,不知道如何将两者结合起来。制定该准则的原因是:;我有两个相关的不同类型的列表。更新列表1中的项目需要更新列表2中相同位置的项目。我相信列表结构可能会提供类似这样的带有“zip”的内容,但这目前正在发挥作用。感谢您的详细解释。我在这里已经多次看到这个习语了,我不明白用同一个名字来命名内部函数和外部函数的目的。我试着用谷歌搜索它,但很难找到你不知道它叫什么的东西。再次感谢!:)在这个网站上,只有代码的答案通常是不受欢迎的。请编辑您的答案,包括一些注释或对代码的解释,好吗?解释应该回答这样的问题:它做什么?它是如何做到的?它去哪里了?它如何解决OP的问题?请参阅:。谢谢
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