Ограничение использования оператора одним классом - PullRequest
0 голосов
/ 20 марта 2019

В: В F # Обязательно ли объявлять операторы для типов в самом объявлении типа?

Чтобы обеспечить некоторую дополнительную безопасность в отношении определенных типов, я хотел определить тип, но разрешать операции над этим типом только из определенного класса. У меня есть следующий код:

/// Tracks identity of an Event
type EventID = EventID of int

let defaultEventID = EventID 0

/// Singleton to generate IDs for Events
type EventIDManager private () =    
    let mutable currentID = defaultEventID
    static let instance = EventIDManager()
    static member Instance = instance

    /// Operator definition in question
    static member inline private (+.) (EventID(a), EventID(b)) = EventID(a + b)

    /// Simply increments IDs for now
    member private __.advanceID () =
        currentID <- currentID +. (EventID 1) /// Compiler warning here

    member this.generateID () =
        let cur = currentID
        this.advanceID ()
        ///return ID
        cur

    member __.getCurrentID () = currentID

Вместо того, чтобы определять оператор +. в самом типе EventID, я переместил его на EventIDManager. Но в методе advanceID() компилятор выдает следующее предупреждение:

The type 'EventID' does not support the operator '+.'

Даже если я добавлю это следующим образом, я получу то же предупреждение:

static member inline private (+.) (e1:EventID) (e2:EventID) =
    match e1, e2 with EventID a, EventID b -> EventID(a + b)

Если объявление оператора перемещено в определение типа, проблема исчезает , но мне было любопытно посмотреть, смогу ли я сохранить определение оператора в классе EventIDManager. Это возможно?

1 Ответ

1 голос
/ 21 марта 2019

Статические члены в F # обычно должны иметь имя класса, чтобы увидеть его.Что бы я сделал (особенно если вам нужен только частный оператор), напишите это как привязку let.Поэтому, прежде всего, у ваших участников просто есть

let (+.) (EventID a) (EventID b) = EventID(a + b)

, и вы сможете использовать его из класса EventIDManager и нигде больше.

...