将操作员使用限制为一个类

时间:2019-03-20 17:53:33

标签: types f# operators

问:在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 个答案:

答案 0 :(得分:1)

F#中的静态成员通常需要将类名放在前面才能看到它。我要做的(特别是因为您只想要一个私有运算符)是将其写为let绑定。因此,最重要的是

import random

def run():
    lst=[]
    for i in range(0,20):
        ran = random.randint(1,10)
        lst.append(ran)
    return lst

lst = run()
print(lst) 
#[5, 10, 5, 1, 8, 10, 10, 6, 4, 9, 3, 9, 6, 9, 2, 9, 9, 1, 7, 8]
result = sorted(lst, key = lambda x: lst.index(x))
print(result)
#[5, 5, 10, 10, 10, 1, 1, 8, 8, 6, 6, 4, 9, 9, 9, 9, 9, 3, 2, 7]

,您应该可以在EventIDManager类中使用它,而在其他任何地方都不能使用它。