gpt4 book ai didi

f# - 这种类型注释是如何工作的,为什么另一个不能?

转载 作者:行者123 更新时间:2023-12-04 10:24:30 25 4
gpt4 key购买 nike

请解释背后的魔力drawShape功能。 1) 为什么它有效——我的意思是它如何调用 Draw成员,2) 为什么它需要是 inline ?

type Triangle() =
member x.Draw() = printfn "Drawing triangle"

type Rectangle() =
member x.Draw() = printfn "Drawing rectangle"

let inline drawShape (shape : ^a) =
(^a : (member Draw : unit->unit) shape)

let triangle = Triangle()
let rect = Rectangle()

drawShape triangle
drawShape rect

下一个问题是——是否可以写 drawShape使用参数类型注释的函数,如下所示?我发现它的签名与第一个完全相同,但我无法完成正文。
let inline drawShape2 (shape : ^a when ^a : (member Draw : unit->unit)) =
...

提前致谢。

最佳答案

这种看起来像巫毒教的语法被称为“statically resolved type parameter”。这个想法是要求编译器检查作为泛型参数传递的类型是否包含某些成员(在您的示例中 - Draw)。

由于 CLR 不支持此类检查,因此它们必须在编译时完成,F# 编译器很乐意为您执行此操作,但它也有代价:因为没有 CLR 支持,因此无法编译此类检查函数到 IL,这意味着每次与新的通用参数一起使用时都必须“复制”它(此技术有时也称为“monomorphisation”),这就是 inline关键字是为。

至于调用语法:出于某种原因,仅声明对参数本身的约束并不能削减它。每次实际引用成员时都需要声明它:

// Error: "x" is unknown
let inline f (a: ^a when ^a: (member x: unit -> string)) = a.x()

// Compiles fine
let inline f a = (^a: (member x: unit -> string)( a ))

// Have to jump through the same hoop for every call
let inline f (a: ^a) (b: ^a) =
let x = (^a: (member x: unit -> string)( a ))
let y = (^a: (member x: unit -> string)( b ))
x+y

// But can wrap it up if it becomes too messy
let inline f (a: ^a) (b: ^a) =
let callX t = (^a: (member x: unit -> string) t)
(callX a) + (callX b)

// This constraint also implicitly carries over to anybody calling your function:
> let inline g x y = (f x y) + (f y x)
val inline g : x: ^a -> y: ^a -> string when ^a : (member x : ^a -> string)

// But only if those functions are also inline:
> let g x y = (f x y) + (f y x)
Script.fsx(49,14): error FS0332: Could not resolve the ambiguity inherent in the use of the operator 'x' at or near this program point. Consider using type annotations to resolve the ambiguity.

关于f# - 这种类型注释是如何工作的,为什么另一个不能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30304080/

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