Как работает неидиоматическая глобальная перегрузка операторов?

Я хочу понять код изэтот ответ

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 # может разрешать перегруженные элементы. (Потому что он не поддерживает каррирование членов). Итак, я полагаю, это должно работать и для методов

Но это не так:

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

Уникальная перегрузка для метода «Do» не может быть определена на основе информации о типе до этой программной точки. Тип аннотации могут быть необходимы. Кандидаты: статический член Mult.Do: Mult: Mult * v1: ^ a -> (^ a -> ^ a) когда ^ a: (статический член (*): ^ a * ^ a -> ^ a), статический член 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

ошибка FS0003: это значение не является функцией и не может быть применено

Ответы на вопрос(1)

Ваш ответ на вопрос