gpt4 book ai didi

f# - 非惯用的全局运算符重载如何工作?

转载 作者:行者123 更新时间:2023-12-01 10:34:46 25 4
gpt4 key购买 nike

我想了解 this 中的代码回答

type Mult = Mult with
static member inline ($) (Mult, v1: 'a list) = fun (v2: 'b list) ->
v1 |> List.collect (fun x -> v2 |> List.map (fun y -> (x, y))) : list<'a * 'b>
static member inline ($) (Mult, v1:'a ) = fun (v2:'a) -> v1 * v2 :'a

let inline (*) v1 v2 = (Mult $ v1) v2

F# 可以解析重载的成员。 (因为它不支持柯里化(Currying)成员)。所以,我想,它也应该适用于方法

但事实并非如此:

type Mult = Mult with
static member inline Do (Mult, v1: 'a list) = fun (v2: 'b list) ->
v1 |> List.collect (fun x -> v2 |> List.map (fun y -> (x, y))) : list<'a * 'b>
static member inline Do (Mult, v1:'a ) = fun (v2:'a) -> v1 * v2 :'a
let inline (<.>) v1 v2 = (Mult.Do (Mult,v1)) v2

A unique overload for method 'Do' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: static member Mult.Do : Mult:Mult * v1: ^a -> ( ^a -> ^a) when ^a : (static member ( * ) : ^a * ^a -> ^a), static member Mult.Do : Mult:Mult * v1:'a list -> ('b list -> ('a * 'b) list)

运算符 $ 定义的语法令人困惑。它接受大写标识符作为运算符的第一个参数,并且 Visual Studio 不会提示它

Mult 被推断为 mult 类型,但令人惊讶的是这不起作用:

type Mult = Mult with
static member inline (!!) (mlt:Mult, v1: 'a list) = fun (v2: 'b list) ->
v1 |> List.collect (fun x -> v2 |> List.map (fun y -> (x, y))) : list<'a * 'b>
static member inline (!!) (mlt:Mult, v1:'a ) = fun (v2:'a) -> v1 * v2 :'a

let inline (<!>) v1 v2 = (Mult !! v1) v2

error FS0003: This value is not a function and cannot be applied

最佳答案

您的第二个示例不起作用,因为 F# 不会像使用运算符那样使用方法自动推断静态成员约束。

所以是的,这是可能的,但你必须手写约束,编译器不会为你推断它们:

type Mult = Mult with
static member inline Do (Mult, v1: 'a list) = fun (v2: 'b list) ->
v1 |> List.collect (fun x -> v2 |> List.map (fun y -> (x, y))) : list<'a * 'b>
static member inline Do (Mult, v1:'a ) = fun (v2:'a) -> v1 * v2 :'a

let inline impl m v1 v2 = ((^T or ^a) : (static member Do:^T* ^a->(^b-> ^c)) (m,v1)) v2
let inline (<.>) a b = impl Mult a b

你提到的大写标识符匹配一个只有一个案例的区分联合,所以它总是会成功,案例的名称与类型的名称相同。所有这些都是为了缩短代码量,因为 DU 是一个虚拟类型。如果它令人困惑,这里有一个普通类的例子:

type Mult() = class end with
static member inline ($) (_:Mult, v1: 'a list) = fun (v2: 'b list) ->
v1 |> List.collect (fun x -> v2 |> List.map (fun y -> (x, y))) : list<'a * 'b>
static member inline ($) (_:Mult, v1:'a ) = fun (v2:'a) -> v1 * v2 :'a

let inline (*) v1 v2 = (Mult() $ v1) v2

您的第三个示例不起作用,因为 (!!) 是一元运算符,而不是像 ($) 这样的二元运算符>

有关此旧技术的更多信息,请参阅 this old blog .

关于f# - 非惯用的全局运算符重载如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37607979/

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