2016-11-29 9 views
4

Я пишу крошечную матричную библиотеку (в основном методы-обертку) в F # и имею проблему перегрузки статических операторских методов, при этом F # выбирает перегрузку, на которую я ее не намеревался.Как использовать перегруженные статические операторы

У меня есть модуль, где я определил правое умножение матрицы с вектором:

[<AutoOpen>] 
module MatrixOps = 

let (*) (matrix : IMatrix) (vector : IVector) = 
    (...) 

Это позволяет мне писать такие вещи, как, например, A * v, где A - IMatrix, а v - IVector. Тем не менее, я теперь добавить следующую строку ниже пусть связывания выше:

let z = 1.0 * 2.0 

и затем F # компилятор идентифицирует это как ошибку. Наведите курсор на «1.0», я получаю: «Тип« float »несовместим с типом« IMatrix », и аналогичным образом, паря над« 2.0 », я получаю:« Тип «float» несовместим с типом ' IVector». Что здесь происходит, похоже, что компилятор F # не применяет оператор умножения для float и вместо этого применяет оператор для IMatrix и IVector. Если я вместо этого напишу

let z = (1.0 : float) * (2.0 : float) 

проблема сохраняется, поэтому добавление явно выраженных аннотаций не помогает. Как я могу гарантировать, что F # выбирает оператор плавающего умножения вместо оператора IMatrix/IVector, который я определил выше?

+2

Вы хотите сделать перегруз статическим членом типа одного из объектов, тогда он работает так, как вы хотите –

+0

Хорошо. Но есть ли другой путь? Если метод умножения находится на интерфейсе IMatrix или IVector, тогда я буду вводить нежелательную зависимость. –

+1

Это не зависимость. Вам все равно нужны типы –

ответ

8

F # не позволяет определить перегрузки, просто добавив связанные функции.

F # Поддержка стандартных .NET экземпляр или статический член перегрузок, так что в этом случае вам нужно добавить статический член:

type Matrix = 
    static member (*) (matrix : Matrix) (vector : IVector) = .. 

Примечания: Советуем против такой конструкции с перегрузками между матрицами и векторами. Если вы продолжаете определять перегрузки таким образом, я имею в виду между смешанными типами, разрешение перегрузки может стать неоднозначным.

Лучше определить перегрузку только между матрицами, а затем другим набором между векторами. Затем вы можете определить такую ​​функцию, как asMatrix, которая позволяет обернуть вектор в матрицу и затем умножить матрицы.

+0

Я думаю, что это опечатка: «Лучше определить перегрузку между матрицами и векторами». –

+0

@FyodorSoikin вроде, теперь, когда вы упоминаете, я замечаю, что это непонятно. Я буду перефразировать его. Благодаря ! – Gustavo

+0

Спасибо. Я думаю, что ваш комментарий о asMatrix звучит. У меня есть некоторые последующие вопросы. Если я (буквально) сделаю это, матрица будет зависеть от IVector. Я бы предпочел не связывать эти два. Потенциальным способом избежать связи было бы определение «статического метода расширения на интерфейсе IMatrix», но интерфейсы не могут иметь статические методы. Возможно, единственный способ сделать эту работу - ввести зависимость? –