List SML-获取列表的索引

List SML-获取列表的索引,list,sml,List,Sml,我正在开发一个程序,它将“+”或“-”附加到列表的一个元素上,这取决于该元素的索引是奇数还是偶数(即交替和列表) 但是,我很难确定每个元素的索引是什么。我有一些代码,我认为应该使用if语句和mod fun alternating([]) = 0 | alternating(l) = if List.nth(l,hd(l)) mod 2 == 0 then '+'@hd(l)@alternating(tl(l)) else '-'@hd(l)@alternat

我正在开发一个程序,它将“+”或“-”附加到列表的一个元素上,这取决于该元素的索引是奇数还是偶数(即交替和列表)

但是,我很难确定每个元素的索引是什么。我有一些代码,我认为应该使用
if语句和
mod

fun alternating([]) = 0
  | alternating(l) = 
        if List.nth(l,hd(l)) mod 2 == 0 then '+'@hd(l)@alternating(tl(l))
        else '-'@hd(l)@alternating(tl(l))

但是,
List.nth(l,hd(l))
总是返回第二个索引处的元素,而不是第一个索引处的元素

如果你想用索引来装饰你的列表,你可以试试下面的方法

fun add_index l =
  let 
    fun add_index_helper (nil,  _) = nil
      | add_index_helper (h::tl,i) = (h,i) :: add_index_helper (tl,1+i)
  in
     add_index_helper (l,0)
  end

val x = add_index [0,1,4,9,16,25]
但是你也可以用同样的方法直接计算奇偶校验

fun add_sign l =
  let 
    fun add_sign_helper (nil,  _) = nil
      | add_sign_helper (h::tl,i) = (h,i) :: add_sign_helper (tl,1-i)
  in
     add_sign_helper (l,0)
  end

val y = add_sign [0,1,4,9,16,25]
然后可以将奇偶校验映射到字符串

fun sign_to_char (x,0) = (x,"+")
  | sign_to_char (x,_) = (x,"-")

val z = List.map sign_to_char y
或者你可以直接加上这个标志

fun add_char l =
  let 
    fun add_char_helper (nil,  _) = nil
      | add_char_helper (h::tl,0) = (h,"+") :: add_char_helper (tl,1)
      | add_char_helper (h::tl,_) = (h,"-") :: add_char_helper (tl,0)
  in
     add_char_helper (l,0)
  end

val zz = add_char [0,1,4,9,16,25]
或者,如果您有一个字符串列表,并且您想添加字符,那么您可以尝试以下方法

fun signs L =
  let
    datatype parity = even | odd
    fun signs_helper ( nil ,_) = nil
      | signs_helper (x::xs,even) = ("+" ^ x) :: signs_helper(xs,odd)
      | signs_helper (x::xs,odd)  = ("-" ^ x) :: signs_helper(xs,even)
  in
    signs_helper (L,even)
  end

val z = signs ["x","2y","3z","4"]
(* this gives you val z = ["+x","-2y","+3z","-4"] : string list *)

如果你真的只想对整数求反,这样你就可以把它们传递到某种求和中,如果它是奇数,我会对它求反。使用相互递归,无需任何明确的索引簿记:

fun alternate l =
   let
       fun alternate1 []      = []
         | alternate1 (x::xs) = (~x) :: alternate2 xs
       and alternate2 []      = []
         | alternate2 (x::xs) =   x  :: alternate1 xs
   in
       alternate1 l
   end
它是这样工作的:

- alternate [1,2,3,4];
val it = [~1,2,~3,4] : int list
我强烈建议您使用模式匹配而不是
hd

编辑讨论
hd

根据经验,如果您需要
hd
,您可能也需要
tl
hd
是一个局部函数——如果列表为空,它将抛出
Empty
。如果模式匹配,就可以方便地获得列表开头和结尾的变量,并得到一个视觉提示,提示您需要处理空列表。在我看来,这在美学上更令人愉悦:

fun foo []      = ...
  | foo (x::xs) = ...
比同等的

fun foo l = 
  if null l 
    then ... 
    else (hd l) ... (tl l)

换言之,您可以获得更短、更清晰的代码,并自动提醒以使其正确。赢/赢。据我所知,换一种方式做没有什么明显的好处。当然,您可能会发现自己处于这样一种情况:您知道列表将至少包含一个元素,而不需要执行任何其他操作。你仍然需要考虑你所给出的情况,但这是一个很好的经验法则。< / P>输入和预期输出的例子会很有帮助。输入是字符串列表吗?@Delfini我在回答中对此进行了扩展。我同意
x::xs
更易于查看:)我尝试了上面的代码,收到了一条错误消息<代码>运算符不是函数:运算符:^Z表达式中的列表:让本地变量=在val=val=在alternate l end alternate中结束我想您有一个复制/粘贴错误。我只是把答案贴在另一台机器上,效果很好。