F# - Как расширить тип с get Zero, чтобы я мог использовать существующий тип в общем виде?
Я пытаюсь сделать следующее:
let c x = System.Numerics.Complex(x, 0.0)
let sum = [c 1.0; c 2.0] |> List.sum
Но я получаю эту ошибку:
The type 'System.Numerics.Complex' does not support the operator 'get_Zero'
Я читал правила о расширении типов, начиная с https://msdn.microsoft.com/en-us/library/dd233211.aspx , и попробуйте сделать следующее:
module ComplexExtension =
let c x = System.Numerics.Complex(x, 0.0)
type System.Numerics.Complex with
// I also tried a bunch of other ways of writing these
// as static or instance members, but nothing worked
static member Zero = c 0.0
static member One = c 1.0
open ComplexExtension
let sum = [c 1.0; c 2.0] |> List.sum
Я все еще получаю эту ошибку.
Можно ли расширить тип с помощью оператора get_Zero? Или мне нужно создать свой собственный тип оболочки вокруг System.Numerics.Complex и переопределить все операторы, если я хочу, чтобы он делал другие вещи, которые сложные числа делать?
2 ответа:
List.sumиспользует статические ограничения членов. Статические ограничения членов не рассматривают методы расширений, так что это не вариант.Обертывание всего сложного типа-это вариант, но это перебор, если это просто конкретный вызов, у вас есть много способов вычислить сумму с помощью еще нескольких нажатий клавиш, вы можете использовать
fold, как показано на другом ответе. В качестве альтернативы можно использоватьList.reduce (+), Если вы уверены, что в списке всегда будет хотя бы один элемент.Это может быть возможно получить исправлено в будущей версии F#, но проблема в том, что статические ограничения членов не работают с полями, если у них нет геттера. Однако в F# lib они могут "эмулировать" эти члены для существующих типов, они делают это обычно с примитивными типами иначе это не будет работать с
Я не уверен, был ли тот факт, чтоint,float, поскольку у них тоже нет этого члена.Complexопределен вSystem.Numerics, причиной, чтобы не реализовать его таким образом, или, возможно, они просто забыли об этом. В в любом случае вы можете открыть проблему или отправить запрос на ее устранение. Наконец, еще один вариант, если вы все еще хотите использовать его в общем виде, - это переопределить функциюsum. Например, функцияsum(вот источник ) из последней версии F#+ будет работать нормально (у нее была та же проблема, но ее было очень легко исправить, на самом деле это была ошибка) практически со всеми числовыми типами, включаяComplexи большинство сторонних числовых типов, потому что у нее есть запасной вариант механизм, который полагается в некоторых преобразованиях, когда тип не имеет членаget_Zero.