gpt4 book ai didi

f# - 在 F# 中如何实现 abs、sign 等

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

我找到:

abs -10
abs -10L

两者都有效。所以我想知道 F# 是如何实现这一点的,并在源代码中进行了搜索:
    type AbsDynamicImplTable<'T>() = 
let AbsDynamic x = AbsDynamicImplTable<_>.Result x

[<CompiledName("Abs")>]
let inline abs (x: ^T) : ^T =
AbsDynamic x
when ^T : ^T = absImpl x

我对这些感到困惑。

据我所知,在 abs 这样的函数中,我们必须将输入与0进行比较,不同的类型有不同的0。

谢谢。

最佳答案

为了给 ChaosPandion 发布的代码添加一些解释,F# 函数的问题,如 abs是他们可以使用任何数字类型。仅使用 F#/.NET 泛型无法表达这一点 - 唯一受支持的约束是类型参数实现某个接口(interface)或具有构造函数,但对数字类型没有约束。

因此,F# 还支持静态约束(类型参数是 ^a 而不是通常的 'a )并且这些是在编译时使用内联处理的(这也解释了为什么函数必须是 inline )。您可以使用 LanguagePrimitives 中的内置函数编写您自己的带有静态约束的函数。其中包含许多需要一些约束的有用功能:

> let inline half (num: ^a) : ^a =
LanguagePrimitives.DivideByInt< (^a) > num 2
;;
val inline half : ^a -> ^a
when ^a : (static member DivideByInt : ^a * int -> ^a)

> half 42.0;;
val it : float = 21.0

> half 42.0f;;
val it : float32 = 21.0f

请注意,推断出约束 - DivideByInt要求类型具有 DivideByInt成员,所以我们的函数需要同样的东西(如果它也有这个成员,它将适用于您自己的类型,这非常有用!)。

除此之外, abs 的实现使用仅在 F# 库中允许的两个附加技巧 - 它为不同类型(使用 when ^a:int = .... )指定不同的代码(内联时使用)和使用 Abs 的后备案例成员,因此它将适用于任何显式列出的类型或具有 Abs 的类型成员。另一个技巧是 retype函数,它“更改类型”,但不包含任何代码 - 唯一目的是对代码进行类型检查,但这可能非常不安全 - 所以这仅在 F# 库中使用。

关于f# - 在 F# 中如何实现 abs、sign 等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2192852/

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