The following code fails in ‘Evaluate’ with:
“This expression was expected to have type Complex but here has type double list”
Am I breaking some rule on operator over-loading on ‘(+)’?
Things are OK if I change ‘(+)’ to ‘Add’.
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
The problem with your code is that your definition of
+actually hides all previous definitions of the operator, so the F# compiler thinks that+can be used only for addition ofPowersvalues. This is because function values (declared usinglet) including F# operators do not support overloading.However, you can overload F# operators if you add them as a
static memberof some type. This doesn’t work for abberviations, so you’ll need to change the type declaration to a record or discriminated union first (I choose the second option). Then you can implement overloaded operator like this:Note that the operator is now declared as part of the
Powerstype. Since the type is a discriminated union, I needed to add unwrapping of parameters (P ls, P rs) and then again wrap the result. YourEvaluatefunction will look like this:It again needs to unwrap the value (
P ks), but the rest of the code is unchanged.