gpt4 book ai didi

f# - 可以为区分联合类型设置默认值吗?

转载 作者:行者123 更新时间:2023-12-01 08:47:00 26 4
gpt4 key购买 nike

我实现了一个可区分联合类型,用于选择一个函数:

type BooleanCombinator =
| All
| Some
| None
| AtLeast of int
| MoreThan of int
| NotMoreThan of int
| LessThan of int
| ExactlyOne
| ExactlyTwo
| AllButOne
| AllButTwo

let boolToInt (b: bool) : int = if b then 1 else 0

let combineBooleans (combinator : BooleanCombinator)
(bools : bool list)
: bool =

let n = List.sumBy boolToInt bools

match combinator with
| BooleanCombinator.All -> List.forall id bools
| BooleanCombinator.Some -> bools |> List.exists id
| BooleanCombinator.None -> bools |> List.exists id |> not
| BooleanCombinator.AtLeast i -> n >= i
| BooleanCombinator.MoreThan i -> n > i
| BooleanCombinator.NotMoreThan i -> n <= i
| BooleanCombinator.LessThan i -> n < i
| BooleanCombinator.ExactlyOne -> n = 1
| BooleanCombinator.ExactlyTwo -> n = 2
| BooleanCombinator.AllButOne -> n = bools.Length - 1
| BooleanCombinator.AllButTwo -> n = bools.Length - 2

这对我来说看起来不错,但编译器开始将 SomeNone 的所有实例视为属于此 DU,而不是 Option杜。

我不想浏览所有代码,将 Some 替换为 Option.Some 并将 None 替换为 Option.None .

有没有办法告诉编译器不合格的 SomeNone 实际上是 Option.SomeOption.None

或者我应该为这些 DU 案例提供不同的名称,例如 AtLeastOneExactlyZero

最佳答案

在 F# 中解决名称冲突的一般规则是“最后声明获胜”。因为你的自定义 DU 是在 Option 之后声明的,所以它的构造函数 SomeNone 胜过 Option 的构造函数。

但这条规则提供了一种解决问题的方法:您只需要在自定义 DU 之后“重新声明”声明:

type Bogus = Some of int | None

let g = function Some _ -> 42 | None -> 5
let x = Some 42

let inline Some a = Option.Some a
let inline None<'a> = Option.None : 'a option
let (|Some|None|) = function | Option.Some a -> Some a | Option.None -> None

let f = function Some _ -> 42 | None -> 5
let y = Some 42

如果检查上述代码中的gxfy的类型:

> g
g : Bogus -> int

> f
f : 'a option -> int

> x
Bogus

> y
int option

函数 g 和值 x 被推断为分别具有 Bogus -> intBogus 类型,因为 SomeNone 在它们的正文中指的是 Bogus.SomeBogus.None

函数 f 和值 y 被推断为具有与 Option 相关的类型,因为 SomeNone 在它们的主体中指的是我在上面定义的 Some 函数和 (|Some|None|) 事件模式。

当然,这是一种相当老套的恢复现状的方法。这将使编译器信服,但人类仍然很难阅读您的代码。我建议你改为重命名你的 DU 的案例。

关于f# - 可以为区分联合类型设置默认值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51334151/

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