在ocaml列表中创建一个元素指向一个新值

时间:2014-02-05 20:55:21

标签: algorithm ocaml ml

O'Caml的新手,我正在玩列表,我的目标是添加元素,并使现有的列表元素指向其新值,即如果我有[4; 6; 7]那么相同的清单应该成为[4; 10; 17]

这是我到目前为止所做的:

let rec summation l curr  =
match l with [] -> l
| (x::xs) -> curr = x + curr
            x = curr;(*make the element in the list point to curr*)
summation xs curr ;;

我希望像summation [5; 4; 2] 0一样调用这个函数,我觉得它应该可以工作。

2 个答案:

答案 0 :(得分:0)

OCaml列表是不可变的。你无法改变它们。有一些方法可以在OCaml中使用可变数据 - 列表不可变的,但如果你坚持可以使用可变值列表。但是,研究OCaml的原因之一是学习使用不可变数据。这就是我最初的建议。

使用不可变数据时,不是更改数据,而是返回所需数据的新版本。如果您的数据变化不止一点,您可能希望使用树而不是列表。

<强>更新

假设我想计算一个包含输入列表值的平方的列表。一种方法是这样的:

let rec squarelist l =
    match l with
    | [] -> []
    | h :: t -> (h * h) :: squarelist t

本质上,这个函数构造一个新的列表(使用::运算符)和我想要的内容。通常,您可以使用递归来处理列表的尾部。

你的案子有点难,因为你需要携带累积金额。所以你可能需要一个带有额外参数的辅助函数。

答案 1 :(得分:0)

除了Jeffrey的回答,这里是您案例的正确代码

let summation l =
  let rec sum (acc,s) = function
    | [] -> List.rev acc
    | hd::tl -> let new_sum = hd+s in sum (new_sum::acc, new_sum) tl
  in 
  sum ([],0) l

请注意,一旦掌握了递归和函数方法,就应该经常考虑尾递归,特别是你不介意一些性能降级。


重新评论:

如有必要,

in始终遵循let。通常,我们有let A in B,这意味着在某些东西中定义A。

让我的代码,简而言之就意味着let sum (acc,s)... in sum ([],0) l。我定义了一个可以在in之后的部分中使用的函数。

functionmatch的快捷方式。如果没有function,我会写:

let rec sum (acc,s) l = 
    match l with
    | [] -> List.rev acc
    | hd::tl -> let new_sum = hd+s in sum (new_sum::acc, new_sum) tl

我建议你阅读https://realworldocaml.org/,这是迄今为止最好的关于ocaml的最新书,非常好而且全面。它是免费的,您也可以从亚马逊购买。

首先进入OCaml的工作非常困难。特别是,您需要了解functional way是什么,与imperative way(如Java)相比