Skip to content

Instantly share code, notes, and snippets.

@denmerc
Created October 11, 2016 18:35
Show Gist options
  • Select an option

  • Save denmerc/d2510ea5b370a45392c60d774d26a917 to your computer and use it in GitHub Desktop.

Select an option

Save denmerc/d2510ea5b370a45392c60d774d26a917 to your computer and use it in GitHub Desktop.
A simple generic Command/Query Agent in F# using MailboxProcessor
type Message<'S> =
| Query of ('S -> unit)
| Command of ('S -> 'S)
| Kill
type CQAgent<'S>(state: 'S) =
let innerModel =
MailboxProcessor<Message<'S>>.Start(fun inbox ->
let rec messageLoop (state: 'S) =
async {
let! msg = inbox.Receive()
match msg with
| Query q ->
q state
return! messageLoop state
| Command c ->
let newState = c state
return! messageLoop(newState)
| Kill -> ()
}
messageLoop state)
member this.Query<'T> (q: 'S -> 'T) =
innerModel.PostAndReply(fun chan -> Query(fun state ->
let res = q state
chan.Reply(res)))
member this.Command<'T> (c: 'S -> 'T * 'S) =
innerModel.PostAndReply(fun chan -> Command(fun state ->
let res, newState = c state
chan.Reply(res)
newState))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment