gpt4 book ai didi

f# - 如何在 F# 中定义执行顺序?

转载 作者:行者123 更新时间:2023-12-01 06:09:26 25 4
gpt4 key购买 nike

在纯函数式编程中,执行顺序无关紧要,因此是不确定的(即取决于编译器)。如果您有副作用,则执行顺序确实很重要。那么在F#中怎么定义呢?

我有一个函数可以递归地删除给定路径的所有空子文件夹。此外,如果它们的名称在给定列表中,它会删除其中包含的一些文件。

算法很简单:

  1. 删除列表中的所有文件。
  2. 对子文件夹进行递归调用。
  3. 如果文件夹为空,请删除该文件夹。这必须是最后一步。

此外,该函数以元组的形式返回已删除元素的数量(已删除文件夹的数量,已删除文件的数量)。

这是我的代码:

let rec DeleteEmptyFolders path filenames =
// Deletes a file or folder using the given function.
// Returns 1 if the file could be deleted, otherwise 0.
let Delete delete name =
try
delete name;
1
with
| _ -> 0

// The function result (number of deleted folders and files).
let deletedFolders (a, _) = a
let deletedFiles (_, a) = a

let accumulator a b =
( deletedFolders a + deletedFolders b,
deletedFiles a + deletedFiles b )

// Deletes the given files and returns the number of deleted elements.
let DeleteFiles folder names =
names
|> Seq.map (fun n -> Path.Combine (folder, n))
|> Seq.map (fun n -> Delete File.Delete n)
|> Seq.reduce (+)

// Deletes the folder if it is empty
// (Directory.Delete will fail if it is not empty).
let DeleteFolder folder = Delete Directory.Delete folder

// The recursive call
let DeleteEmptySubFolders folder files =
Directory.EnumerateDirectories folder
|> Seq.map (fun p -> DeleteEmptyFolders p files)
|> Seq.reduce (accumulator)

// Three functions are executed: DeleteEmptySubFolders, DeleteFolder and DeleteFiles
// But it has to be done in the correct order: DeleteFolder must be executed last.
accumulator (DeleteEmptySubFolders path filenames) (DeleteFolder path, DeleteFiles path filenames)

我可以弄清楚 DeleteEmptySubFolders 是先执行的,然后是 DeleteFolder 和 DeleteFiles。这是函数在代码中出现的顺序。但我不认为这是 F# 的规则,它只是编译器决定的。可以是任何其他顺序。

当然,我可以交换代码最后一行中的元素。编译器会相应地更改执行顺序。但既然这不是语言的规则,那就只能靠运气了。

another question关于这个主题,我读过值(即不带参数的函数)按照声明它们的顺序进行初始化。

let firstCall  = DeleteFiles path filenames
let secondCall = DeleteEmptySubFolders path filenames
let thirdCall = DeleteFolder path

accumulator (secondCall) (thirdCall, firstCall)

现在调用的顺序是正确的。但同样:这是 F# 的规则还是编译器的工作原理? (如果不使用函数,编译器可能决定根本不初始化这些值)

如果我想告诉 F# 执行顺序很重要以及每次调用应该在何时完成,我应该如何写最后一行?是否有关键字或特殊语法将函数标记为无副作用?

最佳答案

F# 不是纯函数式编程语言:函数和值将按从上到下、从左到右的顺序计算。

关于f# - 如何在 F# 中定义执行顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11812979/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com