Como funciona a sobrecarga de operador global não idiomática?
Eu quero entender o código deesta responda
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
O F # pode resolver membros sobrecarregados. (Porque não suporta currying de membros). Então, eu suponho que deveria funcionar para métodos também
Mas isso não acontece:
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
Uma sobrecarga exclusiva para o método 'Do' não pôde ser determinada com base nas informações de tipo anteriores a este ponto do programa. Uma anotação de tipo pode ser necessária. Candidatos: membro estático Mult.Do: Mult: Mult * v1: ^ a -> (^ a -> ^ a) quando ^ a: (membro estático (*): ^ a * ^ a -> ^ a), membro estático Mult.Do: Mult: Mult * v1: 'uma lista -> (' lista b -> ('a *' b) lista)
A sintaxe na qual o operador$
está definido é confuso. Ele aceita identificador em maiúsculas como primeiro argumento do operador e o Visual Studio não reclama.
Mult é inferido como sendo do tipo mult, mas surpreendentemente isso não funciona:
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
erro FS0003: Este valor não é uma função e não pode ser aplicado