OCaml和OCaml评估模型中的功能应用列表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OCaml和OCaml评估模型中的功能应用列表相关的知识,希望对你有一定的参考价值。

我对OCaml的评估模型不太熟悉。如果有人能解释为什么这两行代码会产生不同的结果,我将不胜感激:

List.iter (fun s -> Printf.printf "%s" s) ["a"; "b"; "c"];; (* prints abc *)

List.iter (fun f -> f) [Printf.printf "a"; Printf.printf "b"; Printf.printf "c"];; (* prints cba *)
答案

OCaml是一种严格的函数式编程语言:函数的参数在传递给函数之前被评估为值(并且表达式中的副作用发生)(并且函数内部的任何副作用都可能发生)。

为了理解你的第二个例子,最好去点一点: List.cons (Printf.printf "a") (List.cons (Printf.printf "b") (List.cons (Printf.printf "c") []))

当一个函数同时传递几个参数时 - 就像这里所有List.cons函数的情况一样 - 参数的评估顺序是未指定的。例如,字节码和本机编译器之间的顺序可能不同。在这里,你使用的编译器决定首先评估第一个List.cons的第二个参数。在这样做,它遇到了一个应用程序(第二个List.cons

在评估最后一个List.cons的论点时,它打印了c。结果是(),它允许它建立值[()]。这个论点准备就绪,它现在评估了第二个List.cons的另一个论点。这使它打印b。最后,由于第一个[();()]的论证List.cons准备就绪,它评估了另一个论点。这使它打印a

另一答案

正如Pascal Cuoq已经回答了你的问题,让我澄清一下我从问题标题中可能产生的误解:你的代码中没有任何函数列表。

在第一行有一个字符串列表,["a";"b";"c"]

在第二行中,您有一个列表,其中包含Printf.printf "a"等元素,它们是函数应用程序。它们的结果类型是unit,也不是函数类型。 (实际上这个名单只是[();();()]。)

功能列表的一个例子是

[(fun () -> print_string "a"); (fun () -> print_string "b"); (fun () -> ())]

以上是关于OCaml和OCaml评估模型中的功能应用列表的主要内容,如果未能解决你的问题,请参考以下文章

访问 ocaml 中的全局参考列表 [关闭]

OCaml中的主要功能

OCaml - 在实现我的 rev 功能时需要一些帮助

ocaml的教学语言,从静态切换到动态作用域

在 OCaml 中访问 (int * float) 列表中的浮点数

截断OCaml中的列表