Агенты стиля Clojure в F # - PullRequest
4 голосов
/ 28 января 2011

Я пытаюсь закодировать некоторые агенты стиля Clojure в F #, используя MailboxProcessors. Вот что у меня есть:

namespace GameEngine

type Agent<'T>(inital:'T) = 
    let mutable state:'T = inital

    let queue = new MailboxProcessor<'T -> 'T>( fun inbox ->
            let rec loop count = 
                async {
                    let! msg = inbox.Receive()
                    state <- msg(state)
                    return! loop(count + 1)
                }
            loop 0)

    do
        queue.Start()

    member self.Send(action:'T -> 'T) =
        queue.Post(action)
    member self.Deref() =
        state

Итак, основная идея заключается в том, что у нас есть изменяемое состояние, которое можно обновить, вызвав .Send (). У меня вопрос, будут ли мои сообщения когда-либо не в порядке? Если сообщение A отправляется до B, будет ли вышеуказанная асинхронная функция всегда обрабатывать A до B?

Похоже, что такой класс должен быть уже в F #? Я изобретаю колесо?

Ответы [ 2 ]

2 голосов
/ 28 января 2011

Если сообщение A отправляется до B, будет ли вышеуказанная асинхронная функция всегда обрабатывать A до B?

Да.(Вы можете увидеть код для почтового ящика

http://fsharppowerpack.codeplex.com/SourceControl/changeset/view/54799#970072

, перейти к компилятору \ 2.0 \ Nov2010 \ src \ fsharp \ FSharp.Core \ control.fs и в конечном итоге увидеть, например,

   member x.Post(msg) =
       lock syncRoot (fun () ->
           arrivals.Enqueue(msg);
           ...

, который показывает, что это просто очередь под замком.)

Похоже, такой класс должен быть уже в F #?Я изобретаю колесо?

Ну, мне не сразу понятно, чем это отличается от простого обновления изменяемой глобальной переменной волей-неволей (по модулю атомарности одновременных обновлений; вы сказали «до» в вопросе, поэтому янеясно, если этот аспект имеет значение для вас).В каком контексте это нужно?

1 голос
/ 28 января 2011

Нет встроенной реализации агента в стиле Clojure.

В какой-то момент я также разработал быструю и грязную реализацию F #, похожую на вашу, но не удосужился рассмотреть все связанные с этим вопросы правильности;в частности, не правда ли, что 'T может иметь тип значения (struct) больше 64 бит (или 32 бит в зависимости от обстоятельств), что может вызвать разрыв (я предполагаюУ Clojure, как у Java, здесь нет причин для беспокойства).Возможно, потребуется ограничение общего типа F # ('T when 'T : not struct)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...