Дизъюнктное объединение и позволило привязке?

Используйте этого декоратора @RateLimited (ratepersec) перед Вашей функцией, которая ставит в очередь.

В основном, это проверяет, передали ли 1/уровень secs с прошлого раза, когда и в противном случае ожидает остаток времени, иначе он не ожидает. Это эффективно ограничивает Вас уровнем/секунда. Декоратор может быть применен к любой функции, которую Вы хотите ограниченный уровнем.

В Вашем случае, если Вы хотите максимум 5 сообщений в 8 секунд, @RateLimited использования (0.625) перед Вашей функцией sendToQueue.

import time

def RateLimited(maxPerSecond):
    minInterval = 1.0 / float(maxPerSecond)
    def decorate(func):
        lastTimeCalled = [0.0]
        def rateLimitedFunction(*args,**kargs):
            elapsed = time.clock() - lastTimeCalled[0]
            leftToWait = minInterval - elapsed
            if leftToWait>0:
                time.sleep(leftToWait)
            ret = func(*args,**kargs)
            lastTimeCalled[0] = time.clock()
            return ret
        return rateLimitedFunction
    return decorate

@RateLimited(2)  # 2 per second at most
def PrintNumber(num):
    print num

if __name__ == "__main__":
    print "This should print 1,2,3... at about 2 per second."
    for i in range(1,100):
        PrintNumber(i)
6
задан Edward Brey 23 February 2012 в 20:31
поделиться

3 ответа

имеет смысл разрешить связывание let внутри размеченных объединений. Я думаю, что причина, по которой это невозможно, заключается в том, что размеченные союзы все еще основаны на дизайне OCaml, а объекты - из мира .NET. F # пытается максимально интегрировать эти два аспекта, но он, вероятно, может пойти дальше.

В любом случае, мне кажется, что вы используете дискриминационное объединение только для реализации некоторого внутреннего поведения AI_Choose ] тип. В этом случае вы можете объявить размеченное объединение отдельно и использовать его для реализации типа объекта.

Думаю, вы могли бы написать что-то вроде этого:

type AiChooseOptions =
    | AI_Priority of list<AI> * Condition
    | AI_Weighted_Priority of list<AI * float> * Condition

type AiChoose(aiOptions) = 
    let mutable chosen = Option<AI>.None
    member this.Choose() =
        match aiOptions with
        | AI_Priority(aiList, condition) -> (...)
        | AI_Weighted_Priority(aiList, condition) -> (...)
    member this.Chosen (...)
    interface AI with (...)

Ключевое различие между иерархией классов и размеченными союзами заключается в расширяемости.

2
ответ дан 16 December 2019 в 21:44
поделиться

Для всех, кого это интересует, я в итоге получил AI_Priority и AI_Weighted_Priority из абстрактного базового класса.

[<AbstractClass>]
type AI_Choose() =
    let mutable chosen = Option<AI>.None

    abstract member Choose : unit -> AI

    member this.Chosen
        with get() = 
            if Option.isNone chosen then
                chosen <- Some(this.Choose())
            chosen.Value
        and set(x) =
            if Option.isSome chosen then
                chosen.Value.Stop()
            chosen <- Some(x)
            x.Start()

    interface AI with
        member this.Start() =
            this.Chosen.Start()
        member this.Stop() =
            this.Chosen.Stop()
        member this.Reset() =
            this.Chosen <- this.Choose()
        member this.Priority() =
            this.Chosen.Priority()
        member this.Update(gameTime) =
            this.Chosen.Update(gameTime)

type AI_Priority(aiList : list<AI>, condition : Condition) =
    inherit AI_Choose()
    override this.Choose() =
        aiList 
        |> List.map (fun ai -> ai, ai.Priority())
        |> condition.Select
        |> fst

type AI_Weighted_Priority(aiList : list<AI * float>, condition : Condition) =
    inherit AI_Choose()
    override this.Choose() =
        aiList 
        |> List.map (fun (ai, weight) -> ai, weight * ai.Priority())
        |> condition.Select
        |> fst
3
ответ дан 16 December 2019 в 21:44
поделиться

Вернувшись к этому коду, я в итоге принял предложение Томаса, которое оказалось намного чище.

type AiChooseOptions =
    | Priority of List<AI * Priority>
    | WeightedPriority of List<AI * Priority * float>
    member this.Choose(condition : Condition) =
        match this with
        | Priority(list) ->
            list 
            |> List.map (fun (ai, priority) -> ai, priority.Priority())
            |> condition.Select
        | WeightedPriority(list) ->
            list 
            |> List.map (fun (ai, p, weight) -> ai, p.Priority() * weight)
            |> condition.Select

type AiChoose(condition, list : AiChooseOptions ) =
    let mutable chosen = Unchecked.defaultof<AI>, 0.0

    interface AI with
        member this.Update(gameTime) =
            (fst chosen).Update(gameTime)

    interface Priority with
        member this.Priority() =
            chosen <- list.Choose(condition)
            (snd chosen)
3
ответ дан 16 December 2019 в 21:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: