在OCaml中从值列表中取值

时间:2014-02-12 23:35:16

标签: if-statement recursion ocaml

我正在OCaml中创建一个列表列表,但我无法理解如何实现目标。

我的目标是预先形成以下内容:

给定V =(0 1 1 -1)作为列表:

预先形成这个等式:

(2*V1 - 1)*(2*V2-1) = ?
(2*V1 - 1)*(2*V3-1) = ?
(2*V1 - 1)*(2*V4-1) = ?
(2*V2 - 1)*(2*V3-1) = ?
(2*V1 - 1)*(2*V4-1) = ?
(2*V3 - 1)*(2*V4-1) = ?

然后将其转换为列表,例如

0  V12 V13 V14
V21 0  V23 V24
V31 V32 0  V34
V41 V42 V43 0

矩阵是自身的反映。

我将使用2个功能来完成此任务。

第一个给出一个状态的输出,另一个给出整个矩阵。

以下是我到目前为止所做的事情:

singleState state =
if state = 0.0 then 0.0
else
    ((2*state) -. 1);;

matrixState V =
if V = [] then []
else
    singleState(hd(V)) * singleState(next item after head) + matrixState(tl(V));;

正如你所看到的,我无法弄清楚如何在V的头部之后取出物品。例如V2。

对我有什么建议吗?

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

let singleState state = 
    if state = 0.0 then 0.0
    else
        ((2.0 *. state) -. 1.0);;


let rec matrixState V = 
    match V with
    | [] -> []
    | hd :: [] -> V
    | hd :: (nx :: _ as tl) ->
        singleState hd *. singleState nx :: matrixState tl;;

1 个答案:

答案 0 :(得分:2)

你最好的选择是学习模式匹配方面的思考。而不是使用=来测试V是否为空,您可以编写更类似的内容:

let rec matrixState v =
    match v with
    | [] -> []
    | hd :: [] -> (* Not sure what you want here *)
    | hd :: (nx :: _ as tl) ->
        singleState hd *. singleState nx :: matrixState tl

首先,请记住,这只是一个函数的草图,它可以执行您希望matrixState函数执行的操作。我不确定在你的问题的最终答案中它会有多大用处。

这个函数的作用是将v(列表)与一系列模式相匹配,并根据哪种模式匹配给出不同的答案。

第一个模式([])匹配一个空列表。与在代码中一样,结果是一个空列表。

第二个模式(hd :: [])匹配一个只包含一个元素的列表。我不确定你想为这个案子做什么,所以我没有写代码。

第三种模式(hd :: (nx :: _ as tl))匹配具有两个或更多元素的列表。它将名称hd提供给第一个元素,将名称nx提供给第二个元素。此外,它将名称tl赋予列表的尾部(除第一个元素之外的所有内容)。在这里您可以看到OCaml模式的强大功能。

<强>更新

(注意:您应该使用SO页面来询问一个具有特定技术答案的问题。您不应该使用同一页面来提出一系列问题。这会使人们以后更难找到如果您有新问题,请在新页面上开始。)

在OCaml中,对于构造函数使用以大写字母开头的名称,对于普通变量使用以小写字母开头的名称。您在此处提供的代码将无法编译,因为您使用大写V作为变量。请注意我在上面的代码中使用了小写v。

如果我将大写字母V改为小写字母,那么您的代码编译就可以了。我没有任何错误。

(同样,我建议你做一些关于OCaml的基本阅读。这不是为了避免帮助你,而是我认为它可以帮助你更多,更快。)