F#运算符过载:(+)表示用户defind类型

jyo*_*ung 3 f# operator-overloading

以下代码在"Evaluate"中失败:
"此表达式应该具有类型Complex,但这里有类型双列表"
我是否打破了运算符过载的一些规则'(+)'?
如果我将'(+)'更改为'添加',情况就可以了.

open Microsoft.FSharp.Math

/// real power series [kn; ...; k0] => kn*S^n + ... + k0*S^0
type Powers = double List

let (+) (ls:Powers) (rs:Powers) =
    let rec AddReversed (ls:Powers) (rs:Powers) =
        match ( ls, rs ) with
        | ( l::ltail, r::rtail ) -> ( l + r ) :: AddReversed ltail rtail
        | ([], _) -> rs
        | (_, []) -> ls
    ( AddReversed ( ls |> List.rev ) ( rs |> List.rev) ) |> List.rev

let Evaluate (ks:Powers) ( value:Complex ) =
    ks |> List.fold (fun (acc:Complex) (k:double)-> acc * value +  Complex.Create(k, 0.0)  ) Complex.Zero 
Run Code Online (Sandbox Code Playgroud)

Tom*_*cek 9

您的代码的问题在于您的定义+实际上隐藏了运算符的所有先前定义,因此F#编译器认为+只能用于添加Powers值.这是因为let包含F#运算符的函数值(使用声明)不支持重载.

但是,如果将F#运算符添加为static member某种类型,则可以重载它们.这不适用于abberviations,因此您需要首先将类型声明更改为记录或区分联合(我选择第二个选项).然后你可以像这样实现重载运算符:

/// real power series [kn; ...; k0] => kn*S^n + ... + k0*S^0 
type Powers = 
  | P of double list 
  static member (+) (P ls, P rs) = 
    let rec AddReversed ls rs = 
        match ( ls, rs ) with 
        | ( l::ltail, r::rtail ) -> ( l + r ) :: AddReversed ltail rtail 
        | ([], _) -> rs 
        | (_, []) -> ls 
    P (( AddReversed ( ls |> List.rev ) ( rs |> List.rev) ) |> List.rev)
Run Code Online (Sandbox Code Playgroud)

请注意,现在将运算符声明为该Powers类型的一部分.由于类型是一个有区别的联合,我需要添加unwrapping参数(P ls, P rs)然后再包装结果.你的Evaluate功能将如下所示:

let Evaluate (P ks) ( value:Complex ) = 
  ks |> List.fold (fun (acc:Complex) (k:double)-> 
    acc * value +  Complex.Create(k, 0.0)  ) Complex.Zero
Run Code Online (Sandbox Code Playgroud)

它还需要解包value(P ks),但其余代码不变.