gpt4 book ai didi

f# - 大于(和等效)选项的行为

转载 作者:行者123 更新时间:2023-12-01 09:44:36 24 4
gpt4 key购买 nike

我正在为图像处理任务做一些事情(在这里并没有太大的相关性),我偶然发现了 F# 的 Option 类型的行为,这让我感到惊讶,即执行大于 (>) 比较。在 Stack Overflow、F# 文档或更广泛的网络上,我找不到任何可以直接解释我应该期待的内容(更多内容见下文)的内容。

我正在查看的特定部分类似于:

let sort3Elems (arr: byte option []) = 
if arr.[0] > arr.[1] then swap &arr.[0] &arr.[1]
if arr.[1] > arr.[2] then swap &arr.[1] &arr.[2]
if arr.[0] > arr.[1] then swap &arr.[0] &arr.[2]

我将在其中传递四字节选项的数组(如果您想知道为什么这看起来很奇怪并且 super 无功能,现在我正在故意尝试重新实现一个非功能语言的实现教科书中的算法)。我期望这会导致编译器错误,它会提示无法直接比较选项。令我惊讶的是,这编译得很好。很感兴趣,我在 F# Interactive 中对其进行了测试,结果如下所示:

let arr: byte option [] = Array.zeroCreate 4;;
val arr : byte option [] = [|None; None; None; None|]

> arr.[0] <- Some(127uy);;
val it : unit = ()

> arr.[2] <- Some(55uy);;
val it : unit = ()

> arr.[0] > arr.[2];;
val it : bool = true

> arr.[0] < arr.[2];;
val it : bool = false

> arr.[0] < arr.[1];;
val it : bool = false

> arr.[0] > arr.[1];;
val it : bool = true

> arr.[2] > arr.[1];;
val it : bool = true

> arr.[3] > arr.[1];;
val it : bool = false

> arr.[3] < arr.[1];;
val it : bool = false

> arr.[3] > arr.[1];;
val it : bool = false

在我看来,本质上,比较运算符在询问 Some 是否大于(小于)None 时必须始终返回 true(false),两个 None 始终返回 false,并且两个相同包含类型的 Somes 比较包含值(假设它们可以进行比较,我想)。这是有道理的,虽然我很惊讶。

为了确认这一点,我试图找到一些可以解释我应该期待的行为的东西,但我找不到任何可以解决这一点的东西。 Option page in the MS F# Guide docs没有提及它,我在 F# 之类的地方找不到任何有趣和利润的东西。我什至无法在 MS API 文档中的任何地方找到关于 Option 的页面...查看 the source for Option in the F# GitHub repo什么也没告诉我。我能找到的最好的是a blog post by Don Syme从几年前开始,实际上并没有回答我的问题。有一些 Stack Overflow 问题讨论了与比较运算符或选项类型有关的主题,但我没有找到任何涉及两者组合的问题。

所以,我的问题是,对 Option 类型执行大于/小于比较是否会返回我在上面推测的结果?我猜这在 F# 程序员中是相当普遍的知识,但这对我来说是新闻。作为一个子/相关问题,有人知道我可以/应该在哪里寻找更多信息吗?谢谢。

最佳答案

F# 编译器自动生成可区分联合和记录类型的比较。由于 option 只是一个有区别的联合,这也意味着您可以获得联合的自动比较。我不确定是否有一个很好的网页来记录这一点,但你可以在 section 8.15.4 in the F# specification 中找到描述。 :

8.15.4 Behavior of the Generated CompareTo Implementations

For a type T, the behavior of the generated System.IComparable.CompareTo implementation is as follows:

  • Convert the y argument to type T . If the conversion fails, raise the InvalidCastException.
  • If T is a reference type and y is null, return 1.
  • If T is a struct or record type, invoke FSharp.Core.Operators.compare on each corresponding pair of fields of x and y in declaration order, and return the first non-zero result.
  • If T is a union type, invoke FSharp.Core.Operators.compare first on the index of the union cases for the two values, and then on each corresponding field pair of x and y for the data carried by the union case. Return the first non-zero result.

如最后一个案例中所述,选项的案例首先比较案例。 None具有小于 Some 的索引所以一个None值将始终小于任何 Some值(value)。如果案例匹配,则 None = NoneSome nSome m根据 n 进行比较和 m .

关于f# - 大于(和等效)选项的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52220189/

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