Wie funktioniert das Überladen nicht idiomatischer globaler Operatoren?
Ich möchte den Code von @ verstehDie Antworte
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 # kann überladene Mitglieder auflösen. (Weil es das Curry von Mitgliedern nicht unterstützt). Also, ich nahm an, es sollte auch für Methoden funktionieren
Aber das tut es nicht:
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
Eine eindeutige Überladung für die Methode 'Do' konnte anhand der Typinformationen vor diesem Programmpunkt nicht ermittelt werden. Möglicherweise ist eine Typanmerkung erforderlich. Kandidaten: statisches Mitglied Mult.Do: Mult: Mult * v1: ^ a -> (^ a -> ^ a) wenn ^ a: (statisches Mitglied (*): ^ a * ^ a -> ^ a), statisches Mitglied Mult.Do: Mult: Mult * v1: 'eine Liste -> (' b Liste -> ('a *' b) Liste)
Die Syntax, in der der Operator$
ist definiert ist verwirrend. Es akzeptiert einen Bezeichner in Großbuchstaben als erstes Argument des Operators und Visual Studio beschwert sich nicht darüber
s wird angenommen, dass @Mult vom Typ mult ist, aber überraschenderweise funktioniert dies nicht:
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
Fehler FS0003: Dieser Wert ist keine Funktion und kann nicht angewendet werden