如何将函数映射到列表中的特定元素?

3
例如,如果您有一个函数(fun x -> x+1),并且您想将其映射到[1; 2; 3]。但是,您只想在x=1时进行映射,以便输出为[2; 2; 3]。您该怎么做?
使用OCaml,我尝试了:
let rec foo (input : int list) : int list =
match input with
    | [] -> []
    | hd::tl -> List.map (fun x -> if x=1 then (x+1)) input;;

我曾尝试使用“when”语句,但没有成功。

2个回答

9
这里缺少一个else分支。
你已经接近成功了。你只需要编写完整的if/else语句: if x=1 then (x+1) else x 在上述表达式的任何分支中,OCaml都需要有返回值。
明确一下,在这里使用when保护是无关紧要的,因为它用于条件模式匹配。由于在这种情况下模式匹配是多余的,你的函数可以大大简化:
let foo input =
    List.map (fun x -> if x=1 then x+1 else x) input

我感觉我尝试过了,但是没有成功——但是现在它成功了。Rockstar,你太棒了。感谢你关于“when”的提示。 - Adrienne

2
您实际上可以使用when语句,尽管我更喜欢@pad的解决方案。
let foo (input : int list) : int list = 
  let rec aux acc input = 
   match input with
      [] -> List.rev acc
    | x :: xs when x = 1 -> aux ((x + 1) :: acc) xs
    | x :: xs -> aux (x :: acc) xs
  in
  aux [] input

1
这个是尾递归的;-) - Fabrice Le Fessant
是的,它是尾递归的,但我更喜欢使用List.map的解决方案 :-) - Çağdaş Bozman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接