【发布时间】:2018-09-07 10:04:33
【问题描述】:
我正在为图像处理任务做一些事情(在这里并没有太大的相关性),我偶然发现了 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]
我将在其中传递四字节选项的数组(如果您想知道为什么这看起来很奇怪并且超级无功能,现在我正在故意尝试重新实现一个非功能语言的实现教科书中的算法)。我期望这会导致编译器错误,它会抱怨无法直接比较选项。令我惊讶的是,这编译得很好。很感兴趣,我在 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# comparison optional