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

问题描述 投票:0回答:2

我对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 *)
functional-programming ocaml
2个回答
4
投票

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


1
投票

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

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

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

功能列表的一个例子是

[(fun () -> print_string "a"); (fun () -> print_string "b"); (fun () -> ())]
© www.soinside.com 2019 - 2024. All rights reserved.