Проблема с вашим кодом в том, что ваше определение +
фактически скрывает все предыдущие определения оператора, поэтому компилятор F # считает, что +
можно использовать только для добавления значений Powers
. Это связано с тем, что значения функций (объявленные с использованием let
), включая операторы F #, не поддерживают перегрузку.
Однако вы можете перегрузить операторы F #, если добавите их как static member
некоторого типа. Это не работает для аббревиатур, поэтому вам нужно сначала изменить объявление типа на запись или дискриминированное объединение (я выбираю второй вариант). Тогда вы можете реализовать перегруженный оператор так:
/// 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)
Обратите внимание, что оператор теперь объявлен как часть типа Powers
. Так как тип является распознаваемым объединением, мне нужно было добавить распаковку параметров (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
Снова необходимо развернуть значение (P ks
), но остальная часть кода остается неизменной.